Can we force BGAppRefreshTask to run on receipt of a silent notification in the background - swift5

Id like to know how to get iOS to fetch data from a server on receipt of a silent notification while the app is in the background.
For background, I'd like my app to fetch fresh data from my server while the app is in the background.
I first looked into BGAppRefreshTask but it seems very unreliable.
From what I can gather it only runs when the system 'thinks' it should so this wont really work for my needs.
In fact, I'm positive that I have implemented BGAppRefreshTask correctly but I have never seen any of the tasks actually execute.
What I would like to do is trigger the fetching of data while my app is in the background by responding to a silent notification.
Can this be achieved somehow with BGAppRefreshTask by responding to a silent notification?
If this is not possible how can I achieve my goal of reliably and predictably fetching data while the app is in the background?

Related

Using a timer to refresh the app in the background

I was thinking about adding a timer to my app so I can use it to refresh data in the background on a regular basis, instead of sending silent notifications through APNs with a server.
Will Apple reject my app if I do this?
After 8 seconds in background the app will pass to the state of suspended and it will simply stop to execute any code. Plus, there is no warranty that the app will not be killed by the system.
It will simply not work.
For the periodic update using APNs with silent notifications, most likely apple will ban you from sending APNs, if you send too many of them.
The way you do periodic updates for your app while in background/suspended/dead is by using Background fetch Background mode.
Please note: You don't decide when or how often the background fetch is executed. it's iOS that will decide based on your app usage per user.
Here a link to a tutorial for background modes including background fetch.
Here the app life cycle and states.

Running the code when application is in the background or device is locked

I have a piece of code wherein I make a server call and based on the response I play a sound. Now, this does not work when my application is in background or my devicei is locked.
Is there any way we can execute this piece of code (Server call and response handling) even if app is in background or device is locked?
There is no general solution, which is by design. (Apple does not want you to have a potentially CPU- and power-intensive process running in the background and degrading user experience.)
There are a few limited-case options available:
You said you want to play a sound. If by this you mean "play music" or some such streaming, there is an audio background task that your application can register to perform. Note that you must actually be streaming audio; Apple rightfully frowns upon apps that try to use this approach to circumvent the general-case prohibition and will reject your App Store submission accordingly.
You can invert your scenario and have the server send a push notification through the Apple Push Notification service. Depending on the user's settings, an alert, badge, or sound can result. This might be the best fit for you if you aren't streaming audio.
If what you are really intending to do is, say, finish an upload or download (and the sound is a completion notification), you can request some additional time to finish that task after the app is nominally backgrounded or the device locked. Use -[UIApplication beginBackgroundTaskWithExpirationHandler:] from within the appropriate UIApplicationDelegate methods to register such a task. Note that you have a limited (but appreciable) amount of time to finish your task, and I don't think you can play media in this mode.

IOS background work

I have an iPhone application like facebook for iPhone. My application must connect my server and read all message every two hours regularly. I have a thread to read all message but when the application is terminated the thread cannot work. Can the thread run undependently from main delegate or how can I find solution for this problem?
You cannot have your app do stuff in the background. There is an API to finish tasks like uploading a photo but even that will be killed after around 10 minutes.
But the Apple Push Notification Service seems like the most appropriate solution for your problem. Your server notifies the device that there is something new happening and you fetch the actual messages when the user opens the app.
edit: As of iOS 7 Apple implemented a feature where you can schedule running tasks to fetch data in the background. Those tasks are not guaranteed to run at any specific times. See the release notes for iOS 7 and the linked methods below:
Apps that regularly update their content by contacting a server can
register with the system and be launched periodically to retrieve that
content in the background. To register, include the UIBackgroundModes
key with the fetch value in your app’s Info.plist file. Then, when
your app is launched, call the setMinimumBackgroundFetchInterval:
method to determine how often it receives update messages. Finally,
you must also implement the
application:performFetchWithCompletionHandler: method in your app
delegate.
There is no solution.
Apple does not permit applications to run in the background unless they are of a specific type such as location or audio or voip or newstand (your app can continue to run for about 10 minutes after it was active if it uses shouldBeginBackgroundTaskWithExpirationHandler).
There is no workaround, many many other people have wondered how to do the same thing as yourself before, but there is no legitimate way. Your app cannot schedule any sort of periodic call home activity.
The only way your app can run once its gone into a suspended or terminated state is for the user to launch it, either explicitly or in reponse to a local notification or remote push notification.

Update my app when it is in background

I want to update some data to my application. Consider the application is in the background state, it is neither Voip or Music or GPS. Is it possible to update/send data to the application which is in background?
NOTE: I dont want to notify the user so that the application becomes active.
Can anyone help me ??
The answer is yes and no.
Apple does allow you app to complete a lengthy process in the background. But if you does not fall in the Voip, music or GPS category then you can't run in background.
If for example you want to send some data to a server, which could take some time, then you can mark that process to back executed until it is finished (or 10min. have passed).
You will find some about Executing a Finite-Length Task in the Background
There is not way to run timers or any thing like that in the backgroud, you can only finish a task you started before the app is backgrounded.
The alert which is displayed is an inbuilt functionality. You can't do anything for that. If a notification is fired from the server and application is in background then the alert will be displayed.
I have done a lot of search in past for this stuff.
I have done this in one of my work. this is what i did.
when application enter : - (void)applicationDidEnterBackground:(UIApplication *)application
I send data to server using ASIHTTPRequest with property :
[request setShouldContinueWhenAppEntersBackground:YES];
But after finished, i didn't do anymore connection or data manipulation. So, only the connection is running at background and not your app. you can't do much after the connection finish.
As #rckoenes was mentioned, you may not execute task too long.
If you would like to update server data while your app is running in the background mode, the application should be active at that time. It can only be active if it uses "music, or voip, or location tracking", otherwise the app will be paused in background mode.
One way to avoid this is to develop your application, and to set it to use, for example, «location tracking». This will allow it to meet the requirements for active background process and you will be able to update server data.
Unfortunately, I do not know whether the app can pass app store approval with this set-up.
However, if you are interested in this solution, you can find an example here.

Would Apple reject an app using sksmtpmessage framework to send e-mail in the background?

I'm thinking in making an app that send e-mails without showing the native iOS mail app. For that I'd be using sksmtpmessage framework.
I'd like as well to keep sending the e-mail when the app goes in background. According to this thread, it would be doable.
I know that Apple limits a few tasks to be done is the background (Audio, VoIP and location). Then my question is, would Apple reject an app using sksmtpmessage framework to send an e-mail from the background?
Cheers :)
If you're just "completing a task" (i.e. the user loads the app to send some e-mails, then quits before they're all sent), you're fine - that's what the Task Completion multitasking mode is for. If you want to run constantly in the background sending e-mail, then it'll almost certainly be a reject (if they spot it) - this isn't something they envisage being done on the iPhone.
From the app docs : An application can call the beginBackgroundTaskWithExpirationHandler: method to ask the system for extra time to complete some long-running task in the background. If the request is granted, and if the application goes into the background while the task is in progress, the system lets the application run for an additional amount of time instead of suspending it. (The backgroundTimeRemaining property of the UIApplication object contains the amount of time the application has to run.)
You can do preceding in time, because iOS 4 gives you a 10 mins of time for task completion after you exit an app.