So erkennen Sie den ersten App-Start auf einem iPhone

Antworten:

386
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if (![[NSUserDefaults standardUserDefaults] boolForKey:@"HasLaunchedOnce"])
    {
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"HasLaunchedOnce"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
    return YES;
}
Sameera R.
quelle
Ich erhalte eine Fehlermeldung, weil die Methode keinen booleschen Wert zurückgibt. Wenn ich return 0 benutze; um den Fehler zu töten, schlägt es fehl.
mrEmpty
@mrEmpty 1. ??? Es kehrt zurück BOOL. 2. Dann ist der Fehler in Ihrem Code ... Wenn die Rückgabe von 0 diesen Absturz verursacht, stimmt etwas schrecklich nicht - anderswo.
@ H2CO3 - ist kein NSUserDefaultsalltäglicher Ort? Was ist, wenn eine andere Anwendung denselben "Schlüssel" verwendet, den ich verwende?
Ziv Levy
6
@ZivLevy Nein, Benutzerstandards werden in einer Eigenschaftsliste pro Sandbox (= pro Anwendung) gespeichert.
2
Es funktioniert nur für neue Apps, die noch nie eingereicht wurden.
Elad
36

Versuchen Sie in Swift 3, 4 Folgendes:

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
        }
    }

Versuchen Sie in Swift 2 Folgendes:

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
    }
}

UPDATE: - Für OBJ-C benutze ich dies,

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

Ref für OBJ-C: https://stackoverflow.com/a/9964400/3411787

Mohammad Zaid Pathan
quelle
32

Zu diesem Zweck habe ich eine winzige Bibliothek geschrieben. Hier erfahren Sie, ob dies der erste Start überhaupt ist oder nur für diese Version und für alle früheren Versionen, die der Benutzer installiert hat. Es ist auf Github als Cocoapod unter der Apache 2-Lizenz erhältlich: GBVersionTracking

Sie rufen dies einfach an application:didFinishLaunching:withOptions:

[GBVersionTracking track];

Und um zu überprüfen, ob dies der erste Start ist, rufen Sie dies einfach irgendwo auf:

[GBVersionTracking isFirstLaunchEver];

Und ähnlich:

[GBVersionTracking isFirstLaunchForVersion];

[GBVersionTracking currentVersion];
[GBVersionTracking previousVersion];
[GBVersionTracking versionHistory];
lms
quelle
1
Das ist fast perfekt! Wäre ohne die GBToolbox-Abhängigkeit und eine Podspec fantastisch gewesen.
Stian Høiland
4
@ StianHøiland Die GBToolbox-Abhängigkeit ist weg und die Bibliothek wird mit einer Podspec geliefert (veröffentlicht im CocoaPods Specs Repo).
lms
9

für Swift 3.0 - Swift 5

Erweiterung hinzufügen

    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
        }
    }

dann in deinem Code

UIApplication.isFirstLaunch()
KIO
quelle
8

Eine weitere Idee für Xcode 7 und Swift 2.0 ist die Verwendung von Erweiterungen

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

Jetzt können Sie überall in Ihrer App schreiben

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

Ich persönlich bevorzuge eine Erweiterung von UIApplication wie folgt:

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

Weil der Funktionsaufruf aussagekräftiger ist:

if UIApplication.isFirstLaunch() {
    // do something on first launch
}
Dennis-Tra
quelle
8

Sie können es mit der folgenden statischen Methode implementieren:

