Come rilevare il primo avvio dell'app su un iPhone


Risposte:


386
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if (![[NSUserDefaults standardUserDefaults] boolForKey:@"HasLaunchedOnce"])
    {
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"HasLaunchedOnce"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
    return YES;
}

Viene visualizzato un errore perché il metodo non restituisce un valore booleano. Se uso return 0; per eliminare l'errore non riesce.
Mr.Empty il

@mrEmpty 1. ??? Ritorna BOOL. 2. Quindi l'errore è nel tuo codice ... se la restituzione di 0 causa questo arresto, qualcosa è terribilmente sbagliato - altrove.

@ H2CO3 - non è NSUserDefaultsun luogo comune? cosa succede se un'altra applicazione utilizza la stessa "chiave" che sto usando?
Ziv Levy,

6
@ZivLevy No, le impostazioni predefinite dell'utente sono memorizzate in un elenco di proprietà in base alla sandbox (= per applicazione).

2
Funzionerà solo per le nuove app che non sono mai state inviate prima.
Elad

36

In Swift 3, 4 prova questo:

func isAppAlreadyLaunchedOnce()->Bool{
        let defaults = UserDefaults.standard

        if let isAppAlreadyLaunchedOnce = defaults.string(forKey: "isAppAlreadyLaunchedOnce"){
            print("App already launched : \(isAppAlreadyLaunchedOnce)")
            return true
        }else{
            defaults.set(true, forKey: "isAppAlreadyLaunchedOnce")
            print("App launched first time")
            return false
        }
    }

In Swift 2 prova questo,

func isAppAlreadyLaunchedOnce()->Bool{
    let defaults = NSUserDefaults.standardUserDefaults()

    if let isAppAlreadyLaunchedOnce = defaults.stringForKey("isAppAlreadyLaunchedOnce"){
        print("App already launched : \(isAppAlreadyLaunchedOnce)")
        return true
    }else{
        defaults.setBool(true, forKey: "isAppAlreadyLaunchedOnce")
        print("App launched first time")
        return false
    }
}

AGGIORNAMENTO: - Per OBJ-C lo uso,

+ (BOOL)isAppAlreadyLaunchedOnce {
    if ([[NSUserDefaults standardUserDefaults] boolForKey:@"isAppAlreadyLaunchedOnce"])
    {
        return true;
    }
    else
    {
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"isAppAlreadyLaunchedOnce"];
        [[NSUserDefaults standardUserDefaults] synchronize];
        return false;
    }
}

Fare riferimento a OBJ-C: https://stackoverflow.com/a/9964400/3411787


32

Ho scritto una piccola biblioteca proprio per questo scopo. Mi fa sapere se questo è il primo lancio in assoluto, o solo per questa versione, e tutte le versioni precedenti che l'utente ha installato. È disponibile su github come cocoapod con licenza Apache 2: GBVersionTracking

Lo chiami e basta application:didFinishLaunching:withOptions:

[GBVersionTracking track];

E poi per verificare se questo è il primo lancio, chiamalo ovunque:

[GBVersionTracking isFirstLaunchEver];

E allo stesso modo:

[GBVersionTracking isFirstLaunchForVersion];

[GBVersionTracking currentVersion];
[GBVersionTracking previousVersion];
[GBVersionTracking versionHistory];

1
Questo è quasi perfetto! Sarebbe stato fantastico senza la dipendenza GBToolbox e un podspec.
Stian Høiland

4
@ StianHøiland La dipendenza GBToolbox è sparita e la libreria viene fornita con un podspec (pubblicato nel repository delle specifiche CocoaPods).
LMS

9

per Swift 3.0 - Swift 5

Aggiungi estensione

    extension UIApplication {
        class func isFirstLaunch() -> Bool {
            if !UserDefaults.standard.bool(forKey: "hasBeenLaunchedBeforeFlag") {
                UserDefaults.standard.set(true, forKey: "hasBeenLaunchedBeforeFlag")
                UserDefaults.standard.synchronize()
                return true
            }
            return false
        }
    }

quindi nel tuo codice

UIApplication.isFirstLaunch()

8

Un'altra idea per Xcode 7 e Swift 2.0 è usare le estensioni

extension NSUserDefaults {
    func isFirstLaunch() -> Bool {
        if !NSUserDefaults.standardUserDefaults().boolForKey("HasAtLeastLaunchedOnce") {
            NSUserDefaults.standardUserDefaults().setBool(true, forKey: "HasAtLeastLaunchedOnce")
            NSUserDefaults.standardUserDefaults().synchronize()
            return true
        }
        return false
    }
}

Ora puoi scrivere ovunque nella tua app

if NSUserDefaults.standardUserDefaults().isFirstLaunch() {
    // do something on first launch
}

Personalmente preferisco un'estensione di UIApplication come questa:

