IOS delegation not working when the app is in background - ios

I am currently implementing the delegation in IOS.
But when I put a breakpoint in the XCode and I do some thing which is going to respond back after fe seconds like HTTP request
Then I am checking invoking the delegate method.
But the break point is reached, but it reached only if I restore the application from background. Even sometimes the NSLog is alos not printing when the app in background.
Is this a default behaviour of XCode, can anyone please help me on this
Can we say no normal method calling functionality will work in a background app?

If you need your app to continue operating after being sent to background (your HTTP or network transactions), then you need to execute those operations as a Background task from the beginning. Look at:
https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

Table 3-1 on this page shows the various background modes you can register for:
https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html#//apple_ref/doc/uid/TP40007072-CH4-SW23
While it's possible to register for one of the background modes, just for the sake of being able to du background stuff, it's highly discouraged as Apple might reject the app if you register some background mode that is not necessary for the purpose of your app.
Not knowing exactly what you need, maybe "Background fetch" could solve your problem, since you mention HTTP request?

Related

Implementing a service in background on iOS

I have a custom framework which the client app can consume. I want the framework API's to run even when the application enters the background. How can I achieve this?
Thanks in advance.
It depends on what your app is doing after entering the background.
Perhaps you are looking for UIBackgroundTask. You can take a look at the method beginBackgroundTaskWithExpirationHandler: of UIApplication.
This method lets your app continue to run for a period of time after it transitions to the background. You should call this method at times where leaving a task unfinished might be detrimental to your app’s user experience. For example, your app could call this method to ensure that had enough time to transfer an important file to a remote server or at least attempt to make the transfer and note any errors. You should not use this method simply to keep your app running after it moves to the background.
Background execution on iOS is a very advanced topic.
Without any details, all I can do is forward you to the official Apple documentation.
This explains ALL possible modes that allow your app to run in background.

Periodically update blockerList.json from a server

I’m building a content blocker app for iOS.
Is there any way I can update the blockerList.json file from a server periodically in the background?
I have no idea how to do this, or even where to start.
If, and only if, a background task improves user experience you can declare an iOS app to have a task that runs in the "background". That is, even when another app is in the foreground, your app could potentially perform tasks "in the background".
However, be very picky about that requirement - often enough, it's not really necessary to do this. In your case for example, you could load the list when your app will move to the foreground, and then periodically while it is in the foreground. Doing things in the background when it is not really necessary will drain battery for nothing - one of the bad habits users hate the most!
Well, lets assume you have good reasons for doing it anyway ;)
An iOS app which has not declared such kind of background task will stop executing shortly after it ceases to run in the foreground. In order to support apps that really have to do something in the background - that is, when this app is not in the foreground - there are a couple of certain "background execution modes" (UIBackgroundModes) which can be used to declare that your app wants to execute such kind of task in the background.
So, the first is to find an appropriate "background execution mode" suitable for your background task and declare that in the Info.plist of your app. (In your case, the suitable mode would be fetch: "The app regularly downloads and processes small amounts of content from the network.")
The next thing is to implement the task and the necessary hooks (uhm, I mean delegates), that is in your case you need to implement application:performFetchWithCompletionHandler. You also need to deal with the "application state transitions".
Here are a few pointers to the Apple docs: https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/
And here is a tutorial: http://hayageek.com/ios-background-fetch/

how to handle a long wait time for data, when ios 8+ app has been backgrounded by user

