2016-05-26 8 views
24

Ehi, sto giocando con il nuovo SDK iOS Firebase, nel mio progetto, ho un solo obiettivo, ho creato due configurazioni, Debug e Release, con identificatore di bundler differente, ma sembra che il file di configurazione scaricato da Firebase supporti solo un bundle identificatore.Nel nuovo Firebase, come utilizzare più file di configurazione in xcode?

Quindi qualcuno sa come utilizzare firebase all'interno di un progetto di identificatore di più codici xcode?

Grazie!

+0

Avete obiettivi diversi per gli schemi, o sono entrambi nella stessa destinazione? –

+0

@IanBarber no Ho un solo obiettivo, ho creato due configurazioni, Debug e Release, con identificatore di bundler differente. – coolbeet

risposta

32

Aggiornamento: consultare la documentazione ufficiale di Firebase https://firebase.google.com/docs/configure/#support_multiple_environments_in_your_ios_application

Aggiornato con una soluzione più semplice:

1. keep the same names for both GoogleService-Info.plist 
2. put one GoogleService-Info.plist inside a subfolder, say "staging" 
3. add references to both files in Xcode while linking them to corresponding targets 
4. just use FIRApp.configure() in your AppDelegate, done 

Il mio primo tentativo che non ha risolto il problema:

Ho rinominato il secondo GoogleService-Info.json in qualcos'altro e ho usato il codice seguente per configurare Firebase da AppDelegate.

// Swift code 
#if STAGING 
    let firebasePlistFileName = "GoogleService-Staging-Info" 
#else 
    let firebasePlistFileName = "GoogleService-Info" 
#endif 
let firbaseOptions = FIROptions(contentsOfFile: NSBundle.mainBundle().pathForResource(firebasePlistFileName, ofType: "plist")) 
FIRApp.configureWithOptions(firbaseOptions) 

Se corro il bersaglio Staging, riceverò denuncia di Firebase su 'Impossibile individuare il file di configurazione: ''.' GoogleService-Info.plist. Ma poi dice "Firebase Analytics v.3300000 avviato".

Come ho controllato sul dashboard di Firebase, sia le app di produzione che quelle di staging registrano gli eventi degli utenti in entrata.

Il metodo configureWithOptions sopra menzionato non è documentato nella documentazione di Firebase, l'ho capito controllando il suo codice sorgente. Non sono sicuro di quale potrebbe essere l'inconveniente di chiamare questo. Mi piacerebbe sentire altri approcci.

+2

La tua risposta aggiornata funziona se hai obiettivi diversi. La risposta originale non ha funzionato per me. La configurazione di Firebase tenta ancora di aprire il file GoogleService-Info. Grazie! –

+0

Grazie per l'aggiornamento! – frank

+4

FIRApp.configureWithOptions è documentato qui: https://firebase.google.com/docs/reference/ios/firebaseanalytics/interface_f_i_r_app#a2e4b970bfb6ed8b606c456f42a82b967 – Peacemoon

14

Ho implementato qualcosa di simile, come ho avuto due schemi per un singolo obiettivo che hanno identificatori di bundle diversi. Nei miei esempi qui sotto, ho due schemi diversi, uno per UAT e uno per PROD.

Creare i due file GoogleService-Info.json e inserirli nella directory del progetto (non nel progetto Xcode) in cartelle diverse, ad es.

ROOT/config/UAT/GoogleService-Info.json 
ROOT/config/PROD/GoogleService-Info.json 

quindi aggiungere i file al progetto Xcode in questo modo:

Xcode project advised folder structure

Ora è necessario aggiungere uno script eseguito nelle fasi di creazione. Questo dovrà essere aggiunto prima della fase di compilazione Fonti:

Drag the Run Script to above Compile Sources

Questo Esegui script prende il file appropriato situato JSON e duplicati nella directory di compilazione app, che significa Firebase/Google identificherà è identico a come identificherebbe il file in una singola configurazione dell'identificatore.

isUAT=`expr "$GCC_PREPROCESSOR_DEFINITIONS" : ".*UAT=\([0-9]*\)"` 

RESOURCE_PATH=${SRCROOT}/${PRODUCT_NAME}/config/PROD 

if [ $isUAT = 1 ]; then 
    RESOURCE_PATH=${SRCROOT}/${PRODUCT_NAME}/config/UAT 
fi 

BUILD_APP_DIR=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app 

