Swift 2 verificarea disponibilității

În acest tutorial scurt, aș dori să mă concentrez asupra sintaxei noi de la Swift pentru verificarea disponibilității. Dacă ați realizat o anumită sumă de dezvoltare pentru iOS sau OS X, atunci sunt sigur că știți cât de plictisitor poate fi să verificați dacă un anumit API este disponibil pe dispozitivul pe care se execută aplicația. În Swift 2, acest lucru a devenit mult mai puțin o durere pentru dezvoltatori.

Problema

Imaginați următorul scenariu. Elaborați o aplicație iOS care vizează iOS 7 și în sus. În cursul anului WWDC de anul trecut, Apple a introdus un nou API pentru înregistrarea notificărilor.

registerUserNotificationSettings (_ :) 

Înseamnă că trebuie să ridicați destinația de implementare a aplicației dvs. de pe iOS 7 la iOS 8? Ai putea face asta, dar ar lăsa o parte semnificativă din baza de utilizatori a aplicației dvs. în frig, doar pentru a se conforma noii politici Apple pentru notificările locale și la distanță. Utilizatorii dvs. nu vă vor mulțumi pentru asta.

Alternativa este să utilizați noul API numai pe dispozitive care rulează iOS 8 și în sus. Asta are mai mult sens. Dreapta? Implementarea ar arăta așa.

func application (cerere: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool dacă UIApplication.instancesRespondToSelector ("registerUserNotificationSettings:") let types = UIUserNotificationType.Alert | UIUserNotificationType.Sound | UIUserNotificationType.Badge permite setările = UIUserNotificationSettings (pentru Tipuri: tipuri, categorii: zero) application.registerUserNotificationSettings (setări) return true 

Aceasta este o opțiune viabilă, dar nu este lipsită de risc. În acest tutorial, nu voi intra în detaliile a ceea ce implică aceste riscuri, dar vreau să subliniez că majoritatea dezvoltatorilor consideră că este bine să folosești abordarea de mai sus. Următorul exemplu arată o variație a acestei abordări, de această dată utilizând Obiectiv-C.

dacă ([clasa UIUserNotificationSettings]) [application registerUserNotificationSettings: [UIUserNotificationSettings settingsForTypes: (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge) categorii: nil]];  

În timp ce ambele abordări vor funcționa în cele mai multe situații, există situații în care veți avea probleme. Unele API-uri, de exemplu, își încep viața ca API private și sunt făcute publice într-o etapă ulterioară. În acest scenariu, este posibil să ajungeți la atingerea API-urilor private pe dispozitive care rulează un sistem de operare în care acele interfețe API nu sunt încă publice. Și sunt sigur că știi ce înseamnă asta.

Soluția

Datorită muncii echipei Swift, soluția la problema noastră este simplă și directă în Swift 2. Uitați-vă la următorul exemplu. Rețineți că obiectivul de implementare al proiectului este setat la iOS 7, utilizând Swift 2 și Xcode 7.

În exemplul respectiv, folosim API-uri introduse în iOS 8. Deoarece compilatorul știe că ținta de implementare a proiectului este setată la iOS 7, acesta aruncă o eroare, spunându-ne că API-urile pe care le dorim să le folosim sunt disponibile numai în iOS 8 și în sus. Știe acest lucru prin inspectarea SDK-ului pentru informații despre disponibilitate. Dacă apăsați Comanda și faceți clic pe registerUserNotificationSettings (_ :) metodă, ar trebui să vedeți ceva de genul acesta.

@ disponibil (iOS 8.0, *) func registerUserNotificationSettings (notificare: setările UIUserNotificationSettings) 

Din fericire, Xcode ne oferă o soluție pentru rezolvarea problemei. Acesta sugerează utilizarea unei verificări a versiunii pentru a evita ca API-urile exclusive pentru iOS 8 și mai sus să fie apelate dacă utilizatorii noștri rulează aplicația pe o versiune mai veche a iOS.

Rețineți că această caracteristică a fost introdusă în Swift 2. Compilatorul nu va arunca o eroare dacă utilizați Swift 1.2. Adăugarea verificării versiunii face de asemenea acest exemplu mai ușor de înțeles. Aruncati o privire la exemplul actualizat de mai jos, in care urmam sfatul pe care ni l-a oferit Xcode-ul.

func cerere (cerere: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool if #available (iOS 8.0, *) lăsați setările = UIUserNotificationSettings (pentru Tipuri: tipuri, categorii: zero) application.registerUserNotificationSettings (setări) return true 

Sintaxa este clară și ușor de înțeles. Utilizând sintaxa de disponibilitate, verificăm dacă aplicația rulează pe un dispozitiv cu iOS 8 și în sus. Dacă nu, atunci dacă clauza este omisă, în caz contrar, cererea solicită noul API pentru înregistrarea notificării.

Sintaxă

Sintaxa este simplă. Începem condiția de disponibilitate cu #disponibil și împachetați condiția în paranteze. Putem adăuga câte platforme este necesar, separând lista de platforme cu virgule.

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

Rețineți că terminăm lista de platforme cu un asterisc. Acest asterisc este necesar și indică faptul că dacă clauza este executată pe destinația minimă de implementare pentru orice platformă care nu este inclusă în lista de platforme.

După cum am văzut mai devreme, putem folosi @disponibil atribuiți pentru a adăuga informații despre disponibilitate la funcții, metode și clase. În următorul exemplu, îi spunem compilatorului că useFancyNewAPI ar trebui să fie solicitate numai pe dispozitive care rulează iOS 9 și în sus.

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

Concluzie

Rețineți că sintaxa de disponibilitate nu este o alternativă pentru cele două exemple pe care le-am arătat la începutul acestui tutorial. Aceste exemple sunt eronate și ar trebui să fie utilizate numai dacă utilizați obiectivul C sau o versiune anterioară a Swift.

Sintaxa availabilty este încă un motiv pentru migrarea proiectelor Swift la Swift 2. Se elimină soluțiile predispuse la erori pentru verificarea disponibilității API. Lumea pare puțin mai prietenă cu Swift 2. Nu o face?

Cod