2012-04-13 9 views
15

Ho impostato le notifiche push nella mia app. Sto provando a determinare se il token del dispositivo ricevuto da APNS nel metodo application:didRegisterForRemoteNotificationsWithDeviceToken: proviene dalla sandbox o dall'ambiente di sviluppo. Se riesco a distinguere quale ambiente ha inizializzato il token, sarò in grado di dire al mio server su quale ambiente inviare la notifica push.Determinare se l'app sta comunicando con la sandbox APNS o l'ambiente di produzione

Ho provato a utilizzare la macro DEBUG per determinare ciò, ma ho visto un comportamento strano con questo e non mi fido che sia corretto al 100%.

#ifdef DEBUG 
BOOL isProd = YES; 
#else 
BOOL isProd = NO; 
#endif 

Idealmente, sarei in grado di esaminare il aps-environment diritto (il valore è lo sviluppo o produzione) nel codice, ma non sono sicuro se questo è ancora possibile.

Qual è il modo corretto per determinare se l'app sta comunicando con la sandbox APNS o gli ambienti di produzione? Presumo che il server abbia bisogno di sapere questo in primo luogo. Per favore correggimi se questo è un presupposto errato.

Modificato: la documentazione Apple su Provider Communication with APNS descrive la differenza tra la comunicazione con la sandbox e la produzione. Tuttavia, la documentazione non fornisce informazioni su come essere coerenti con la registrazione del token (dall'app client iOS) e la comunicazione con il server.

risposta

14

è possibile leggere e controllare il profilo di provisioning incorporato.

https://github.com/tcurdt/TCMobileProvision

Questo è quello che faccio:

NSString *mobileprovisionPath = [[[NSBundle mainBundle] bundlePath] 
     stringByAppendingPathComponent:@"embedded.mobileprovision"]; 
TCMobileProvision *mobileprovision = [[TCMobileProvision alloc] initWithData:[NSData dataWithContentsOfFile:mobileprovisionPath]]; 
NSDictionary *entitlements = mobileprovision.dict[@"Entitlements"]; 
NSString *apsEnvironment = entitlements[@"aps-environment"]; 
BOOL production = entitlements && apsEnvironment && [apsEnvironment isEqualToString:@"production"]; 
+0

La libreria è un po 'obsoleta, ma ha funzionato bene per l'acquisizione di 'aps- environment' (sostituisci '" get-task-allow "' con '" aps-environment "' nell'esempio di @tcurdt, e non confrontarlo come bool) –

+0

@AlbertBori potresti per favore presentare un problema su cosa è é piú attuale? – tcurdt

+0

Sicuro! Ecco qua: https://github.com/tcurdt/TCMobileProvision/issues/1 –

4
  1. L'ambiente APNS è determinata in base ai diritti del segno di codice corrispondente alla vostra identità Codice segno (buon posto here) - identificando la vostra configurazione di generazione può funzionare, può anche essere falso se hai corrispondeva a quella configurazione di generazione con un diritto errato.

  2. Tenendo questo in mente, utilizzando DEBUG come mezzo per determinare i diritti dovrebbe funzionare (se trovate DEBUG per essere difficile, è possibile aggiungere una propria bandiera linker sotto "Apple LLVM ..." -> "Altro C Flags" -> "Debug") ad esempio, aggiungere -DDEBUGGING e quindi utilizzare:

#ifdef DEBUGGING BOOL isProd = YES; #else BOOL isProd = NO; #endif

+0

Grazie per la risposta, @ Wiz. Ho finito per usare un booleano nel file plist di configurazione. L'unica presa, come hai detto, è che questa impostazione di configurazione deve corrispondere all'identità di firma del codice, che si trova nel file di progetto. È indesiderabile, ma la migliore soluzione disponibile. – goldierox

+0

concordato. Apple potrebbe facilmente fornire API per dirti quale sia la titolarità corrente - quindi potresti impostare la produzione o indirizzare i token sandbox sul tuo server sandbox ... –

0

Come accennato nella risposta @ di tcurdt, l'unico modo sicuro per determinare se utilizzare la sandbox o meno è quello di controllare il file di provisioning. Ecco il codice Swift, utilizzando TCMobileProvision:

func isAPNSandbox() -> Bool { 
    if let mobileProvisionURL = NSBundle.mainBundle().URLForResource("embedded", withExtension: "mobileprovision"), 
    let mobileProvisionData = NSData(contentsOfURL: mobileProvisionURL), 
    let mobileProvision = TCMobileProvision(data: mobileProvisionData) { 
     if let entitlements = mobileProvision.dict["Entitlements"], 
     let apsEnvironment = entitlements["aps-environment"] as? String 
     where apsEnvironment == "development" { 
      return true 
     } 
    } 

    return false 
} 

Per installare TCMobileProvision, aggiungere questo al vostro Podfile:

pod 'TCMobileProvision', :git => 'https://github.com/tcurdt/TCMobileProvision.git' 
+0

phatmann, grazie per il codice Swift. Sono curioso di sapere se hai un motivo per controllare uno stato booleano di Sandbox e non restituirlo vero se in produzione? Quello che ho scoperto è che se sto eseguendo una build locale da xCode fallisce quando si tenta di caricare 'mobileprovision', che provoca un ritorno di false (indicando che NON è nella sandbox). Tuttavia, se creo un file Archive con provisioning sandbox che carica correttamente il file mobileprovision e indica correttamente che si tratta di una build Sandbox. Stando così le cose sembra necessario testare per trovare con successo "produzione". – KeithB

+0

@KeithB sembra che l'approccio migliore potrebbe essere quello di restituire un enum con 'sandbox',' production' e 'unspecified'. Sentiti libero di modificare il codice in modo appropriato. – phatmann

4

Questo è un hack, ma il suo lavoro su XCode 8 con Swift 3

Noi' fondamentalmente aprendo il file embedded.mobileprovision, convertendolo in una stringa, quindi controllando la presenza di una stringa che indicherebbe che l'app utilizza l'ambiente di sviluppo aps.

func isDevelopmentEnvironment() -> Bool { 
    guard let filePath = Bundle.main.path(forResource: "embedded", ofType:"mobileprovision") else { 
     return false 
    } 
    do { 
     let url = URL(fileURLWithPath: filePath) 
     let data = try Data(contentsOf: url) 
     guard let string = String(data: data, encoding: .ascii) else { 
      return false 
     } 
     if string.contains("<key>aps-environment</key>\n\t\t<string>development</string>") { 
      return true 
     } 
    } catch {} 
    return false 
} 
Problemi correlati