echo "Copying all files under ${RESOURCE_PATH} to ${BUILD_APP_DIR}" 
cp -v "${RESOURCE_PATH}/"* "${BUILD_APP_DIR}/" 

Vorrei stima è possibile utilizzare questa stessa logica per Google Analytics pure, che utilizza una simile configurazione file di configurazione JSON.

11

Un approccio migliore se si ha un singolo obiettivo è solo assegnare un nome appropriato ai propri file di configurazione e caricarli come indicato di seguito. Sembra funzionare bene per l'ambiente SVS esempio: Swift 3,0

var fireBaseConfigFile = Bundle.main.path(forResource: "GoogleService-Info-PROD", ofType: "plist") 
    #if UAT 
     fireBaseConfigFile = Bundle.main.path(forResource: "GoogleService-Info-UAT", ofType: "plist") 
    #endif 

    guard let firOptions = FIROptions(contentsOfFile: fireBaseConfigFile) else { 
     assert(false, "Failed to load Firebase config file") 
     return 
    } 

    FIRApp.configure(with: firOptions) 
+5

Questo è stato il metodo più semplice che ho trovato e ha funzionato perfettamente la prima volta. Ho scritto un rapido sommario sul metodo: https://gist.github.com/cohenadair/3a2aff5084603bfa65824f09cf74206e – cohenadair

+0

Grazie @TheiOSChap, hai reso la mia giornata –

+0

Non dovresti mai fare cose del genere in fase di esecuzione perché può influire sull'analisi della tua produzione –

6

Aggiungere entrambi plists servizio di Google al vostro progetto, con nomi diversi:

enter image description here

Poi, per ogni generazione Scheme, selezionare Modifica schema e aggiungere un valore unico per una variabile di ambiente in questo modo:

enter image description here

Quindi la variabile d'ambiente BUILD_FOR dello schema di costruzione sarebbe impostata su "DEV", ad esempio.

Poi, si dovrebbe verificare la presenza di questa variabile in App Delegato e configurare il FIRApp secondo cui schema è stato costruito:

let buildFor = ProcessInfo.processInfo.environment["BUILD_FOR"]! as String 
    var firebasePlistFileName = "GoogleService-Info" 

    if buildFor == "PROD" { 
     firebasePlistFileName = "GoogleService-Prod-Info" 
    } 

    let firbaseOptions = FIROptions(contentsOfFile: Bundle.main.path(forResource: firebasePlistFileName, ofType: "plist")) 
    FIRApp.configure(with: firbaseOptions!) 
+1

Non ho verificato questo, ma se questo è ora possibile con Firebase lo consiglierei. –

6

ho fatto negozio 2 GoogleService-Info con nomi diversi:

  • GoogleService-Info.plist per la produzione
  • GoogleService-Info-Debug.plist per lo sviluppo

e poi andare a Build Phases, aggiungi nuovo script run:

if [ "${CONFIGURATION}" == "Release" ]; then 
cp -r "${PROJECT_DIR}/PathToYourGoogleServiceInfoFile/GoogleService-Info.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" 

echo "Production plist copied" 

elif [ "${CONFIGURATION}" == "Debug" ]; then 

cp -r "${PROJECT_DIR}/PathToYourGoogleServiceInfoFile/GoogleService-Info-Debug.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" 

echo "Development plist copied" 
fi 
1

Utilizzando Objective-C, nel AppDeletage.m:

#ifdef DEBUG 
    filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info-Debug" ofType:@"plist"]; 
#else 
    filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info-Production" ofType:@"plist"]; 
#endif 

    FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:filePath]; 
    [FIRApp configureWithOptions:options]; 
0

Firebase comprende official documentation per sapere come fare questo ora. Ho usato questo metodo nella mia app e funziona benissimo.

In particolare, ho definito un flag Swift personalizzato "BUILD_TYPE" in XCode e per ogni schema, definisco un valore univoco per quel flag. Poi, nel mio AppDelegate, dico quello che Firebase GoogleService-___.plist file da caricare in fase di esecuzione di questo valore bandiera Swift:

let filePath = Bundle.main.path(forResource: "GoogleService-" + Bundle.main.infoDictionary!["BUILD_FLAVOR"] as! String, ofType: "plist") 
    guard let fileopts = FirebaseOptions.init(contentsOfFile: filePath!) else { 
     fatalError("Couldn't load config file") 
    } 
    FirebaseApp.configure(options: fileopts)