+ (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;
}
Mati Bot
quelle
Beachten Sie, dass Sie diese Methode sperren müssen, wenn sie threadsicher sein soll.
Mati Bot
9
Ich weiß, aber diese Methode ist nicht. 2 Threads können das if (! -Flag) erreichen {wenn flag NO ist. Sie werden in die if-Blöcke gelangen. Einer von ihnen gelangt zum inneren else und setzt die NSUserDefaults. Der zweite übergibt "hasLaunchOnce" (weil der erste Thread dies deklariert hat) und setzt das Ergebnis auf NO. Das heißt, Sie können den falschen Wert erhalten.
Mati Bot
5

Sie müssen beim Start etwas speichern und dann überprüfen, ob es vorhanden ist. Wenn nicht, ist es das erste Mal. "Etwas" kann eine Datei, ein Datenbankeintrag, eine Einstellung in den Benutzerstandards sein ...

Phillip Mills
quelle
4

Dies ist recht einfach und erfordert nur sechs Codezeilen.

Es ist hilfreich, diesen Code in den Einstellungen für den Anwendungsstart oder an einer anderen Stelle hinzuzufügen, an der Sie möglicherweise testen müssen, ob Ihre Anwendung zum ersten Mal ausgeführt wurde.

//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 Verwenden Sie in den Einstellungen KEINE Bools einfach an ganze Zahlen. Sie sind standardmäßig Null, wenn sie nicht definiert sind.

Außerdem ist die [theDefaults synchronize];Leitung nicht erforderlich, aber ich habe festgestellt, dass die Ergebnisse nicht immer zuverlässig sind, wenn eine App hunderte Male auf Hunderten von Geräten ausgeführt wird. Außerdem ist dies eine bessere Vorgehensweise.

Milo
quelle
Ihr Beispiel funktioniert, aber das OP fragt nur, ob es der erste Start ist oder nicht. Ein Bool ist dafür vollkommen in Ordnung. Ihr Code ist sinnvoll, wenn Sie wissen möchten, wie oft der Benutzer die App geöffnet hat.
bis
3

Speichern Sie einen Bool-Schlüssel in NSUserDefaults, wenn er zum ersten Mal "Nein" ist. Sie ändern ihn in "Ja" und behalten ihn bei, bis die App beim ersten Mal gelöscht oder neu installiert wird.

Malek_Jundi
quelle
3

Schnelle und einfache Funktion

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

Für Swift 2.0 in Xcode 7. In der Datei 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
    }
}

}
MB_iOSDeveloper
quelle
2

schnell

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

Registrieren Sie die Standardwerte beim Start der App:

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

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

        UserDefaults.standard.register(defaults: prefs)

Klarer Wert bei App-Beendigung:

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

Wert prüfen:

 if Pref.isFirstRun {
    ... do whatever 
Prcela
quelle
2

In Kürze würde ich vorschlagen, eine globale Konstante zu verwenden, die sehr einfach außerhalb eines Bereichs wie über dem App-Delegaten durchgeführt werden kann. Somit wird es auf den richtigen Wert gesetzt, solange die App nicht beendet wird. Es wird immer noch der gleiche Wert zurückgegeben, wenn die App in den Hintergrund wechselt. Der Wert ändert sich nur, wenn die App vollständig neu gestartet wird.

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

Aber ehrlich gesagt ist es besser zu verfolgen, dass die App mindestens einmal in den Hintergrund gesendet wurde. In diesem Fall bevorzuge ich die Verwendung einer Erweiterung für UIApplication und setze das Flag in der applicationDidEnterBackground-Methode so, dass:

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()
        }
    }
}

und dann in Ihrem App-Delegaten oder Szenendelegierten

func sceneDidEnterBackground(_ scene: UIScene) {
        UIApplication.didEnterBackground()
    }
Nicolas Manzini
quelle
2

Swift 5 iOS 13.

Ich mag schnell und einfach von Chris Fremgen . Also habe ich es aktualisiert.

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

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

}
user3069232
quelle
2

Aktualisiert für 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
}

Dann nennst du es als

UIApplication.isFirstLaunch()
sasquatch
quelle
0

NSUserDefaults + Makro

Der beste Ansatz besteht darin NSUserDefaults, eine BOOLVariable zu verwenden und zu speichern . Wie oben erwähnt, reicht der folgende Code aus:

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

Sie können auch ein Makro wie folgt erstellen, um auf einfache Weise zu überprüfen, ob es sich um den ersten Start handelt oder nicht

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

Dann benutze es als solches,

if (kApplicationHasLaunchedBefore) {
    //App has previously launched
} else {
    //App has not previously launched
}
Fernando Cervantes
quelle
0

Hier ist eine Antwort, die in Swift 5.0 funktioniert. Die Verbesserung gegenüber der Antwort von @Zaid Pathan ist, dass es keinen versteckten Vertrag gibt. Wenn Sie vor dem Aufruf nicht setFirstAppLaunch()genau einmal aufrufen isFirstAppLaunch(), wird ein Bestätigungsfehler angezeigt (nur im Debug-Modus).

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
}

Dann müssen Sie nur noch die Funktion setFirstAppLaunch()zu Beginn Ihrer Anwendung aufrufen und isFirstAppLaunch()wann immer Sie überprüfen möchten, ob Ihre App aufgerufen wurde.

Äon
quelle