วิธีตรวจสอบการเปิดตัวแอพครั้งแรกบน 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จะช่วยคุณ
Charan

คำตอบ:


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 ในฐานะ 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 หายไปและไลบรารีมาพร้อมกับพ็อคสเปค (เผยแพร่ไปยังข้อกำหนดรายละเอียดของ CocoaPods repo)
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;
}

โปรดจำไว้ว่าคุณต้องล็อควิธีนี้ถ้าคุณต้องการที่จะปลอดภัยด้าย
Mati Bot

9
ฉันรู้ แต่วิธีนี้ไม่ใช่ 2 เธรดสามารถเข้าถึง if (! flag) {เมื่อ flag คือ NO พวกเขาจะเข้าไปข้างในถ้าบล็อก หนึ่งในนั้นจะไปด้านในและตั้งค่า NSUserDefaults และอันที่สองจะผ่าน "hasLaunchOnce" (เนื่องจากเธรดแรกประกาศแล้ว) และตั้งค่าผลลัพธ์เป็น NO นั่นหมายความว่าคุณจะได้รับค่าที่ไม่ถูกต้อง
Mati Bot

5

คุณต้องบันทึกบางสิ่งเมื่อคุณเปิดใช้งานจากนั้นตรวจสอบเพื่อดูว่ามีอยู่หรือไม่ ถ้าไม่เป็นครั้งแรก "Something" สามารถเป็นไฟล์รายการฐานข้อมูลการตั้งค่าเริ่มต้นของผู้ใช้ ...


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];ไม่จำเป็นต้องใช้บรรทัด แต่ฉันพบว่าเมื่อแอพทำงานหลายร้อยครั้งในอุปกรณ์หลายร้อยผลก็ไม่น่าเชื่อถือเสมอไปนอกจากนี้ยังเป็นการฝึกฝนที่ดีกว่า


ตัวอย่างของคุณใช้งานได้ แต่ OP ทั้งหมดขอว่าจะเป็นการเริ่มต้นครั้งแรกหรือไม่ บูลนั้นดีมากสำหรับเรื่องนี้ รหัสของคุณสมเหตุสมผลถ้าต้องการทราบว่าผู้ใช้เปิดแอปกี่ครั้ง
tilo

3

เก็บคีย์บูลใน 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

ฉันชอบที่ง่ายและรวดเร็วโดยคริส Fremgen ดังนั้นฉันจึงปรับปรุงมัน

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

นี่คือคำตอบที่ทำงานใน 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()เมื่อใดก็ตามที่คุณต้องการตรวจสอบว่าแอปของคุณถูกเรียก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.