Comment détecter le premier lancement d'application sur un iPhone

Réponses:

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.
la source
J'obtiens une erreur car la méthode ne renvoie pas de valeur booléenne. Si j'utilise return 0; pour tuer l'erreur, il échoue.
mrEmpty
@mrEmpty 1. ??? Il revient BOOL. 2. Ensuite, l'erreur est dans votre code ... si le retour de 0 provoque ce plantage, alors quelque chose ne va vraiment pas - ailleurs.
@ H2CO3 - n'est pas NSUserDefaultsun lieu commun? et si une autre application utilise la même "clé" que j'utilise?
Ziv Levy
6
@ZivLevy Non, les valeurs par défaut de l'utilisateur sont stockées dans une liste de propriétés par sandbox (= par application).
2
Cela ne fonctionnera que pour les nouvelles applications qui n'ont jamais été soumises auparavant.
Elad
36

Dans Swift 3, 4 essayez ceci:

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

Dans Swift 2, essayez ceci,

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

MISE À JOUR: - Pour OBJ-C j'utilise ceci,

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

Réf pour OBJ-C: https://stackoverflow.com/a/9964400/3411787

Mohammad Zaid Pathan
la source
32

J'ai écrit une toute petite bibliothèque dans ce but précis. Cela me permet de savoir s'il s'agit du tout premier lancement, ou simplement de cette version, et de toutes les versions précédentes installées par l'utilisateur. Il est disponible sur github en tant que cocoapod sous la licence Apache 2: GBVersionTracking

Vous appelez juste ça application:didFinishLaunching:withOptions:

[GBVersionTracking track];

Et puis pour vérifier s'il s'agit du premier lancement, appelez-le n'importe où:

[GBVersionTracking isFirstLaunchEver];

Et de même:

[GBVersionTracking isFirstLaunchForVersion];

[GBVersionTracking currentVersion];
[GBVersionTracking previousVersion];
[GBVersionTracking versionHistory];
lms
la source
1
C'est presque parfait! Cela aurait été génial sans la dépendance GBToolbox et un podspec.
Stian Høiland
4
@ StianHøiland La dépendance GBToolbox a disparu et la bibliothèque est livrée avec un podspec (publié dans le repo de spécifications de CocoaPods).
lms le
9

pour Swift 3.0 - Swift 5

ajouter une extension

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

puis dans ton code

UIApplication.isFirstLaunch()
KIO
la source
8

Une autre idée pour Xcode 7 et Swift 2.0 est d'utiliser des extensions

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

Vous pouvez désormais écrire n'importe où dans votre application

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

Personnellement, je préfère une extension de UIApplication comme celle-ci:

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

Parce que l'appel de fonction est plus descriptif:

if UIApplication.isFirstLaunch() {
    // do something on first launch
}
dennis-tra
la source
8

Vous pouvez l'implémenter avec la méthode statique ci-dessous:

+ (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
la source
gardez à l'esprit que vous devez verrouiller cette méthode si vous voulez qu'elle soit thread-safe.
Mati Bot
9
Je sais, mais cette méthode ne l'est pas. 2 Threads peuvent atteindre le if (! Flag) {when flag is NO. ils entreront dans les blocs if. l'un d'eux ira à l'intérieur else et définira NSUserDefaults et le second passera le "hasLaunchOnce" (car le premier thread l'a déclaré) et définira le résultat sur NON. Cela signifie que vous pouvez obtenir la mauvaise valeur.
Mati Bot
5

Vous devez enregistrer quelque chose lorsque vous lancez, puis vérifier s'il existe. Sinon, c'est la première fois. "Quelque chose" peut être un fichier, une entrée de base de données, un paramètre par défaut de l'utilisateur ....

Phillip Mills
la source
4

C'est assez simple à faire et ne nécessite que six lignes de code.

Il sera utile d'ajouter ce code dans vos préférences de lancement d'application ou à tout autre endroit où vous pourriez avoir besoin de tester si c'est la première fois que votre application est exécutée ou non.

//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 N'utilisez PAS de booléens dans les préférences simplement aux nombres entiers. Ils sont par défaut à zéro lorsqu'ils ne sont pas définis.

De plus, la [theDefaults synchronize];ligne n'est pas requise, mais j'ai constaté que lorsqu'une application est exécutée des centaines de fois sur des centaines d'appareils, les résultats ne sont pas toujours fiables, en plus, c'est une meilleure pratique.

Milo
la source
Votre exemple fonctionne, mais tout ce que l'OP demande est de savoir s'il s'agit du premier démarrage ou non. Un booléen est parfaitement bien pour cela. Votre code a du sens si l'on veut savoir combien de fois l'utilisateur a ouvert l'application.
tilo
3

stockez une clé booléenne dans NSUserDefaults pour la première fois, ce sera non, vous la changerez en oui et la conserverez comme ça jusqu'à ce que l'application supprime ou réinstalle ce sera à nouveau la première fois.

Malek_Jundi
la source
3

Fonction simple et rapide

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

Pour Swift 2.0 dans Xcode 7. Dans le fichier 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
la source
2

rapide

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

Enregistrez les valeurs par défaut au lancement de l'application:

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

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

        UserDefaults.standard.register(defaults: prefs)

Effacer la valeur lors de l'arrêt de l'application:

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

Vérifier la valeur:

 if Pref.isFirstRun {
    ... do whatever 
Prcela
la source
2

En swift, je suggérerais d'utiliser une constante globale qui peut être effectuée très facilement en dehors de toute portée, comme au-dessus du délégué d'application. Ainsi, il sera défini sur la bonne valeur tant que l'application n'est pas terminée. il renverra toujours la même valeur si l'application passe en arrière-plan ou plus. la valeur ne changera que si l'application est entièrement relancée.

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

Mais honnêtement, il est préférable de suivre le fait que l'application a été envoyée en arrière-plan au moins une fois. Dans ce cas, je préfère utiliser une extension sur UIApplication et définir le drapeau dans la méthode applicationDidEnterBackground de telle sorte que:

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

puis dans votre délégué d'application ou délégué de scène

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

Swift 5 iOS 13.

J'aime rapide et facile par Chris Fremgen . Alors je l'ai mis à jour.

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

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

}
user3069232
la source
2

Mis à jour pour 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
}

Ensuite, vous l'appelez comme

UIApplication.isFirstLaunch()
sasquatch
la source
0

NSUserDefaults + Macro

La meilleure approche consiste à utiliser NSUserDefaultset à enregistrer une BOOLvariable. Comme mentionné ci-dessus, le code suivant fera très bien l'affaire:

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

Vous pouvez également créer une macro comme ci-dessous pour vérifier facilement s'il s'agit du premier lancement ou non

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

Alors utilisez-le comme tel,

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

Voici une réponse fonctionnant dans swift 5.0. L'amélioration par rapport à la réponse de @Zaid Pathan est qu'il n'y a pas de contrat caché. Si vous n'appelez pas setFirstAppLaunch()exactement une fois avant d'appeler, isFirstAppLaunch()vous obtiendrez une erreur d'assertion (uniquement en mode débogage).

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
}

Ensuite, il vous suffit d'appeler la fonction setFirstAppLaunch()au démarrage de votre application et à isFirstAppLaunch()chaque fois que vous souhaitez vérifier si votre application a été appelée.

temps infini
la source