Okazuje się więc, że ponieważ AnyObject jest duchowym następcą id, możesz wywołać dowolną wiadomość na AnyObject. Jest to odpowiednik wysłania wiadomości do id. Ok, w porządku. Ale teraz dodajemy koncepcję, że wszystkie metody są opcjonalne w AnyObject i mamy coś, z czym możemy pracować.
Biorąc pod uwagę powyższe, miałem nadzieję, że mogę po prostu przesłać UIApplication.sharedApplication () do AnyObject, a następnie utworzyć zmienną równą sygnaturze metody, ustawić tę zmienną na opcjonalną metodę, a następnie przetestować zmienną. To nie działało. Domyślam się, że po kompilacji z zestawem SDK systemu iOS 8.0 kompilator wie, gdzie według niego powinna być ta metoda , więc optymalizuje to wszystko do wyszukiwania pamięci. Wszystko działa dobrze, dopóki nie spróbuję przetestować zmiennej, w którym to momencie otrzymam EXC_BAD_ACCESS.
Jednak w tym samym przemówieniu WWDC, w którym znalazłem klejnot o tym, że wszystkie metody są opcjonalne, używają Łańcucha Opcjonalnego, aby wywołać metodę opcjonalną - i wydaje się, że to działa. Słaba część polega na tym, że musisz faktycznie wywołać metodę, aby dowiedzieć się, czy ona istnieje, co w przypadku rejestrowania powiadomień stanowi problem, ponieważ próbujesz dowiedzieć się, czy ta metoda istnieje przed utworzeniem metody Obiekt UIUserNotificationSettings. Wygląda na to, że wywołanie tej metody na zero jest w porządku, więc rozwiązaniem, które wydaje się dla mnie działać, jest:
var ao: AnyObject = UIApplication.sharedApplication()
if let x:Void = ao.registerUserNotificationSettings?(nil) {
// It's iOS 8
var types = UIUserNotificationType.Badge | UIUserNotificationType.Sound | UIUserNotificationType.Alert
var settings = UIUserNotificationSettings(forTypes: types, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
} else {
// It's older
var types = UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound | UIRemoteNotificationType.Alert
UIApplication.sharedApplication().registerForRemoteNotificationTypes(types)
}
Po wielu związanych z tym poszukiwaniach kluczowe informacje pochodzą z tego przemówienia WWDC https://developer.apple.com/videos/wwdc/2014/#407 w środkowej części w sekcji o „Opcjonalnych metodach w protokołach”
W Xcode 6.1 beta powyższy kod już nie działa, poniższy kod działa:
if UIApplication.sharedApplication().respondsToSelector("registerUserNotificationSettings:") {
// It's iOS 8
var types = UIUserNotificationType.Badge | UIUserNotificationType.Sound | UIUserNotificationType.Alert
var settings = UIUserNotificationSettings(forTypes: types, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
} else {
// It's older
var types = UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound | UIRemoteNotificationType.Alert
UIApplication.sharedApplication().registerForRemoteNotificationTypes(types)
}