Как обнаружить первый запуск приложения на iPhone

Ответы:

386
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if (![[NSUserDefaults standardUserDefaults] boolForKey:@"HasLaunchedOnce"])
    {
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"HasLaunchedOnce"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
    return YES;
}
Самера Р.
источник
Я получаю сообщение об ошибке, потому что метод не возвращает логическое значение. Если я использую return 0; убить ошибку не удается.
mrEmpty
@mrEmpty 1. ??? Это возвращается BOOL. 2. Тогда ошибка в вашем коде ... если возвращение 0 приводит к сбою, то что-то ужасно не так - в другом месте.
@ H2CO3 - это не NSUserDefaultsобычное место? Что делать, если другое приложение использует тот же «ключ», который я использую?
Зив Леви
6
@ZivLevy Нет, пользовательские настройки по умолчанию хранятся в списке свойств для каждой песочницы (= для приложения).
2
Он будет работать только для новых приложений, которые никогда не отправлялись ранее.
Элад
36

В Swift 3, 4 попробуйте это:

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

В Swift 2 попробуйте это,

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

ОБНОВЛЕНИЕ: - Для OBJ-C я использую это,

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

Ссылка для OBJ-C: https://stackoverflow.com/a/9964400/3411787

Мухаммед Заид Патан
источник
32

Я написал крошечную библиотеку для этой цели. Это позволяет мне узнать, является ли это первым запуском в истории, или только для этой версии, и любых предыдущих версий, которые установил пользователь. Он доступен на github как cocoapod под лицензией Apache 2: GBVersionTracking

Вы просто называете это в application:didFinishLaunching:withOptions:

[GBVersionTracking track];

А затем, чтобы проверить, является ли это первым запуском, просто вызовите это где-нибудь:

[GBVersionTracking isFirstLaunchEver];

И так же:

[GBVersionTracking isFirstLaunchForVersion];

[GBVersionTracking currentVersion];
[GBVersionTracking previousVersion];
[GBVersionTracking versionHistory];
Пленки
источник
1
Это почти идеально! Было бы здорово без зависимости GBToolbox и подспека.
Stian Høiland
4
@ StianHøiland GBToolbox зависимость исчезла, и библиотека поставляется с podspec (опубликованным в репозитории спецификации CocoaPods).
Lms
9

для Swift 3.0 - Swift 5

добавить расширение

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

тогда в вашем коде

UIApplication.isFirstLaunch()
КИО
источник
8

Другая идея для Xcode 7 и Swift 2.0 - использовать расширения

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

Теперь вы можете написать в любом месте вашего приложения

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

Я лично предпочитаю расширение UIApplication следующим образом:

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

Поскольку вызов функции является более наглядным:

if UIApplication.isFirstLaunch() {
    // do something on first launch
}
Дэннис-тр
источник
8

Вы можете реализовать это статическим методом ниже:

+ (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;
}
Мати Бот
источник
имейте в виду, что вам нужно заблокировать этот метод, если вы хотите, чтобы он был потокобезопасным.
Мати Бот
9
Я знаю, но этот метод не так. 2 потока могут достигнуть if (! Flag) {когда flag равен NO. они попадут внутрь блоков if. один из них доберется до внутреннего else и установит NSUserDefaults, а второй передаст «hasLaunchOnce» (потому что первый поток объявил его) и установит результат в NO. Это означает, что вы можете получить неправильное значение.
Мати Бот
5

Вам нужно что-то сохранить при запуске, а затем проверить, существует ли оно. Если нет, то это первый раз. «Нечто» может быть файлом, записью в базе данных, настройкой по умолчанию для пользователя ....

Филип Миллс
источник
4

Это довольно просто сделать и требует всего шесть строк кода.

Было бы полезно добавить этот код в настройках запуска вашего приложения или в любом другом месте, где вам может понадобиться проверить, работает ли приложение в первый раз или нет.

//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 НЕ используйте bools в настройках Просто придерживайтесь целых чисел. Они по умолчанию равны нулю, когда не определены.

Кроме того, [theDefaults synchronize];линия не обязательна, но я обнаружил, что когда приложение запускается сотни раз на сотнях устройств, результаты не всегда надежны, кроме того, это более эффективная практика.

Milo
источник
Ваш пример работает, но все, что требует OP, это первый запуск или нет. A bool отлично подходит для этого. Ваш код имеет смысл, если вы хотите знать, сколько раз пользователь открывал приложение.
Тило
3

сохраните ключ bool в NSUserDefaults в первый раз, если вы не измените его на да и оставьте так до тех пор, пока приложение не удалит или не переустановит его снова в первый раз.

Malek_Jundi
источник
3

Быстрая и простая функция

- (BOOL) isFirstTimeOpening {
    NSUserDefaults *theDefaults = [NSUserDefaults standardUserDefaults];
    if([theDefaults integerForKey:@"hasRun"] == 0) {
        [theDefaults setInteger:1 forKey:@"hasRun"];
        [theDefaults synchronize];
        return true;
    }
    return false;
}
Крис Фремген
источник
3

Для Swift 2.0 в Xcode 7. В файле 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
источник
2

быстрый

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

Зарегистрируйте значения по умолчанию при запуске приложения:

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

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

        UserDefaults.standard.register(defaults: prefs)

Очистить значение при завершении приложения:

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

Проверьте значение:

 if Pref.isFirstRun {
    ... do whatever 
Prcela
источник
2

В быстром я бы предложил использовать глобальную константу, которая может быть очень легко сделана вне любой области, такой как над делегатом приложения. Таким образом, он будет установлен на правильное значение до тех пор, пока приложение не будет завершено. оно все равно вернет то же значение, если приложение перейдет в фоновый режим или около того. значение изменится, только если приложение будет полностью перезапущено.

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

Но, честно говоря, лучше отследить тот факт, что приложение было отправлено в фоновом режиме хотя бы один раз. В таком случае я предпочитаю использовать расширение для UIApplication и установить флаг в методе applicationDidEnterBackground так, чтобы:

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

а затем в вашем приложении делегат или делегат сцены

func sceneDidEnterBackground(_ scene: UIScene) {
        UIApplication.didEnterBackground()
    }
Николас Манзини
источник
2

Swift 5 iOS 13.

Мне нравится быстро и легко Крис Фремген . Я обновил его.

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

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

}
user3069232
источник
2

Обновлено для 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
}

Тогда вы называете это как

UIApplication.isFirstLaunch()
Sasquatch
источник
0

NSUserDefaults + Macro

Наилучшим подходом является использование NSUserDefaultsи сохранение BOOLпеременной. Как уже упоминалось выше, следующий код будет хорошо работать:

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

Вы также можете создать макрос, как показано ниже, чтобы легко проверить, является ли он первым запуском или нет

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

Тогда используйте это как таковое,

if (kApplicationHasLaunchedBefore) {
    //App has previously launched
} else {
    //App has not previously launched
}
Фернандо Сервантес
источник
0

Вот ответ, работающий в Swift 5.0. Улучшение по сравнению с ответом @Zaid Pathan в том, что нет скрытого контракта. Если вы не позвоните setFirstAppLaunch()ровно один раз перед вызовом, isFirstAppLaunch()вы получите ошибку подтверждения (только в режиме отладки).

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
}

Затем вам просто нужно вызвать функцию setFirstAppLaunch()в начале вашего приложения и isFirstAppLaunch()всякий раз, когда вы хотите проверить, было ли вызвано ваше приложение.

геологический период
источник