Swift 2 Tillgänglighetskontroll

I denna korta handledning vill jag fokusera på Swifts helt nya syntax för tillgänglighetskontroll. Om du har gjort någon mängd iOS- eller OS X-utveckling, är jag säker på att du vet hur tråkigt det kan vara att kontrollera om ett visst API är tillgängligt på den enhet som din applikation körs på. I Swift 2 har detta blivit mycket mindre av smärta för utvecklare.

Problemet

Bild följande scenario. Du utvecklar en iOS-applikation som riktar sig mot iOS 7 och uppåt. Under förra årets WWDC introducerade Apple ett nytt API för anmälningsregistrering.

registerUserNotificationSettings (_ :) 

Betyder det att du behöver höja din applikations implementeringsmål från iOS 7 till iOS 8? Du kan göra det, men det skulle lämna en betydande del av din applikations användarbas i kölden, bara för att följa Apples nya policy för lokala och fjärranslutna meddelanden. Dina användare kommer inte att tacka för det.

Alternativet är att bara använda det nya API-en på enheter som kör iOS 8 och uppåt. Det är mer meningsfullt. Höger? Genomförandet skulle se ut så här.

func application (application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool om UIApplication.instancesRespondToSelector ("registerUserNotificationSettings:") let types = UIUserNotificationType.Alert | UIUserNotificationType.Sound | UIUserNotificationType.Badge låt settings = UIUserNotificationSettings (forTypes: types, categories: nil) application.registerUserNotificationSettings (inställningar) returnera true 

Detta är ett lönsamt alternativ, men det är inte uteslutet risk. I denna handledning kommer jag inte att gå in i detaljerna om vad dessa risker innebär, men jag vill betona att de flesta utvecklare tycker att det är bra att använda ovanstående tillvägagångssätt. Följande exempel visar en variation av detta tillvägagångssätt, den här gången med Objective-C.

om ([UIUserNotificationSettings class]) [ansökningsregisterUserNotificationSettings: [UIUserNotificationSettings settingsForTypes: (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge) kategorier: noll]];  

Medan båda metoderna kommer att fungera i de flesta situationer, finns det situationer där du kommer att stöta på problem. Vissa API: er, till exempel, startar sina liv som privata API och publiceras senare. I det här fallet kan du sluta slå privata API på enheter som kör ett operativsystem där de här API: erna inte är offentliga ännu. Och jag är säker på att du vet vad det betyder.

Lösningen

Tack vare Swift-teamets arbete är lösningen på vårt problem enkelt och enkelt i Swift 2. Ta en titt på följande exempel. Observera att implementeringsmålet för projektet är inställt på iOS 7, med hjälp av Swift 2 och Xcode 7.

I exemplet använder vi API som introducerades i IOS 8. Eftersom kompilatören vet att installationsmålet för projektet är inställt på iOS 7, kastar det ett fel och berättar att API: erna vi vill använda endast är tillgängliga i iOS 8 och uppåt. Den vet detta genom att inspektera SDK för tillgänglighetsinformation. Om du trycker på Kommando och klicka på registerUserNotificationSettings (_ :) metod, du borde se något så här.

@ tillgänglig (iOS 8.0, *) func registerUserNotificationSettings (notificationSettings: UIUserNotificationSettings) 

Lyckligtvis ger Xcode oss en lösning för att lösa problemet. Det föreslår att du använder en versionskontroll för att undvika att API: erna exklusiva till iOS 8 och upp heter om våra användare kör programmet på en äldre version av IOS.

Observera att den här funktionen introducerades i Swift 2. Kompilatorn kommer inte att kasta ett fel om du använder Swift 1.2. Tillsatsen av versionskontrollen gör det också lättare att förstå exemplet. Ta en titt på det uppdaterade exemplet nedan, där vi följer de råd som Xcode har givit oss.

func application (application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool if # available (iOS 8.0, *) let types = UIUserNotificationType ([UIUserNotificationType.Alert, UIUserNotificationType.Sound, UIUserNotificationType.Badge]) låt inställningar = UIUserNotificationSettings (forTypes: types, categories: nil) application.registerUserNotificationSettings (inställningar) returnera true 

Syntaxen är tydlig och förståelig. Med hjälp av syntaxen för tillgänglighet kontrollerar vi om programmet körs på en enhet med iOS 8 och uppåt. Om det inte är det om klausulen hoppas över, annars kallar programmet det nya API för anmälningsregistrering.

Syntax

Syntaxen är enkel. Vi startar tillgängligheten med #tillgängliga och lindra tillståndet inom parentes. Vi kan lägga till så många plattformar som nödvändigt, separera listan över plattformar med kommatecken.

om # tillgänglig (iOS 8.0, OSX 10.10, watchOS 2, *) ... 

Observera att vi slutar listan över plattformar med en asterisk. Denna stjärna är obligatorisk och indikerar att om klausulen exekveras på det minsta implementeringsmålet för någon plattform som inte ingår i listan över plattformar.

Som vi såg tidigare kan vi använda @tillgängliga Attribut för att lägga till tillgänglighetsinformation till funktioner, metoder och klasser. I följande exempel berättar vi kompilatorn att useFancyNewAPI bör endast anropas enheter som kör iOS 9 och uppåt.

@ tillgänglig (iOS 9.0, *) func useFancyNewAPI () ... 

Slutsats

Tänk på att tillgänglighetssyntaxen inte är ett alternativ för de två exemplen jag visade dig i början av denna handledning. Dessa exempel är felaktiga och ska bara användas om du använder Objective-C eller en tidigare version av Swift.

Synligheten för tillgänglighet är ytterligare en anledning till att migrera dina Swift-projekt till Swift 2. Det blir av med felaktiga lösningar för att kontrollera API-tillgängligheten. Världen ser lite snällare ut med Swift 2. Gör det inte?