I've spent a lot of time looking at the options but am still not 100% clear, so wanted to reach out for some guidance.
Scenario is this:
User submits an HTTPS request to our backend server for some data via an iOS app
Depending on the data, the first (only) request can take a REALLY long time. like, say, 10+ minutes (shocking i know)
When that payload finally does become available and is returned via the HTTPS request, we then want to use it to update the UI in background.
The assumption here is that the user has moved on to another app whilst waiting for the data to arrive (and lets also assume they haven't killed the app).
Is it possible to handle this via iOS 8+ API's without the app being force/killed by Apple when in the background ?
Could we use background task for example?
var backgroundTask: UIBackgroundTaskIdentifier
xxx.beginBackgroundTaskWithName...
etc
Before testing some code blocks we just wanted to see if someone has (a) already done this and/or (b) whether we're heading in the right direction
Thanks for your help.
You should re-think on your web service which may take almost 10 min to process. If you are not able to optimize server task processing time then below one of the idea may be help you.
You can divided your one request into multiple request to reduce processing time and get response in faster way.
Your server should sent notification to app when its done with its task. So app will came to know task is done.
I am not sure why you try to update UI when apps in background mode , you may try to update UI when users come to foreground mode from background mode.
Please check this link which show as example of long running task. Where its use a blank audio play to keep alive app background task.
You can used "Background fetch" functionality.
For learning purpose you can refer this link

Call web service even if ios app is in background

In my application I need to log user status every 15 minutes. Is it possible if the app is in background (not killed)??
Currently I enables the Background location update. But how to call in each and every 15 minutes
While other answers are correct about background fetch, there is also another background option called VoIP, which apps like Skype use. In this case OS will wake up your application more frequently (even every 10 minutes if I remember correctly) and you can keep pinging your server in background. The obvious down side is that your app must have Voice over IP functionality, otherwise it would get rejected on the App Store.
All you need to do is add call setKeepAliveTimeout:handler: method and have voip enabled in background capabilities.
Just adding this for the sake of completion.
You may want to look at the Background Fetch capabilities added in iOS7 and beyond:
http://www.appcoda.com/ios7-background-fetch-programming/
https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html (Search for background fetch)
You won't be able to control the interval to exactly 15 minutes but you will find that this mechanism is the closest Apple will allow.
It is not possible to perform network calls at clearly specified intervals when your app is in background mode. You can tell your app to use background fetches
This article gives a great overview on the capabilities that you can do with this API. Basically it allows you to tell iOS that your app wants to perform networking calls in the background, however you can't exactly control when and how often iOS the network calls are going to be performed. iOS will schedule your network calls for you, and depending on how your app is used it will adopt the frequency with which it performs the requests. Documentation can be found here.

performFetchWithCompletionHandler never gets fired

1) My plist configuration to provide backgroundmode:
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
</array>
2) In didFinishLaunchingWithOptions I have:
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:1.0];
3) I declared the protocol UIApplicationDelegate in the delegate.
4) I implemented the following method, but it never gets fired. (It only works if I simulate the fetch with "XCode->Debug->Simulate Background Fetch".)
-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
Why? Is this a DP5 beta error? Should I radar this?
Running your app in the iOS Simulator, in Xcode Debug mode, you can force a background fetch from the Xcode menu:
Debug > Simulate Background Fetch
May work for a tethered device, I haven't tried it recently.
I'm afraid this is hard to debug on a device because you're not guaranteed it is called in the amount of time you specify.
setMinimumBackgroundFetchInterval means that it is not called in an interval which is smaller than the value you specified. But there's no setMaximumBackgroundFetchInterval.
So if iOS decides to call your app just once a day or even just once a week than it won't be called more often regardless your minimumBackgroundFetchInterval. AFAIK iOS decides when to call performFetchWithCompletionHandler measured by the pattern when and how often the users start the app.
There are many considerations:
Make sure the background fetch capability was set in the plist.
Make sure the background fetch capability hasn't been disabled for this particular app, or in general, in the device's Settings app.
Make sure to set the minimum fetch interval.
Make sure you gracefully leave the app (e.g. just hit the home button and fire up another app and/or just lock the device). But if you kill the app (by “force quitting” by double tapping on the home button and swiping up or, for those devices without home button, swiping up from the bottom to pull up the task manager and then swiping up on the app in question) that will prevent the OS from offering your app a chance to fire off subsequent background fetch requests (at least until the user runs the app again).
Make sure you are testing this on physical device and not running the app via the Xcode debugger. Being attached to the debugger changes the behavior of background operations.
Make sure the app is actually doing some network requests. If you have app that performs no network requests at all, it won't participate in background fetch. If you do, for example, a little test app with "background fetch" and don't issue any network requests, you won't participate in background fetch.
Likewise, if the OS starts up your app in background mode so it can perform a background fetch, if you don't actually perform a network request, the OS may stop offering your app the ability to perform background fetches in the future.
Make sure to call the completion handler, and do so within the allotted time, or your app may not participate in background fetch in the future.
The timing of when the OS performs background fetch is dictated by poorly documented rules that may change in the future. But the relevant factors include:
Whether the device is connected to power and/or is sufficiently charged;
Whether connected to WiFi or not;
How often the user actually fires up the app;
Whether the device is doing other network related tasks (e.g. whether background fetch can be coalesced with other network operations);
How frequently past background fetch requests resulted in there being data available.
In my experience, after the app is run the first time, if connected to wifi and power, if you wake the device about 5 minutes later, the app will perform background fetch. This isn't a hard and fast rule, but just what we've experienced in the past.
But many new developers post on Stack Overflow with questions like “how can I have app request data ever x minutes (or hours)”, “how can I request data every day at 2 am time”, etc. The short answer is that you can't. The OS decides the timing of background at its own discretion. You cannot control this (other than the minimum request interval; but you cannot control the maximum interval, as the OS controls that).
This may seem obvious to many, but make sure you've got a reliable way of knowing whether background fetch process is running correctly or not. User Notifications framework can be used to present some alert so you know if the background request resulted in something. Alternatively, os_log or Logger “Unified Logging” (see WWDC 2016 Unified Logging and Activity Tracing or 2020’s Explore logging in Swift) can be used to post messages on device that can be monitored on macOS Console app. But more than once, I've seen users do something like waiting for message to show up in Xcode or waiting for UIAlertController. You need some mechanism that works when not connected to Xcode and when the app never enters foreground.
Using your device you can fire application:performFetchWithCompletionHandler with the following steps:
Put your app in the Background state
Lock your device and wait 5 minutes.
Unlock your device, this will fire the method
(It only works if I simulate the fetch with "Xcode->Debug->Simulate
Background Fetch".)
It's because you're in Debug mode. Please try launch app without Xcode.
Another thing to check is your plist file. Make sure the UIApplicationExitsOnSuspend key is not present.
Many people here on Stack Overflow have recommended using that setting as a way to force your app to start fresh each time it's launched. That does work, but the side effect is that it prevents the new iOS 7 background fetch feature from being triggered.
If application: performFetchWithCompletionHandler: never gets fired (unless you simulate it using Xcode), check also if "Background App Refresh" preference is "On" for your app. (Settings app -> General -> Background App Refresh)
Also, background fetch is disabled if the iPhone is in Low Power Mode.
Apple provides an algorithm which defines how often the background fetch should trigger, based on your own usage of the app. If you use it a lot, then it will fetch as often as possible, but if you use like at 4pm every day, the background fetch should trigger just before, so your data is updated when you launch it.

Resources