Entonces resulta que debido a que AnyObject es el sucesor espiritual de la identificación, puede llamar a cualquier mensaje que desee en AnyObject. Eso es el equivalente a enviar un mensaje a id. OK bastante justo. Pero ahora agregamos el concepto de que todos los métodos son opcionales en AnyObject , y tenemos algo con lo que podemos trabajar.
Teniendo en cuenta lo anterior, tenía la esperanza de poder enviar UIApplication.sharedApplication () a AnyObject, luego crear una variable igual a la firma del método, establecer esa variable en el método opcional y luego probar la variable. Esto no pareció funcionar. Supongo que cuando se compila contra el SDK de iOS 8.0, el compilador sabe dónde cree que debería estar ese método , por lo que optimiza todo esto a una búsqueda de memoria. Todo funciona bien hasta que trato de probar la variable, en ese momento obtengo un EXC_BAD_ACCESS.
Sin embargo, en la misma charla de WWDC donde encontré la gema acerca de que todos los métodos son opcionales, usan el encadenamiento opcional para llamar a un método opcional, y esto parece funcionar. La parte lamentable es que debes intentar llamar al método para saber si existe, lo que en el caso de registrarte para recibir notificaciones es un problema porque estás tratando de descubrir si este método existe antes de crear un Objeto UIUserNotificationSettings. Parece que llamar a ese método con nil está bien, así que la solución que parece estar funcionando para mí es:
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)
}
Después de muchas búsquedas relacionadas con esto, la información clave vino de esta charla de WWDC https://developer.apple.com/videos/wwdc/2014/#407 justo en el medio en la sección sobre "Métodos opcionales en protocolos"
En Xcode 6.1 beta, el código anterior ya no funciona, el siguiente código funciona:
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)
}