2012-03-28 12 views
11

È possibile in qualche modo codificare come di seguito nell'app iOS?Verifica se l'app iOS è attiva nell'app store

if(app is live in app store) 
{ 
    //Do something 
} 
else 
{ 
    //Do other thing 
} 

Volevo evitare casi in cui il nostro team di QE/Dev utilizza l'app per i test. C'è un modo per rilevare come viene firmato il codice dell'app (Sviluppatore/Adhoc/Distribuzione) per verificare? Anche se è possibile, non eliminerà i casi in cui Apple utilizza la nostra app per i test come parte della revisione. Abbiamo registrato molti download dei nostri contenuti da parte di Apple prima che la nostra app venga pubblicata in App Store.

+1

Perché vuoi farlo? È possibile utilizzare macro di preprocessore per distinguere tra build di debug e release, ma il team di revisione di Apple deve utilizzare la stessa app dei clienti senza modifiche. Puoi utilizzare un test lato server degli indirizzi IP per assicurarti di non fatturare i revisori per i contenuti scaricati o altro, ma non cercare di ingannarli. –

+0

Ho già macro per differenziare il debug e rilasciare build. Ma non è quello che voglio. Utilizziamo testflight per inviare le nostre app a clienti e tester. Il problema è che quando scaricano qualsiasi contenuto non vogliamo tracciarlo perché non sono utenti reali.Una soluzione (in teoria) che ho pensato è prendere decisioni basate sul profilo di provisioning "Ad-Hoc/Developer" o "Distribution" utilizzato nel codice. Come, ho bisogno di capire. Un altro problema è il contenuto scaricato da Apple come parte della revisione. In che modo posso rilevarlo? – msk

+0

È possibile aggiungere un parametro per le richieste al server quando si tratta di una build AdHoc e controllare tale parametro sul server. Quando Apple verifica l'app, puoi rilevare l'indirizzo IP sul tuo server. –

risposta

8

È possibile determinare se l'app è stata distribuita tramite l'app store controllando l'assenza di embedded.mobileprovision. Questo file è incluso solo in build ad hoc.

Ti piace questa:

if ([[NSBundle mainBundle] pathForResource:@"embedded" 
            ofType:@"mobileprovision"]) { 
    // not from app store (Apple's reviewers seem to hit this path) 
} else { 
    // from app store 
} 

Questa tecnica è da the HockeyApp SDK. Personalmente ho applicazioni nel negozio che usano questa tecnica, e naturalmente ci sono molte app distribuite che includono l'HKK App di HockeyApp.

Sulla base di un arresto improvviso, ho accidentalmente rilasciato una particolare build della mia applicazione nel percorso "da app store", il team di Apple seguirà il percorso "non da app store". Lascia che la mia perdita sia il tuo guadagno su quello. :)

+1

Questo distinguerà i tester Apple? Usano la propria MobileProvision per caricare app per il test o hanno un modo speciale per caricarle? – xdumaine

+0

Buona domanda. Non conosco la risposta. Ho avuto codice che utilizza questa tecnica approvata da Apple e, come parte dell'SDK HockeyApp, è probabilmente abbastanza diffuso. Quindi se sei curioso di sapere se ti farà rifiutare, sembra che non lo farà. Oltre a questo…? –

+2

Ok, ora ho prove abbastanza forti (anche se non conclusive) che il team di Apple App Review seguirebbe il percorso "non da app store" in questo codice. –

1

Ho affrontato una situazione simile nella mia app. Almeno credo di averlo fatto, non sono sicuro di comprendere appieno la tua domanda.

Nella mia app ho utenti con account che creano contenuti. Non voglio che il contenuto dello sviluppatore (o il contenuto dei dipendenti Apple) non inquini il contenuto pubblico. Ho un bit di "test" nella struttura dati utente che viene attivata e il contenuto del test non è visibile al pubblico. Non ho ancora inviato all'App Store ma dovrò collaborare con Apple per assicurarmi che i loro account abbiano attivato questo bit di prova.

Se questo non è il tuo obiettivo, beh, non importa poi! : -)

+0

Puoi elaborare quello che chiedi ad Apple? Cosa intendi con "test" bit? Come si imposta/resetta qualcuno? – msk

+0

Sul mio server, ho una struttura dati utente, contiene cose come Login, password, e-mail. Ha anche un booleano chiamato "test". Se il valore booleano è ON, la mia applicazione si comporta in modo diverso. L'ho impostato tramite un'API sul mio server. Quando invio al negozio Apple, dovrò lavorare con loro per assicurarmi che il bit di test sia attivo. –

+0

Ahhh, vedo il tuo commento qui sopra. Sì, puoi avere un account speciale per TestFlight e gli utenti Apple. Non risponde alla tua domanda ma risolverà il tuo problema. –

3

Su iOS 7 e versioni successive, si può anche essere in grado di controllare:

if ([NSData dataWithContentsOfURL:[NSBundle mainBundle].appStoreReceiptURL] != nil) { 
    // Downloaded from App Store 
} else { 
    // Not downloaded from App Store 
} 
+0

Funzionerà anche per le app gratuite? Penso che [NSBundle mainBundle] .appStoreReceiptURL sarà nullo in questo caso, giusto? – msk

+0

Non ho provato questo (l'investimento in termini di tempo per aggiungere questo a un'app, farlo approvare e in qualche modo estrarre i dati è piuttosto significativo). Ma a quanto ho capito, un'applicazione gratuita conta come un "acquisto", solo uno che avviene a costo zero per il consumatore. –

0

Swift

func isAppStoreBuild() -> Bool { 

    if NSBundle.mainBundle().appStoreReceiptURL != nil { 
     if let _ = NSData(contentsOfURL: NSBundle.mainBundle().appStoreReceiptURL!) { 
      return true 
     } 
    } 
    return false 
} 
2

Questo non funziona più con XCode 7, vorrei suggerire a utilizzare la nuova soluzione HockeyApp https://github.com/bitstadium/HockeySDK-iOS/blob/6b727733a5a93847b4a7ff8a734692dbe4e3a979/Classes/BITHockeyHelper.m Ecco una versione semplificata:

+ (BOOL)isAppStoreBuild 
{ 
#ifdef DEBUG 
    return NO; 
#else 
    return ([UIApplication isTestFlightBuild] == NO); 
#endif 
} 

+ (BOOL)isTestFlightBuild 
{ 
#ifdef DEBUG 
    return NO; 
#else 
    NSURL *appStoreReceiptURL = NSBundle.mainBundle.appStoreReceiptURL; 
    NSString *appStoreReceiptLastComponent = appStoreReceiptURL.lastPathComponent; 
    BOOL isSandboxReceipt = [appStoreReceiptLastComponent isEqualToString:@"sandboxReceipt"]; 

    return isSandboxReceipt; 
#endif 
} 
0

Per la versione Swift:

private static let isTestFlight = NSBundle.mainBundle().appStoreReceiptURL?.lastPathComponent == "sandboxReceipt" 

This complete answer spiega più elaborato su come si potrebbe usarlo.