2010-11-03 13 views
11

Sto pianificando di aprire un negozio in app e mi piacerebbe dare agli utenti esistenti alcuni articoli gratuitamente.Come determinare la data in cui un'app viene installata o utilizzata per la prima volta?

Ho pensato di rilasciare un aggiornamento che memorizzasse alcune informazioni la prima volta che viene utilizzata l'app, quindi rilasciamo l'aggiornamento "reale" che sembrerebbe se l'app fosse stata acquistata prima, tuttavia, è probabile che non tutti optino per per il primo aggiornamento.

Quindi, c'è un modo per scoprire quando esattamente un utente ha installato (o utilizzato) l'app?

Aggiornamento:

Grazie per le risposte, ma dovrei fare il meno ambiguo:

Sto cercando una chiamata/qualcosa di simile nativo per farlo. Poiché l'app è già in negozio e non ho impostato nulla per archiviare i dati nella prima versione, un aggiornamento mi aiuterà a fare ciò che voglio se tutti gli utenti afferrarlo prima che venga rilasciato il secondo aggiornamento: E ' È impossibile distinguere un nuovo utente da uno esistente che ha perso l'aggiornamento dell'intermediario e si è appena aggiornato a quello più recente.

+0

Come hai risolto questo? Come ha funzionato il controllo dell'ultima data modificata? – Brandon

+0

Sembra che non abbia funzionato a causa di qualche altro bug nel mio programma, ora ha funzionato bene. Non so cosa succederebbe se l'utente eliminasse l'app, quindi la ripristinasse in futuro, ma non riuscivo a trovare un modo migliore. – felace

+0

Hai estratto la risposta a @medTechy, penso che controllare la data di creazione della directory dei documenti delle app degli utenti sia la soluzione giusta !? –

risposta

9

La mia soluzione sarebbe di controllare l'ultima data di modifica di uno dei file nel pacchetto di app.

NSString *sourceFile = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Icon.png"]; 

NSDate *lastModif = [[[NSFileManager defaultManager] attributesOfItemAtPath:sourceFile error:&err] objectForKey:NSFileModificationDate]; 
+1

Sembra che dovresti controllare la data di creazione visto che puoi aggiornare l'icona e quindi inviare una nuova build e non pensare a questo controllo. – mxcl

+2

Sfortunatamente questo non funziona se si deve fare questo con un aggiornamento dato che visualizzerà la nuova data dopo l'aggiornamento :( – Ondrej

+0

Qualcuno ha la minima idea di come farlo su Android? –

1

Si consiglia di impostare semplicemente una data al primo avvio e di memorizzarla in NSUserDefaults. Cerca la data al momento del lancio, se non è lì, impostala. Se lo è, fai un confronto con la data e gestisci il resto in base al tuo piano.

10
NSDate *installDate = [[NSUserDefaults standardUserDefaults]objectForKey:@"installDate"]; 

if (!installDate) { 
    //no date is present 
    //this app has not run before 
    NSDate *todaysDate = [NSDate date]; 
    [[NSUserDefaults standardUserDefaults]setObject:todaysDate forKey:@"installDate"]; 
    [[NSUserDefaults standardUserDefaults]synchronize]; 

    //nothing more to do? 
} else { 
    //date is found 
    NSDate *todaysDate = [NSDate date]; 
    //compare todaysDate with installDate 
    //if enough time has passed, yada yada, 
    //apply updates, etc. 
} 
+0

dolce risolvere, Justin! Ci siamo imbattuti su di esso da parte di Google ed era esattamente quello che stavo cercando. :) – Eric

+0

il problema con questo è, l'utente non può eseguire l'app nella stessa data in cui è stato installato. Ad esempio, tecnicamente, potrebbe installare l'app a gennaio ed eseguirla a marzo, nel qual caso la chiave 'NSUserDefault' memorizzerebbe la data sbagliata (marzo). –

+0

Vero, ma semanticamente parlando potremmo semplicemente cambiare il bool di installDate su "firstRun". Non c'è modo di conoscere la data di installazione assoluta. Tranne il ragazzo sotto di me dice che la data di creazione della directory docs è vera per l'installazione. Neat – Justin

0

È sempre possibile controllare sul server. Era semplice con UDID ma dato che questi sono deprecati hai creato un UUID (CFUUIDCreate() o qualcosa del genere :)) e lo memorizzi nel portachiavi, ogni informazione memorizzata nel portachiavi rimarrà persistente anche se l'utente eliminerà il app e installa di nuovo dopo circa un anno ... Ho trovato questo articke davvero utile quando gestivo i valori del portachiavi per la prima volta: http://useyourloaf.com/blog/2010/3/29/simple-iphone-keychain-access.html

