26

Is there way to wakeup iOS app without using "The significant-change location service"?

I need to wakeup my app without server or user intervention Some thing similar to Alarm clock wherein you get an alert popup when it's time to wakeup.

UILocalNotification - Won't work since it would need user and sever intervention.

Silent Push Notifications - Won't work since you cannot send local notifications as Silent push notifications. These can only be sent by Server. Which means it would need Server intervention.

Background Fetch - Won't work since there is not guaranteed trigger time.

Am I missing something?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Haris Farooqui
  • 944
  • 3
  • 12
  • 28

3 Answers3

26

Edit: You have adjusted your question to explicitly state 'without user or server intervention'.

No, As far as I'm aware by design iOS does not provide an explicit way to wake up your app at determinate time in the future. You can continue long running tasks while in the background, opportunistically fetch updated content, remind users to re-open your app if need be and prompt the first two with silent push notifications if need be.

Here are some hints on the three options above:

UILocalNotification

The easiest way is to schedule some UILocalNotifications at a time in the future but in order to wake up your app you need to interact with the notification. This may not be what you want.

Silent Push Notifications

Another option since iOS 7 is a content-available or silent push notification. You setup a particular payload for this kind of notification and if your app has the correct UIBackgroundMode value setup it will be delivered to your app silently:

The payload would look something like this:

{
    "aps" : {
        "content-available" : 1
    },
    "content-id" : 42
}

And you would receive it in your app delegate with a specific delegate method:

- (void)         application:(UIApplication *)application 
didReceiveRemoteNotification:(NSDictionary *)userInfo 
      fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    NSLog(@"Remote Notification userInfo is %@", userInfo);

    NSNumber *contentID = userInfo[@"content-id"];
    // Do something with the content ID
    completionHandler(UIBackgroundFetchResultNewData);
}

You can then use this opportunity download content or update your app quickly if need be, take a look at the UIBackgroundModes and background execution documentation for more info on this approach.

The Multi-Tasking article at Objc.io is also a good start for this approach.

Background Fetch

If you read into the background modes documentation from Apple it's possible using the UIBackgroudnModes value fetch for your app to be woken up opportunistically and given time to download or update it's data.

Apple's documentation on this mentions it's use case:

Apps that need to check for new content periodically can ask the system to wake them up so that they can initiate a fetch operation for that content. To support this mode, enable the Background fetch option from the Background modes section of the Capabilities tab in your Xcode project.

Jessedc
  • 12,320
  • 3
  • 50
  • 63
  • Thanks for you response. Yes. I could send a push notification but this would require user intervention. I believe that I cannot sent local silent notification. Silent notification will always be sent by remote server. I need my app to wakeup without user intervention. – Haris Farooqui Feb 14 '16 at 04:01
  • I've updated my answer quite significantly with more detail on a few options. – Jessedc Feb 14 '16 at 04:23
  • 2
    UILocalNotification - Won't work since it would need user and sever intervention.... Silent Push Notifications - Wont work since you cannot send local notifications as Silent push notifications. These can only be sent by Server. Which means it would need Server intervention.... Background Fetch - Wont work since there is not guaranteed trigger time.... I need to wakeup my app without server or user intervention. – Haris Farooqui Feb 14 '16 at 05:42
  • I've updated my answer to highlight that what you're asking isn't possible, and it's by design. You may need to adjust your expectations of the system. – Jessedc Feb 14 '16 at 21:26
  • @Jessedc thanks for the detailed answer! wondering if it isn't possible, though, how do alarm clock apps work without server intervention? need to do something similar (user sets schedule app should follow) so trying to understand. thanks! – Crashalot Oct 10 '16 at 18:24
  • @Crashalot Are you sure they don't use a server/service to schedule push notifications? (It's pretty easy these days). If not, they would use local notifications as I mentioned, scheduled in the future. iOS 10 has arrived since this post, notifications have been updated a lot so there may be more options. – Jessedc Oct 10 '16 at 22:50
  • @Jessedc yes because some of these alarms still work offline. thanks for answering. – Crashalot Oct 10 '16 at 23:12
  • On receipt of a silent push notification is there a way to keep the app open for a couple of seconds before calling the completionHandler? I need it do some some http work which is asynchronous. At the moment it behaves quite well if the app is in the background, but after a while it starts to fail, meaning the http stuff doesn't kick in. I guess the app has been suspended? I can see in the logs that the push notifications are being received but the downloads aren't been given enough time to complete – pomo Oct 21 '16 at 07:31
  • @Jessedc Silent push notifications will not work if you kill the app explicitly right? – nr5 Jun 22 '18 at 07:17
  • @Jessedc I want to send a tracking event to server, If i get a notification but i want to do that when app is not in running state? Is that possible ? – IamDev Jul 17 '18 at 12:05
