Так виходить, що оскільки AnyObject є духовним спадкоємцем id, ви можете викликати будь-яке повідомлення, яке ви хочете, на AnyObject. Це еквівалент відправки повідомлення на id. Гаразд, досить справедливо. Але тепер ми додаємо в концепцію, що всі методи необов’язкові в AnyObject , і ми маємо з чим працювати.
З огляду на вищесказане, я сподівався, що я можу просто передати UIApplication.sharedApplication () на AnyObject, потім створити змінну, рівну підпису методу, встановити цю змінну на необов'язковий метод, а потім перевірити змінну. Це, здається, не спрацювало. Я гадаю, що коли компілюється проти iOS 8.0 SDK, компілятор знає, де вважає цей метод повинен бути бути, тому він оптимізує це все до пошуку пам'яті. Все працює добре, поки я не спробую перевірити змінну, і тоді я отримаю EXC_BAD_ACCESS.
Однак у тій же розмові WWDC, де я знайшов дорогоцінне каміння про те, що всі методи є необов'язковими, вони використовують Optional Chaining для виклику необов'язкового методу - і це, здається, працює. Кульгава частина полягає в тому, що вам потрібно насправді намагатися викликати метод, щоб знати, чи він існує, що у випадку реєстрації для сповіщень є проблемою, оскільки ви намагаєтесь з’ясувати, чи існує цей метод, перш ніж ви створюєте Об'єкт UIUserNotificationSettings. Схоже, викликати цей метод за допомогою нуля, хоча це нормально, тому рішення, яке, здається, працює для мене:
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)
}
Після багато пошуків, пов’язаних із цим, ключова інформація надійшла з цього розмови WWDC https://developer.apple.com/videos/wwdc/2014/#407 прямо в середині в розділі "Необов’язкові методи в протоколах"
У Xcode 6.1 beta наведений вище код не працює, код нижче працює:
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)
}