1

Risposta per vedere se le persone possono trovare difetti in questo. Sembrava più lungo degli altri che trovo qui, ma lo fa dire se applicazione è in esecuzione, per la prima volta da quando l'aggiornamento (per questo è necessario cambiare la vostra info.plist) ...

// called during startup, compares the current version string with the one stored on standardUserDefaults 
+ (BOOL)isFreshInstallOrUpdate 
{ 
    BOOL ret = YES; 
    NSString *cfBundleVersionStored = [[NSUserDefaults standardUserDefaults] objectForKey:@"CFBundleVersion"]; 
    NSString *cfBundleShortVersionStringStored = [[NSUserDefaults standardUserDefaults] objectForKey:@"CFBundleShortVersionString"]; 

    NSString *cfBundleVersionPlist = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];; 
    NSString *cfBundleShortVersionStringPlist = [[NSBundle mainBundle] objectForInfoDictionaryKey: 
               @"CFBundleShortVersionString"]; 

    ret = [cfBundleVersionPlist compare:cfBundleVersionStored] != NSOrderedSame || 
    [cfBundleShortVersionStringPlist compare:cfBundleShortVersionStringStored] != NSOrderedSame; 

    return ret; 
} 


// calling this once will necessarily cause isFreshInstall to return false 
+ (void)setStoredVersionNumber 
{ 
    NSString *cfBundleVersionPlist = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]; 
    NSString *cfBundleShortVersionStringPlist = [[NSBundle mainBundle] objectForInfoDictionaryKey: 
               @"CFBundleShortVersionString"]; 

    [[NSUserDefaults standardUserDefaults] setObject:cfBundleVersionPlist forKey:@"CFBundleVersion"]; 
    [[NSUserDefaults standardUserDefaults] setObject:cfBundleShortVersionStringPlist forKey:@"CFBundleShortVersionString"]; 

    // setting now as unfresh! 
    [[NSUserDefaults standardUserDefaults] synchronize]; 
} 
29

Per ottenere il data di installazione, controllare la data di creazione della cartella Documenti.

NSURL* urlToDocumentsFolder = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; 
__autoreleasing NSError *error; 
NSDate *installDate = [[[NSFileManager defaultManager] attributesOfItemAtPath:urlToDocumentsFolder.path error:&error] objectForKey:NSFileCreationDate]; 

NSLog(@"This app was installed by the user on %@", installDate); 

per ottenere la data dell'ultimo aggiornamento App, controllare la data di modifica di App riunire in sé

NSString* pathToInfoPlist = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"]; 
NSString* pathToAppBundle = [pathToInfoPlist stringByDeletingLastPathComponent]; 
NSDate *updateDate = [[[NSFileManager defaultManager] attributesOfItemAtPath:pathToAppBundle error:&error] objectForKey:NSFileModificationDate]; 

NSLog(@"This app was updated by the user on %@", updateDate); 
+0

Sembra la soluzione giusta, qualsiasi organismo sa perché questo non potrebbe funzionare? –

+0

Errore di digitazione in questo, pathToDocumentsFolder dovrebbe essere un oggetto NSURL. Dovresti quindi utilizzare l'accessorpath .path quando fai riferimento al metodo attributesOfItemAtPath. Altrimenti sembra funzionare alla grande. – steemcb

+0

Grazie! Risolto il problema di battitura. –

0

soluzione Swift:

let urlToDocumentsFolder = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).last! 
//installDate is NSDate of install 
let installDate = (try! NSFileManager.defaultManager().attributesOfItemAtPath(urlToDocumentsFolder.path!)[NSFileCreationDate]) 
print("This app was installed by the user on \(installDate)") 
1

App data di realizzazione:

public var appBuildDate: Date { 
    if let path = Bundle.main.path(forResource: "Info", ofType: "plist") { 
    if let createdDate = try! FileManager.default.attributesOfItem(atPath: path)[.creationDate] as? Date { 
     return createdDate 
    } 
    } 
    return Date() // Should never execute 
} 

Installazione di app d mangiato:

public var appInstallDate: Date { 
    if let documentsFolder = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last { 
    if let installDate = try! FileManager.default.attributesOfItem(atPath: documentsFolder.path)[.creationDate] as? Date { 
     return installDate 
    } 
    } 
    return Date() // Should never execute 
} 
Problemi correlati