iOS - How can I schedule something once a day?

4.3k views Asked by At

I know there is NSTimer.scheduledTimerWithInterval

Which is used like this:

override func viewDidLoad() {
    super.viewDidLoad()

    var timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: Selector("update"), userInfo: nil, repeats: true)
}

func update() {
    // Something cool
}

But I assume that the view where var timer is living must be living too, ie: can't close that view (am I right?)

How can I schedule something once a day in iOS, eg: everyday at 8pm send a notification?

In Android I've achieved this the following way:

  1. I've used a thing called AlarmManager, that is similar to the iOS scheduledTimerWithInterval but for large intervals, which is running inside a background service.

  2. At the startup (boot), there is another background service that setups the alarm again. This covers the case when the Android device is shut down (and so the background service is shut down too)

So, in iOS, is there something like scheduledTimerWithInterval for large intervals?

Will I need to set again the interval if the iPhone/iPad is rebooted?

1

There are 1 answers

6
Rob On BEST ANSWER

Yes, to use NSTimer, the app has to be running either in foreground or background. But Apple is quite particular only allowing certain types of apps to continue to run in the background (in an effort to make sure we don't have apps randomly running on their own prerogative and killing our batteries in the process and/or affecting our performance while using the device).

  1. When you say "notification", do you really mean notifying the user of something?

    In that case, the alternative here is to create a UILocalNotification, which is a user notification (assuming they've granted your app permission to perform notifications), which is presented even when your app is not running.

    For example, to register for local notifications:

    let application = UIApplication.sharedApplication()
    let notificationTypes: UIUserNotificationType = .Badge | .Sound | .Alert
    let notificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)
    application.registerUserNotificationSettings(notificationSettings)
    

    And then to schedule the repeating notification:

    let notification = UILocalNotification()
    notification.fireDate = ...
    notification.alertTitle = ...
    notification.alertBody = ...
    notification.repeatInterval = .CalendarUnitDay
    application.scheduleLocalNotification(notification)
    

    For more information, see the Local and Remote Notification Programming Guide.

  2. Or do you mean initiating some process, such as fetching data from a remote server.

    If you want the app to fetch data even if your app isn't running, you can use background fetch. See Fetching Small Amounts of Content Opportunistically in the App Programming Guide for iOS.

    Note, with background fetch, you don't specify when data is to be retrieved, but rather the system will check for data at a time of its own choosing. It reportedly factors in considerations ranging from how often the user uses the app, how often requests to see if there is data result in there actually being new data to retrieve, etc. You have no direct control over the timing of these background fetches.