Як виявити перший запуск програми на iPhone


163

Як я можу виявити перший запуск

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  // if very first launch than perform actionA
  // else perform actionB
}

метод?


Я думаю, що stackoverflow.com/questions/5456134/iphone-launch-options допоможе вам
Чаран

Відповіді:


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звичайне місце? що робити, якщо інша програма використовує той самий "ключ", який я використовую?
Ziv Levy

6
@ZivLevy Ні, типові параметри користувачів зберігаються у списку властивостей на основі «пісочниці» (= за програмою).

2
Він працюватиме лише для нових програм, які раніше ніколи не надсилалися.
Elad

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 у вигляді кокапода за ліцензією 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 відпала, а бібліотека поставляється з підспеком (опубліковано в репортажі специфікацій 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
}

Я особисто вважаю за краще таке розширення UIAplus:

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

майте на увазі, що вам потрібно заблокувати цей метод, якщо ви хочете, щоб він був безпечним для потоку.
Mati Bot

9
Я знаю, але цей метод - ні. 2 Нитки можуть досягати знака if (!) {Коли прапор НІ. вони потраплять до блоків if. один з них дістанеться до внутрішнього і встановить NSUserDefaults, а другий передасть "hasLaunchOnce" (тому що перший потік оголосив це) і встановить результат NO. Це означає, що ви можете отримати неправильне значення.
Mati Bot

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 НЕ використовуйте булі в налаштуваннях Просто дотримуйтесь цілих чисел. Вони за замовчуванням до нуля, якщо їх не визначено.

Крім того, [theDefaults synchronize];рядок не потрібен, але я виявив, що коли додаток запускається сотні разів на сотні пристроїв, результати не завжди є надійними, крім того, це краща практика.


Ваш приклад працює, але все ОП просить - це це перший старт чи ні. Бул для цього цілком чудово. Ваш код має сенс, якщо хтось хоче знати, скільки разів користувач відкривав додаток.
tilo

3

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


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

}

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 

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

}

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

0

NSUserDefaults + Макрос

Найкращий підхід - використовувати 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

Ось відповідь, що працює у швидкій версії 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()коли завгодно, щоб перевірити, чи викликано ваш додаток.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.