Swift 2 Verifica disponibilità

In questo breve tutorial, vorrei concentrarmi sulla nuovissima sintassi di Swift per il controllo della disponibilità. Se hai fatto qualsiasi sviluppo iOS o OS X, sono sicuro che sai quanto può essere noioso controllare se una particolare API è disponibile sul dispositivo su cui è in esecuzione la tua applicazione. In Swift 2, questo è diventato molto meno un problema per gli sviluppatori.

Il problema

Immagina il seguente scenario. Stai sviluppando un'applicazione iOS destinata a iOS 7 e versioni successive. Durante il WWDC dello scorso anno, Apple ha introdotto una nuova API per la registrazione delle notifiche.

registerUserNotificationSettings (_ :) 

Ciò significa che è necessario aumentare il target di distribuzione dell'applicazione da iOS 7 a iOS 8? Potresti farlo, ma lasciare una parte significativa della base di utenti della tua applicazione al freddo, solo per rispettare la nuova politica di Apple per le notifiche locali e remote. I tuoi utenti non ti ringrazieranno per questo.

L'alternativa è utilizzare la nuova API solo su dispositivi che eseguono iOS 8 e versioni successive. Questo ha più senso. Destra? L'implementazione sarebbe simile a questa.

func application (application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool if UIApplication.instancesRespondToSelector ("registerUserNotificationSettings:") let types = UIUserNotificationType.Alert | UIUserNotificationType.Sound | UIUserNotificationType.Badge let settings = UIUserNotificationSettings (forTypes: types, categories: nil) application.registerUserNotificationSettings (impostazioni) return true 

Questa è un'opzione valida, ma non è rischiosa. In questo tutorial, non approfondirò i dettagli di ciò che questi rischi implicano, ma voglio sottolineare che molti sviluppatori pensano che sia corretto utilizzare l'approccio sopra descritto. L'esempio seguente mostra una variazione di questo approccio, questa volta utilizzando Objective-C.

if ([UIUserNotificationSettings class]) [application registerUserNotificationSettings: [UIUserNotificationSettings settingsForTypes: (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge) categories: nil]];  

Mentre entrambi gli approcci funzioneranno nella maggior parte delle situazioni, ci sono situazioni in cui ti imbatterai in problemi. Alcune API, ad esempio, iniziano la loro vita come API private e sono rese pubbliche in una fase successiva. In tale scenario, potresti finire per colpire API private su dispositivi che eseguono un sistema operativo in cui tali API non sono ancora pubbliche. E sono sicuro che tu sai cosa significa.

La soluzione

Grazie al lavoro del team Swift, la soluzione al nostro problema è semplice e diretta in Swift 2. Dai un'occhiata al seguente esempio. Si noti che l'obiettivo di distribuzione del progetto è impostato su iOS 7, utilizzando Swift 2 e Xcode 7.

Nell'esempio, utilizziamo le API introdotte in iOS 8. Poiché il compilatore sa che la destinazione di distribuzione del progetto è impostata su iOS 7, genera un errore, comunicandoci che le API che vogliamo utilizzare sono disponibili solo in iOS 8 e versioni successive. Lo sa ispezionando l'SDK per informazioni sulla disponibilità. Se si preme Comando e fare clic su registerUserNotificationSettings (_ :) metodo, dovresti vedere qualcosa di simile.

@available (iOS 8.0, *) func registerUserNotificationSettings (notificationSettings: UIUserNotificationSettings) 

Fortunatamente, Xcode ci fornisce una soluzione per risolvere il problema. Suggerisce di utilizzare un controllo di versione per evitare che le API in esclusiva per iOS 8 e versioni successive vengano chiamate se i nostri utenti eseguono l'applicazione su una versione precedente di iOS.

Si noti che questa funzione è stata introdotta in Swift 2. Il compilatore non genera un errore se si utilizza Swift 1.2. L'aggiunta del controllo della versione rende anche l'esempio più facile da capire. Dai un'occhiata all'esempio aggiornato di seguito in cui seguiamo il consiglio che Xcode ci ha fornito.

func application (applicazione: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool if #available (iOS 8.0, *) let types = UIUserNotificationType ([UIUserNotificationType.Alert, UIUserNotificationType.Sound, UIUserNotificationType.Badge]) let settings = UIUserNotificationSettings (forTypes: types, categories: nil) application.registerUserNotificationSettings (impostazioni) return true 

La sintassi è chiara e comprensibile. Utilizzando la sintassi della disponibilità, controlliamo se l'applicazione è in esecuzione su un dispositivo con iOS 8 e versioni successive. Se non lo è, il Se la clausola viene saltata, altrimenti l'applicazione chiama la nuova API per la registrazione delle notifiche.

Sintassi

La sintassi è semplice. Iniziamo la condizione di disponibilità con #a disposizione e avvolgere la condizione tra parentesi. Possiamo aggiungere tutte le piattaforme necessarie, separando l'elenco delle piattaforme con virgole.

se #available (iOS 8.0, OSX 10.10, watchOS 2, *) ... 

Si noti che finiamo la lista delle piattaforme con un asterisco. Questo asterisco è richiesto e indica che il Se la clausola viene eseguita sulla destinazione minima di implementazione per qualsiasi piattaforma che non è inclusa nell'elenco delle piattaforme.

Come abbiamo visto in precedenza, possiamo usare il @a disposizione attributo per aggiungere informazioni sulla disponibilità a funzioni, metodi e classi. Nell'esempio seguente, diciamo al compilatore che il file useFancyNewAPI dovrebbe essere chiamato solo su dispositivi con iOS 9 e versioni successive.

@available (iOS 9.0, *) func useFancyNewAPI () ... 

Conclusione

Tieni presente che la sintassi della disponibilità non è un'alternativa per i due esempi che ti ho mostrato all'inizio di questo tutorial. Questi esempi sono imperfetti e dovrebbero essere usati solo se stai usando Objective-C o una versione precedente di Swift.

La sintassi di disponibilità è un altro motivo per la migrazione dei tuoi progetti Swift a Swift 2. Elimina le soluzioni soggette a errori per verificare la disponibilità dell'API. Il mondo sembra un po 'più amichevole con Swift 2. Non è così?