Har du noen gang følt behov for å kunne raskt og enkelt bytte mellom konfigurasjoner uten å rote med kompilatorflagger eller manuelt endre variabler i prosjektet ditt? I dette raske tipset vil jeg gjerne vise deg en smart løsning på dette problemet ved å utnytte Xcode-ordninger og tilpassede prosjektkonfigurasjoner.
For noen iOS-prosjekter trenger du muligheten til å raskt bytte mellom ulike konfigurasjoner eller miljøer. Et vanlig scenario er når et iOS-program kommuniserer med en API eller en webtjeneste. Under utviklingen må du jobbe i et utviklings- eller scenemiljø. Før du slipper en oppdatering, vil du mest sannsynlig teste søknaden din i et oppstarts- eller produksjonsmiljø. Bytte mellom konfigurasjoner eller miljøer kan være tungvint, spesielt hvis du trenger å gjøre denne bryteren ofte.
Den enkleste tilnærmingen er å manuelt endre konfigurasjonen hver gang du bytter miljø. Dette betyr å modifisere et kompilatorflagg eller manuelt endre verdier i prosjektet ditt. Denne tilnærmingen er feilaktig, kjedelig og langt fra ideell. En bedre løsning er å skape en egendefinert konfigurasjon for hvert miljø. Dette innebærer å opprette en konfigurasjonsfil som sentraliserer miljøvariabler og tilpassede Xcode-ordninger. La meg vise deg hvordan dette fungerer ved å lage et prøveprosjekt.
Opprett et nytt prosjekt i Xcode ved å velge Tom søknad mal fra listen over maler (figur 1). Navn søknaden din konfigurerbar, skriv inn en bedriftsidentifikator, sett iPhone for enhetens familie, og sjekk Bruk automatisk referansetelling. Resten av avmerkingsboksene kan stå ukontrollert for dette prosjektet (figur 2). Fortell Xcode hvor du vil lagre prosjektet og klikk Skape.
Figur 1: Velge en prosjektmal Figur 2: Konfigurere prosjektetNøkkelideen for denne tilnærmingen er å vite hva den nåværende konfigurasjonen er. Hva er en konfigurasjon og hvor er de definert? Du kan se en liste over alle prosjektets konfigurasjoner ved å velge prosjektet ditt i Prosjektnavigator og åpner info fanen øverst. Kontroller at du har valgt prosjektet i venstre sidefelt og ikke et mål fra listen over mål (figur 3).
Figur 3: ProsjektkonfigurasjonerI denne opplæringen skal vi anta at vi har en utvikling, en oppføring og et produksjonsmiljø som vi trenger å jobbe med. Begynn med å opprette en ny konfigurasjon for hvert miljø ved å klikke på pluss-knappen under listen over konfigurasjoner. Velg Dupliser "Feilsøking" -konfigurasjon alternativ for hver ny konfigurasjon (figur 4) og gi konfigurasjonen et passende navn (figur 5).
Figur 4: Dupliser feilsøkingskonfigurasjon Figur 5: Tre tilpassede konfigurasjonerNår programmet kjører, må vi kunne finne ut hva den nåværende konfigurasjonen er. Vi kan gjøre dette ved å legge til en ny oppføring i målets Info.plist-fil. Velg målets Info.plist-fil og opprett et nytt nøkkelverdierpar. Sett nøkkelen til konfigurasjon og verdien til $ KONFIGURASJON (figur 6). De KONFIGURASJON Identifikator identifiserer byggekonfigurasjonen (for eksempel Utvikling eller Staging) som målet bruker til å generere produktet.
Figur 6: Legge til en ny oppføring i Info.plistMed disse endringene gjort, kan vi nå hente den nåværende konfigurasjonen i vår søknad. For å prøve dette ut, åpne MTAppDelegate.m og oppdater applikasjons: didFinishLaunchingWithOptions:
som vist under. For å få tilgang til informasjonen i Info.plist, spør vi hovedapplikasjonspakken for sin infoDictionary
. Fra infoordboken tar vi verdien av konfigurasjon nøkkel som vi la til og logg den til Xcode-konsollen. Bygg og kjør programmet for å se hva som er logget på Xcode-konsollen.
- (BOL) søknad: (UIApplication *) søknad didFinishLaunchingWithOptions: (NSDictionary *) launchOptions NSString * configuration = [[[NSBundle mainBundle] infoDictionary] objectForKey: @ "Configuration"]; NSLog (@ "Gjeldende konfigurasjon>% @", konfigurasjon); // Initialiser Window self.window = [[UIWindow alloc] initWithFrame: grenser for [[UIScreen mainScreen]]; // Konfigurer Window self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; returnere JA;
Til tross for at vi opprettet tre tilpassede konfigurasjoner, er den nåværende konfigurasjonen fortsatt satt til Debug. La oss rette opp det i neste avsnitt.
Når du bygger et program, brukes en Xcode-skjema. En Xcode-ordning definerer et antall variabler som skal brukes ved bygging av produktet. En av disse variablene er konfigurasjonen som skal brukes.
Den nåværende Xcode-ordningen vises øverst til venstre på Xcodes verktøylinje. For å enkelt bytte mellom konfigurasjonene (Development, Staging, etc.) som vi opprettet tidligere, anbefaler jeg at du oppretter en Xcode-skjema for hver konfigurasjon. Klikk på den nåværende ordningen, velg Ny ordning fra menyen som vises, og navnet på den nye ordningen Utvikling. Med den nye ordningen valgt, klikk på skjemaet og velg Rediger skjema fra menyen. Å velge Kjør Konfigurerbar fra venstre rute, åpne info kategorien øverst, og sett inn Bygg konfigurasjon til Utvikling (figur 7). Opprett en Xcode-skjema for staging og Produksjon konfigurasjoner ved å gjenta trinnene ovenfor.
Figur 7: Opprette et tilpasset Xcode-skjemaFor å gjøre det enkelt å administrere konfigurasjonsinnstillingene, oppretter vi en egendefinert egenskapsliste som grupperer de forskjellige konfigurasjonsinnstillingene. Opprett en ny eiendomsliste og oppgi navnet Configurations.plist (figur 8). Egenskapslisten er en ordbok med en oppføring for hver konfigurasjon. Hver oppføring i eiendomslisten inneholder en annen ordbok med informasjon som er spesifikk for den konfigurasjonen (figur 9).
Figur 8: Opprett en ny eiendomsliste Figur 9: KonfigurasjonsegenskapslisteSom du kan se, kan du legge til hvilke variabler til Configurations.plist som du liker. Du trenger bare å forsikre deg om at hver oppføring i eiendomslisten inneholder de samme variablene (nøklene).
Du har nå alle nødvendige elementer for å raskt bytte mellom konfigurasjoner. Men vårt arbeid er ikke ferdig ennå. Den nåværende implementeringen er ikke veldig brukervennlig (eller utvikler). Når jeg vedtar denne tilnærmingen, lager jeg alltid en konfigurasjonsklasse som gir meg enkel tilgang til variablene som er definert i Configurations.plist. Konfigurasjonsklassen henter den nåværende konfigurasjonen, belastninger Configurations.plist, og gir enkel tilgang til variablene. Ta en titt på MTConfiguration
klasse under for å se hva jeg mener.
#importere@interface MTConfiguration: NSObject #pragma mark - + (NSString *) konfigurasjon; #pragma mark - + (NSString *) APIEndpoint; + (BOOL) isLoggingEnabled; @slutt
#import "MTConfiguration.h" #define MTConfigurationAPIEndpoint @ "MTAPIEndpoint" #define MTConfigurationLoggingEnabled @ "MTLoggingEnabled" @interface MTConfiguration () @property (kopi, ikkeatomisk) NSString * konfigurasjon; @property (nonatomic, strong) NSDictionary * variabler; @end @implementation MTConfiguration #pragma mark - #pragma mark Delt konfigurasjon + (MTConfiguration *) sharedConfiguration static MTConfiguration * _sharedConfiguration = nil; statisk dispatch_once_t onceToken; dispatch_once (& onceToken, ^ _sharedConfiguration = [[selvtillit] init];); returnere _sharedConfiguration; #pragma mark - #pragma mark Private Initialization - (id) init self = [super init]; hvis (selv) // Hent nåværende konfigurasjon NSBundle * mainBundle = [NSBundle mainBundle]; self.configuration = [[mainBundle infoDictionary] objectForKey: @ "Configuration"]; // Load Configurations NSString * bane = [mainBundle pathForResource: @ "Configurations" ofType: @ "plist"]; NSDictionary * konfigurasjoner = [NSDictionary DictionaryWithContentsOfFile: bane]; // Load Variables for Current Configuration self.variables = [konfigurasjoner objectForKey: self.configuration]; returner selv; #pragma mark - + (NSString *) konfigurasjon return [[MTConfiguration sharedConfiguration] konfigurasjon]; #pragma mark - + (NSString *) APIEndpoint MTConfiguration * sharedConfiguration = [MTConfiguration sharedConfiguration]; hvis (sharedConfiguration.variables) return [sharedConfiguration.variables objectForKey: MTConfigurationAPIEndpoint]; returner null; + (BOOL) isLoggingEnabled MTConfiguration * sharedConfiguration = [MTConfiguration sharedConfiguration]; hvis (sharedConfiguration.variables) return [[sharedConfiguration.variables objectForKey: MTConfigurationLoggingEnabled] boolValue]; returnere NO; @slutt
De MTConfiguration
Klassen gir enkel tilgang til variablene lagret i Configurations.plist. Bytte mellom konfigurasjoner er nå like enkelt som å velge riktig Xcode-skjema. Selv om det kan se ut som en del arbeid foran, kan jeg forsikre deg om at det vil spare deg for en enorm mengde tid - og frustrasjon - nedover veien.
For å teste løsningen, importerer headerfilen til MTConfiguration
klasse i MTAppDelegate.m og oppdatere applikasjons: didFinishLaunchingWithOptions:
metode som vist nedenfor.
#import "MTAppDelegate.h" #import "MTConfiguration.h"
- (BOOL) søknad: (UIApplication *) søknad didFinishLaunchingWithOptions: (NSDictionary *) launchOptions NSLog (@ "Konfigurasjon>% @", [MTCkonfigurasjonskonfigurasjon]); NSLog (@ "API Endpoint>% @", [MTConfiguration APIEndpoint]); NSLog (@ "Er logging aktivert>% i", [MTConfiguration isLoggingEnabled]); // Initialiser Window self.window = [[UIWindow alloc] initWithFrame: grenser for [[UIScreen mainScreen]]; // Konfigurer Window self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; returnere JA;
Egendefinerte konfigurasjoner og Xcode-ordninger kan virkelig bidra til å organisere et prosjekt og strømlinjeforme utviklingsarbeidet. Jeg håper jeg har kunnet overbevise deg om verdien av denne løsningen, spesielt for komplekse prosjekter med flere miljøer.