1

You could opt out of multitasking. This way the app never enters background or gets suspended. Just wait for the correct time when the alert should be displayed. However, this probably is not the best solution considering the power usage. Also, the app needs to be active all the time. If the user presses the Home button the app is terminated. But the app does not get terminated when the user locks the device. This is the best thing you can do without using any undocumented apis.

If you do not want your app to run in the background at all, you can explicitly opt out of background by adding the UIApplicationExitsOnSuspend key (with the value YES) to your app’s Info.plist file. When an app opts out, it cycles between the not-running, inactive, and active states and never enters the background or suspended states. When the user presses the Home button to quit the app, the applicationWillTerminate: method of the app delegate is called and the app has approximately 5 seconds to clean up and exit before it is terminated and moved back to the not-running state.

Opting out of background execution is strongly discouraged but may be the preferred option under certain conditions.

https://developer.apple.com/library/archive/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

Cœur
  • 37,241
  • 25
  • 195
  • 267
Tapani
  • 3,191
  • 1
  • 25
  • 41
  • Thanks for you reply. Yes that might not be the best and the optimized way to go. In worst case, I might have to ask server to send silent notification and do the needful – Haris Farooqui Feb 22 '16 at 21:45
  • 1
    It's not such a bad solution to ask the server to send a notification. – Tapani Feb 23 '16 at 06:19
0

What you are asking for is against Apple's rule, and I believe no one would like your app doing something secretly in the background without his permission.

And you have listed all the options, that you don't want, but have to count on them.

I think you need to think of how to combine them nicely and user friendly, make them work close what you need.

This is the best combination I can think of:

  • Significant Location Change, you ask for user permission at the first time and occasionally afterwards.
  • Background Fetch, make sure your server return something every time get called, so that iOS won't optimize it to less frequent.
  • Silent Push Notification, you ask for user permission at the first time.
dichen
  • 1,643
  • 14
  • 19
  • 2
    Ofcourse I would be asking for user permission (for the first time) to perform some tasks using silent notification else apple would reject my app. I did think about combinations but it doesn't solve my problem. In worst case, I might have to ask server to send silent notification to do the needful – Haris Farooqui Feb 22 '16 at 21:43
  • 1
    I would not use a combination. Asking a permission for location changes in an alarm clock may feel weird to the user. I wouldn't rely on background fetch either. Silent Push Notifications from the server is so reliable that, as long as there is a network connection, it should work. – Tapani Feb 23 '16 at 09:24
  • 1
    @Tapani many alarm clock apps work without a server, so this must be possible somehow? – Crashalot Oct 10 '16 at 18:25
  • Silent notifcations won't work if you kill the app explicitly by double tapping the home button and swiping it out right? – nr5 Jun 22 '18 at 07:13
  • @nr5 In the [documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623013-application), `However, the system does not automatically launch your app if the user has force-quit it.`, but I've observed that app IS woken up by background pushes even if the user has swiped app from app switcher. Not sure why. – NightFuryLxD Mar 01 '23 at 08:29