I'm currently working on an alarm application , and i am implementing a smart alarm feature where i have to fetch data from server to determine whether it is the right time to wake user up.
Let's say, the case is :
Alarm set to 06:30AM
Smart alarm feature set to 30 mins before 06:30 , which the data fetching will happens 5 times with 5 minutes interval starting from 06:00AM to 06:25AM
If , let's say , at 06:15AM the server returned a data which is needed to wake the user up, all tasks scheduled will be cancelled immediately
Current time is 11:30PM
No smart alarm's tasks will be executed during the period of 11:30PM to 06:00AM
You can use Push Notifications / Silent Push Notifications to achieve this task.
Please note the user must opt-in for push notifications for this to work.
Here is an overview of how you can achieve it
Whenever user set's an alarm send this time to server via a web-service.
The server will send a push notification payload to APNS and it will redirect to App based on device token.
Once the device receives notification payload a delegate will be called. You can process the data in this payload related to alarm or invoke a web service call.
Use beginBackgroundTaskWithExpirationHandler to execute your 5 minute interval tasks. beginBackgroundTaskWithExpirationHandler request extra time from the OS to execute a task. It is not specified (intentionally) by Apple how long this extra time is, however in practice it is around 10 minutes.
Please read more in detail about: Push Notifications, Silent Push Notifications & background task handlers.
Background Fetch API : In iOS 7, Apple added support for background fetch—a kind of smart, per-app crontab that wakes up at opportunistic times. There is no way to force background fetches to execute at exact intervals. iOS checks how much data and battery power was used during previous background fetches when scheduling future callbacks.
Adding support involves editing your application’s property list (see UIBackgroundModes) and setting a fetch interval early in the app lifecycle
More Details Here
Related
Scenario: Backend returns a list of appointments with timings and their priorities for the current day (24 hours). iOS application checks for the most important (top priority) meeting and schedule local notification for that particular appointment time.
Requirement: Ideally app should notify user about the most important appointment of the day. So App should fetch the data at-least once in 24 hours (As backend data gets updated for each day) to schedule local notifications for each day.
Problem: To trigger background downloading (Other than background-fetch) reliably and periodically (once in 24 hours) and and execute small code (to schedule local notifications) even after user force quits the application.
I have implemented background fetch to download the data if app is in suspended or in background mode, although it is not reliable. The main problem occurs when user force quit the application from multitasking window (by swiping-up), iOS does not trigger background fetch most of the time (As per the apple documentation, and it is happening in my case as well).
App downloads the data and works fine if user opens it at-least once a day.
I read that silent remote notification can trigger the code by using notification-service-extention, but that need backend to trigger the notification. Is there any way if I can schedule silent local notifications to trigger run code in notification-service-extention
If an app is in the background or terminated and it receives a voip push then the OS will launch it and run it.
The documentation says:
"Your app is given runtime to process a push, even if your app is
operating in the background."
Does anybody know how long this runtime is and if the app can find out how long there is remaining?
If an an app is in the foreground and moves to the background, then if it uses beginBackgroundTask() etc. it can get 30 seconds of execution time.
I've conducted experiments and found that if a silent push is delivered to the app when it is already in the background then the app can also use beginBackgroundTask() in that situation and it also get 30s seconds in which to execute and do something when it receives the push (and it can use UIApplication.shared.backgroundTimeRemaining to see how much time there is remaining.)
BUT if a Voip push is delivered instead of a silent push then beginBackgroundTask() functionality does not work (and of course therefore UIApplication.shared.backgroundTimeRemaining cannot be used to determine remaining execution time), however the app can run in the background and perform some activity (which is what the documentation quoted above says it can do).
So to repeat the question - is it documented by Apple how much time it does get to run when it receives the Voip push? Can the app find out how much time there is remaining? Or get some waring that execution time is about to expire?
1) is it documented by Apple how much time it does get to run when it receives the Voip push?
No, Apple doesn't have this information in documentation
2) Can the app find out how much time there is remaining?
No. When app launched it assumed as executed in Background mode. You will have about 30s for perform necessary tasks.
3) Or get some waring that execution time is about to expire?
No. At least there is no docummented way to do this.
is it documented by Apple how much time it does get to run when it receives the Voip push?
No, There is no official documents available about how much time you
have got, When received VoIP Push notification.
As per my personal experience, You will extends time up to 45 Sec
using long duration sound file if required.
Can the app find out how much time there is remaining? Or get some Waring that execution time is about to expire?
No, There is no official documents or do not available any delegate
method to find how much time remaining.
I have faced same issue, I was overcome above issue using multiple
VoIP Push with different parameters. You can achieved it as below.
As per my requirement, I have to display notification when user received
new incoming call. If user not picked up call then i have to give new notification
for missed call. I was achieved it as below.
1) Generate local notification when received first VoIP Push.
2) Cancel already generated notification and generate new missed call notification for user.
I am not sure, but you can also use timer if working.
Once you get VOIP push payload in didReceiveIncomingPushWithPayload , then you have to schedule local notification with sound file, as per sound file duration your application will awake in background ( while it is in terminated mode ).
Sound file allowed maximum to 30 seconds, and there is no process to know how much time is pending.
UIApplication.shared.backgroundTimeRemaining
Not working to get remaining time because app is not yet awake from AppDelegate, it is awake in background by VOIP delegate methods.
Refer more details.
https://github.com/hasyapanchasara/PushKit_SilentPushNotification
I am working on an app that keeps people updated with news around a certain event. That means that I don't want to run background fetches all the time. And one more thing, what I understood from Apple's background execution documentation is that it is not guarantee to have those fetch operations scheduled as the minimum fetch interval set.
So is there any way to schedule those fetches guaranteeing those fetch intervals? I know of silent push notifications but I don't want to have a server side solution.
I have developed a small iBeacon based application, when the application detects one of our iBeacons makes a call to a web service to obtain a data set and send a local notification to the user. All this is working correctly.
I have now raised the idea that these local notifications could vary over short time intervals, with new content. The problem is that if the user does not leave the region of the iBeacon and reenters, the application will not "wake up" and the user will not receive the new updated notification.
I do not know if this could be solved somehow or actually the approach to make something like that should not be related to technology of iBeacons.
I'm really lost and do not know if anyone would know advise me on how to raise it.
You can schedule local notifications to be delivered at a specific time: use the fireDate and timeZone properties of the UILocalNotification, and then use scheduleLocalNotification instead of the presentLocalNotificationNow method of the UIApplication.
With that in mind you could do this: upon an "enter" event, retrieve a few notifications to be showed to the user over a certain time period while they remain in the zone, schedule them appropriately and let iOS do the delivering.
If the user exits the zone before all the notifications are shown, you can cancel the remaining local notifications using cancelLocalNotification or cancelAllLocalNotifications methods.
In order to do this, you need to get the app to run in the background while beacons are in the vicinity. This would allow you to periodically check for updated content associated with the beacon and then display notifications under two conditions:
When a beacon first appears, and there is a message associated with that beacon.
The message associated with the beacon above changes during the time the beacon is still visible.
As you mention, the second item is a problem, because you need a way to continually check to see if there is updated content despite the fact that iOS will suspend your app within 5 seconds of beacon detection in the background.
A few options, each of which have downsides:
You can use a custom hardware beacon that changes its identifier every minutes or so (e.g. the minor goes back and forth between 0 and 1). This would allow you to monitor two regions and re-trigger on each every minute the beacon is in the vicinity. Downside: This requires building a custom beacon.
You can make your app request an extra 3 minutes of background running time during which you can check for changed messages. Downside: You only get three minutes to display changed messages.
You can specify extra background modes in your .plist so you can continue running in the background. Downside: Apple won't approve your app for distribution in the store unless you have a good reason to run in the background (e.g. a navigation app or a music player app.)
You can send a push notification to your app each time the message changes, which would wake up your app in the background so you could display an updated notification if a beacon is in the vicinity. Downside: Setting up push notifications are a bit complex, delivery can be slow, and is not guaranteed.
Read here for more info on some of these options: http://developer.radiusnetworks.com/2014/11/13/extending-background-ranging-on-ios.html
iOS guidelines apparently don't allow to use background tasks for more than 10 minutes. I am designing a cooking timer app that allows the user to set a specific time and begins a count down.
However it appears impossible to set a background task (e.g. using UILocalNotification or adding an NSTimer to [NSRunLoop mainRunLoop]) that runs for more than 10 minutes.
Is there a work around this? How do developers designs apps that trigger timers that last longer than 10 minutes?
Possible solutions:
A: use server service and run the timer remotely, push notification from server once timer finishes to "warn" user. Cons: expensive to run server, time costly to develop.
B: once the app starts keep it active in the foreground (don't allow the screensaver to trigger). Cons: battery expensive.
Any other ideas?
EDIT: I would like the app to work with iWatch. Hence displaying a glance notification on iWatch once the timer should trigger. As this is guided by the iPhone app I would not be able to do so unless the app is active.
The documentation for UILocalNotification says:
A UILocalNotification object specifies a notification that an app can schedule for presentation at a specific date and time. The operating system is responsible for delivering local notifications at their scheduled times; the app does not have to be running for this to happen.
So, this limit of running apps no more than a few minutes in background does not apply with notifications (as the app doesn't have to be running).
For more information, see the Local and Remote Notification Programming Guide.