I am trying to implement background fetch in my iOS app (it's a simple http call that downloads some data for later processing).
I enabled background fetch in my project capabilities:
Also in AppDelegate I set minimum fetch interval:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UIApplication.shared.setMinimumBackgroundFetchInterval(UIApplication.backgroundFetchIntervalMinimum)
return true
}
And implemented fetch handler:
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
do {
try api.downloadInBackground()
} catch {
Debug(self).error(error)
}
completionHandler(.newData)
}
Testing with Debug -> Simulate Background Fetch or custom scheme with enabled background fetch mode work fine and data gets downloaded:
However, when the app is not being debugged background fetch is never invoked. I've read that there's no strict rule when it happens and some time and networking has to be done. However, I've tried leaving device over a weekend (connected to wifi) after I've tried reading some emails browsing, and still nothing happened. What could be wrong?
(At first, I thought it might something to do with a provisioning profile because I did not update it in the apple developer portal, but there's no option to do that, so I suspect that enabling this capability only in the project locally is enough?
Related
I am using the following line in my AppDelegate:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
Database.database().isPersistenceEnabled = true
return true
}
Is this all I need to add to make my ReactJS app available offline? When I compile and run and test through Testflight - I turn off WIFI and use Airplane Mode and my app just returns a blank screen ... do I have to enable something else?
The Database.database().isPersistenceEnabled = true only ensures that data that you app has recently loaded while online is also available when you call the same API next time while offline.
If the app itself doesn't load, it is unrelated to this API call and you'll want to look at how to make a React app available while offline.
I'm using method for background refresh, works when app is active. But in background mode (app isn't killed), can't make Api request to take new data from server.
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> ()) {
case .active:
// works
...
completionHandler(.newData)
case .background:
// doesn't refresh / make api request
completionHandler(.newData)
}
Also remote notifications are enabled on background mode Capabilities.
Any solution for refreshing/ fetching data in background mode?
Maybe the following question, and the answer on that question can help you since it is a similar problem, maybe even a duplicate.
We have implemented the deep link activity in our application. It worked in iOS 11. When we send SMS via a web portal. Its received in iPhone. After updated into iOS 12 the link messages are not received for my iPhone devices. Here is my code below:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let branch: Branch = Branch.getInstance()
branch.initSession(launchOptions: launchOptions, automaticallyDisplayDeepLinkController: true, deepLinkHandler: { params, error in
if error == nil {}}
// Respond to URI scheme links
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
Branch.getInstance().handleDeepLink(url);
return true
}
we have added branch_app_domain, branch_key and URL Type in plist also.
Do we need to add anything in my code ??
After updating a device to iOS 11.2+,the app's AASA file is no longer downloaded reliably onto your user’s device after an app install. As a result, clicking on Universal Links will no longer open the app consistently. You can set forced uri redirect mode on your Branch links to open the app with URI schemes. View details of the issue on the Apple Bug report.
For any further questions, please write to integrations#branch.io.
My app want to update server about users location after every 5 seconds even if app is in background. I implemented Background fetch for it.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil))
application.setMinimumBackgroundFetchInterval(5.0)
return true
}
func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
completionHandler(UIBackgroundFetchResult.NewData)
UpdateData()
}
func UpdateData(){
print("UpdateData executes")
// function to update data when ever this method triggers
}
but the problem is
I am unable to enter performFetchWithCompletionHandler method unless I click Debug>simulate background fetch
How can I achieve to invoke performFetchWithCompletionHandler after every 5 seconds.
You have a misunderstanding about what background fetch is. Developers have no power over when a background fetch will be performed exactly. iOS itself decides when to allow an app to perform a background fetch.
The setMinimumBackgroundFetchInterval function only allows you to specify a minimum time interval that has to pass between background fetches to minimize the energy and data usage of your app. However, the interval you set here does not guarantee at all that your app will be able to perform a background fetch this frequently. The key sentence in the documentation regarding this is "Fetch content opportunistically in the background...".
At the moment, the only way to ensure that your app can execute certain functions (including fetching data from a server) in the background is by sending silent push notifications from your own server at regular intervals. However, even then, the system might decide not to wake up your app in response to a silent push notification if your app takes to long to finish execution in response to the push or if your app receives too many notifications.
I have 4 scenario
When the app is not Launched
Given the app was not Launched or Killed
When the push notification receive
And opened the app without tapping the notification
Then the app should capture the notification.
When the app is running in foreground
Given the app running in foreground
When the push notification receive
Then the app should capture the notification.
When the app is running in background
Given the app is running in background
When the push notification receive
And opened the app without tapping the notification
Then the app should capture the notification.
When the app is not Launched and cleared the notification
Given the app is not Launched or Killed
When the push notification receive
And user cleared the notification
And opened the app
Then the app should capture the notification.
The first 3 scenario works fine with the following code
The last scenario is not worked When the app is not Launched and cleared the notification
AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().getDeliveredNotifications(completionHandler: { requests in
for request in requests {
self.setNotification(userInfo: request.request.content.userInfo as NSDictionary)
}
})
}
return true
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
setNotification(userInfo: userInfo as NSDictionary)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
setNotification(userInfo: userInfo as NSDictionary)
}
According to your query
When the app is not Launched and cleared the notification
Given the app is not Launched or Killed When the post notification
receive And user cleared the notification And opened the app Then the
app should capture the notification.
This is not possible for a Normal Push notification unless the user interacts with that notification. You may want to try Silent notifications, these are not shown in the UI but the control reaches the app and you can use the data/payload from there in your code.
When user clears the notification from bar, there is no way to fetch that information.
You could also try to add the same information that is being sent in the push within an API and call it once the user opens the app.
This link deals with all the detail involved. According to your implementation, you can try a combination of both.