extension UIApplication {
    class func isFirstLaunch() -> Bool {
        if !NSUserDefaults.standardUserDefaults().boolForKey("HasAtLeastLaunchedOnce") {
            NSUserDefaults.standardUserDefaults().setBool(true, forKey: "HasAtLeastLaunchedOnce")
            NSUserDefaults.standardUserDefaults().synchronize()
            return true
        }
        return false
    }
}

Perché la chiamata di funzione è più descrittiva:

if UIApplication.isFirstLaunch() {
    // do something on first launch
}

8

Puoi implementarlo con il metodo statico di seguito:

+ (BOOL)isFirstTime{
    static BOOL flag=NO;
    static BOOL result;

    if(!flag){
        if ([[NSUserDefaults standardUserDefaults] boolForKey:@"hasLaunchedOnce"]){
            result=NO;
        }else{
            [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"hasLaunchedOnce"];
            [[NSUserDefaults standardUserDefaults] synchronize];
            result=YES;
        }

        flag=YES;
    }
    return result;
}

tieni presente che devi bloccare questo metodo se vuoi che sia sicuro per i thread.
Mati Bot

9
Lo so, ma questo metodo non lo è. 2 I thread possono raggiungere if (! Flag) {quando flag è NO. entreranno nei blocchi if. uno di loro andrà nell'altro interno e imposterà NSUserDefaults e il secondo passerà "hasLaunchOnce" (perché il primo thread lo ha dichiarato) e imposterà il risultato su NO. Ciò significa che puoi ottenere il valore sbagliato.
Mati Bot

5

È necessario salvare qualcosa all'avvio e quindi verificare se esiste. Altrimenti, è la prima volta. "Something" può essere un file, una voce di database, un'impostazione di default dell'utente ....


4

È abbastanza semplice farlo e richiede solo sei righe di codice.

Sarà utile aggiungere questo codice nelle preferenze di avvio dell'applicazione o in qualsiasi altro luogo in cui potresti dover verificare se è la prima volta che l'applicazione è stata eseguita.

//These next six lines of code are the only ones required! The rest is just running      code when it's the first time.
//Declare an integer and a default.
NSUserDefaults *theDefaults;
int  launchCount;
//Set up the properties for the integer and default.
theDefaults = [NSUserDefaults standardUserDefaults];
launchCount = [theDefaults integerForKey:@"hasRun"] + 1;
[theDefaults setInteger:launchCount forKey:@"hasRun"];
[theDefaults synchronize];

//Log the amount of times the application has been run
NSLog(@"This application has been run %d amount of times", launchCount);

//Test if application is the first time running
if(launchCount == 1) {
    //Run your first launch code (Bring user to info/setup screen, etc.)
    NSLog(@"This is the first time this application has been run";
}

//Test if it has been run before
if(launchCount >= 2) {
    //Run new code if they have opened the app before (Bring user to home screen etc.
    NSLog(@"This application has been run before);
}

PS NON usare i bool nelle preferenze Basta attenersi ai numeri interi. L'impostazione predefinita è zero quando non definita.

Inoltre, la [theDefaults synchronize];linea non è richiesta ma ho scoperto che quando un'app viene eseguita centinaia di volte su centinaia di dispositivi, i risultati non sono sempre affidabili, inoltre è una pratica migliore.


Il tuo esempio funziona, ma tutto ciò che l'OP richiede è se è il primo avvio o meno. Un bool va benissimo per questo. Il tuo codice ha senso se si desidera sapere quante volte l'utente ha aperto l'app.
tilo,

3

archivia una chiave booleana in NSUserDefaults la prima volta che sarà no, la cambierai in Sì e la manterrai così fino a quando l'app non cancellerà o reinstallerà la prima volta.


3

Funzione semplice e veloce

- (BOOL) isFirstTimeOpening {
    NSUserDefaults *theDefaults = [NSUserDefaults standardUserDefaults];
    if([theDefaults integerForKey:@"hasRun"] == 0) {
        [theDefaults setInteger:1 forKey:@"hasRun"];
        [theDefaults synchronize];
        return true;
    }
    return false;
}

3

Per Swift 2.0 in Xcode 7. Nel file AppDelegate.swift:

import UIKit

@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(application: UIApplication, willFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool
{
    return true
}


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
    didFinishLaunchingOnce()
    return true
}

func didFinishLaunchingOnce() -> Bool
{
    let defaults = NSUserDefaults.standardUserDefaults()

    if let hasBeenLauncherBefore = defaults.stringForKey("hasAppBeenLaunchedBefore")
    {
        //print(" N-th time app launched ")
        return true
    }
    else
    {
        //print(" First time app launched ")
        defaults.setBool(true, forKey: "hasAppBeenLaunchedBefore")
        return false
    }
}

}

2

veloce

struct Pref {
    static let keyFirstRun = "PrefFirstRun"
    static var isFirstRun: Bool {
        get {
            return UserDefaults.standard.bool(forKey: keyFirstRun)
        }
        set {
            UserDefaults.standard.set(newValue, forKey: keyFirstRun)
        }
    }
}

Registra i valori predefiniti all'avvio dell'app:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        let prefs: [String:Any] = [
            Pref.keyFirstRun: true
            ...
        ]

        UserDefaults.standard.register(defaults: prefs)

Cancella valore al termine dell'app:

func applicationWillTerminate(_ application: UIApplication) {
        Pref.isFirstRun = false

Verifica valore:

 if Pref.isFirstRun {
    ... do whatever 

2

In breve suggerirei di utilizzare una costante globale che può essere eseguita molto facilmente al di fuori di qualsiasi ambito come sopra il delegato dell'app. Pertanto, verrà impostato sul valore corretto fino a quando l'app non verrà chiusa. restituirà comunque lo stesso valore se l'app passa in background o giù di lì. il valore cambierà solo se l'app viene riavviata completamente.

let isFirstLaunch: Bool = {
    if !UserDefaults.standard.bool(forKey: "hasBeenLaunchedBeforeFlag") {
        UserDefaults.standard.set(true, forKey: "hasBeenLaunchedBeforeFlag")
        UserDefaults.standard.synchronize()
        return true
    }
    return false
}()

Ma onestamente è meglio tenere traccia del fatto che l'app è stata inviata in background almeno una volta. In tal caso, preferisco utilizzare un'estensione su UIApplication e impostare il flag nel metodo applicationDidEnterBackground in modo tale che:

extension UIApplication {
    private static let isFirstLaunchKey = "isFirstLaunchKey"
    static var isFirstLaunch: Bool {
        return !UserDefaults.standard.bool(forKey: isFirstLaunchKey)
    }
    static func didEnterBackground() {
        if isFirstLaunch {
            UserDefaults.standard.set(true, forKey: isFirstLaunchKey)
            UserDefaults.standard.synchronize()
        }
    }
}

e quindi nel delegato dell'app o delegato scena

func sceneDidEnterBackground(_ scene: UIScene) {
        UIApplication.didEnterBackground()
    }

2

Swift 5 iOS 13.

Mi piace facile e veloce da Chris Fremgen . Quindi l'ho aggiornato.

func isFirstTimeOpening() -> Bool {
  let defaults = UserDefaults.standard

  if(defaults.integer(forKey: "hasRun") == 0) {
      defaults.set(1, forKey: "hasRun")
      return true
  }
  return false

}

2

Aggiornato per XCode 11 , Swift 5

extension UIApplication {
  func isFirstLaunch() -> Bool {
    if !UserDefaults.standard.bool(forKey: "HasLaunched") {
      UserDefaults.standard.set(true, forKey: "HasLaunched")
      UserDefaults.standard.synchronize()
      return true
  }
  return false
}

Quindi lo chiami come

UIApplication.isFirstLaunch()

0

NSUserDefaults + Macro

L'approccio migliore è utilizzare NSUserDefaultse salvare una BOOLvariabile. Come accennato in precedenza, il seguente codice andrà bene:

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:[NSNumber numberWithBool:true] forKey:@"~applicationHasLaunchedBefore"];
[userDefaults synchronize];

Puoi anche creare una macro come di seguito per verificare facilmente se si tratta del primo avvio o meno

#define kApplicationHasLaunchedBefore [[NSUserDefaults standardUserDefaults] objectForKey:@"~applicationHasLaunchedBefore"]

Quindi usalo come tale,

if (kApplicationHasLaunchedBefore) {
    //App has previously launched
} else {
    //App has not previously launched
}

0

Ecco una risposta che funziona in swift 5.0. Il miglioramento rispetto alla risposta di @Zaid Pathan è che non esiste un contratto nascosto. Se non si chiama setFirstAppLaunch()esattamente una volta prima di chiamare isFirstAppLaunch(), verrà visualizzato un errore di asserzione (solo in modalità debug).

fileprivate struct _firstAppLaunchStaticData {
    static var alreadyCalled = false
    static var isFirstAppLaunch = true
    static let appAlreadyLaunchedString = "__private__appAlreadyLaunchedOnce"
}

func setFirstAppLaunch() {
    assert(_firstAppLaunchStaticData.alreadyCalled == false, "[Error] You called setFirstAppLaunch more than once")
    _firstAppLaunchStaticData.alreadyCalled = true
    let defaults = UserDefaults.standard

    if defaults.string(forKey: _firstAppLaunchStaticData.appAlreadyLaunchedString) != nil {
        _firstAppLaunchStaticData.isFirstAppLaunch = false
    }
    defaults.set(true, forKey: _firstAppLaunchStaticData.appAlreadyLaunchedString)
}

func isFirstAppLaunch() -> Bool {
    assert(_firstAppLaunchStaticData.alreadyCalled == true, "[Error] Function setFirstAppLaunch wasn't called")
    return _firstAppLaunchStaticData.isFirstAppLaunch
}

Quindi è sufficiente chiamare la funzione setFirstAppLaunch()all'inizio dell'applicazione e isFirstAppLaunch()ogni volta che si desidera verificare se l'app è stata chiamata.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.