Check how many consecutive days a user has used an app

1.1k Views Asked by At

I've already seen other questions asking about how many times the app has been opened. I want to send a local notification when the user uses the app for 31 consecutive days.

Would this be a NSUserDefaults discovery method or would I need to use an analytics API?

2

There are 2 best solutions below

6
Hitesh Agarwal On BEST ANSWER

Use UserDefault. In appdelegate's didFinishLaunch method check for days count

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
     
    let kLastUsed = "LastUsedTime"
    let kDaysCount = "DaysCount"
    let currentDateTimeInterval = Int(Date().timeIntervalSinceReferenceDate)
    var storedDaysCount:Int = UserDefaults.standard.integer(forKey: kDaysCount)
    if storedDaysCount >= 31 {
        //show pushNotifications
    }
    else {
        let lastDateTimeInterval = UserDefaults.standard.integer(forKey: kLastUsed)
    
        let diff = currentDateTimeInterval - lastDateTimeInterval
        if diff > 86400 && diff < 172800 {
            //next day. increase day count by one
            storedDaysCount = storedDaysCount + 1
            UserDefaults.standard.set(storedDaysCount, forKey: kDaysCount)
        }
        else if diff > 86400 {
            //not next day. reset counter to 1
            UserDefaults.standard.set(1, forKey: kDaysCount)
        }
        
        UserDefaults.standard.set(currentDateTimeInterval, forKey: kLastUsed)
    }
    
    return true
}
1
Edison On

Just expanding on Hitesh's awesome answer to make it more suitable for realtime testing.

You cannot change the date in the simulator settings like you can on a real device. And if you change the date on your real device you might get some Apple server-Xcode syncing issues and Xcode will ask you to register your device in the Developer Portal again.

*Test on a real device using the current time because the UserDefaults needs the date and store from the real device.

To test for minutes or seconds just change all the Ints to Doubles and change the condition to something finer like if storedDaysCount >= 0.0000000015.

let kLastUsed = "LastUsedTime"
let kDaysCount = "DaysCount"
let currentDateTimeInterval = Double(Date().timeIntervalSinceReferenceDate)

var storedDaysCount:Double = UserDefaults.standard.double(forKey: kDaysCount)
    if storedDaysCount >= 0.000000000015 {

        print("storedDaysCount = \(storedDaysCount)")