Quindi risulta che, poiché AnyObject è il successore spirituale di id, puoi chiamare qualsiasi messaggio tu voglia su AnyObject. È l'equivalente di inviare un messaggio a id. Ok, abbastanza giusto. Ma ora aggiungiamo il concetto che tutti i metodi sono opzionali su AnyObject e abbiamo qualcosa con cui possiamo lavorare.
Dato quanto sopra, speravo di poter semplicemente eseguire il cast di UIApplication.sharedApplication () su AnyObject, quindi creare una variabile uguale alla firma del metodo, impostare quella variabile sul metodo opzionale, quindi testare la variabile. Questo non sembra funzionare. La mia ipotesi è che quando viene compilato con l'SDK di iOS 8.0, il compilatore sa dove pensa che il metodo dovrebbe essere, quindi ottimizza tutto fino a una ricerca di memoria. Tutto funziona bene finché non provo a testare la variabile, a quel punto ottengo un EXC_BAD_ACCESS.
Tuttavia, nello stesso discorso del WWDC in cui ho trovato il gioiello su tutti i metodi opzionali, usano il concatenamento opzionale per chiamare un metodo opzionale - e questo sembra funzionare. La parte debole è che devi effettivamente tentare di chiamare il metodo per sapere se esiste, il che nel caso della registrazione per le notifiche è un problema perché stai cercando di capire se questo metodo esiste prima di creare un Oggetto UIUserNotificationSettings. Sembra che chiamare quel metodo con zero sia ok, quindi la soluzione che sembra funzionare per me è:
var ao: AnyObject = UIApplication.sharedApplication()
if let x:Void = ao.registerUserNotificationSettings?(nil) {
var types = UIUserNotificationType.Badge | UIUserNotificationType.Sound | UIUserNotificationType.Alert
var settings = UIUserNotificationSettings(forTypes: types, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
} else {
var types = UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound | UIRemoteNotificationType.Alert
UIApplication.sharedApplication().registerForRemoteNotificationTypes(types)
}
Dopo molte ricerche relative a questo, le informazioni chiave provenivano da questo discorso WWDC https://developer.apple.com/videos/wwdc/2014/#407 proprio nel mezzo nella sezione sui "Metodi opzionali nei protocolli"
In Xcode 6.1 beta il codice sopra non funziona più, il codice seguente funziona:
if UIApplication.sharedApplication().respondsToSelector("registerUserNotificationSettings:") {
var types = UIUserNotificationType.Badge | UIUserNotificationType.Sound | UIUserNotificationType.Alert
var settings = UIUserNotificationSettings(forTypes: types, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
} else {
var types = UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound | UIRemoteNotificationType.Alert
UIApplication.sharedApplication().registerForRemoteNotificationTypes(types)
}