Method <NSURLSessionDelegate> is not called, when no internet connection - ios

I am using NSURLSessionDownloadTask and NSURLSession.
Question:
When I started downloading and after a while Internet is turned off, which method from or must be called ?
P.S.
At the moment, does not call the method.
I want get call in delegate’s method with error and display on screen some message -#“You lost internet connection”.

Be careful !
If you test on a simulator and disable wifi on a mac, the method will not be called.
Test only on a real device

Use
- (void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
from NSURLSessionTaskDelegate.
And it's true - this method is called when Internet connection disappear only on the real device. On simulator task is paused and resume when Internet connection get back.

Related

Quick Reply: NSURLSessionDataTask from "userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:"

I have Remote Notifications set up successfully for my Messaging App and want to incorporate the "Quick Reply"-functionality of iOS, better known as UNTextInputNotificationAction of UNUserNotificationCenter now.
I added the Text Input Action to my incoming message notifications and it is working as expected.
My Problem lies in the UNUserNotificationCenterDelegate function userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:.
No matter how I set up the NSURLSessionDataTask to POST the input response userText of UNTextInputNotificationResponse, the Request always times out. It does work fine when I am "Quick replying" to a notification received while the app is in the Foreground.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
if ([response isKindOfClass:UNTextInputNotificationResponse.class]) {
if ([response.actionIdentifier isEqualToString:#"REPLY_MESSAGE"]) {
[ApiManager chatWithId:#"123456789abcdefg" postTextMessage:[(UNTextInputNotificationResponse *)response userText] completion:^(Message *message) {
if (!message) {
NSLog(#"Sending failed");
}
completionHandler();
}];
}
}
}
The Data Task within ApiManager is built atop a [NSURLSession sharedSession] - Note that this did not work, even after changing it to backgroundSessionConfigurationWithIdentifier: and implementing the needed Delegate methods.
The Log "Sending failed" can be seen through the Console, if I check the error of the DataTask, it shows a "Timeout" error.
I suspect I have something wrong with my background networking, but I cannot wrap my head around it, and nowhere I looked was an answer to be found. The documentation is very sparse here too.
For anyone stumbling about this issue in the future: I was able to solve it by adding content-available:1 to my push notification payload. I am still using a data task and a shared url session here. No delegate either, working with completion blocks, for anyone interested.
I initially did not think this would work, adding the content available flag actually had another reason, so it’s nice that this solves the initial problem I had. Why did I think this wouldn’t work? Easy, because the content available, if we believe the documentation, indicates to the app, that there is content available to download. There is a special application delegate method being called for specifically this situation:
application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
It is a nice side effect that the method which responds to user actions on notifications also gets more time to process.
Neat bonus: I also found out that, without adding the content-available flag, the quick reply would work from the Apple Watch, as, I guess, the OS allows the app to perform longer background operations when responding to a request from the Apple Watch.

Get cause of Multipeerconnectivity connection error

I am using the MultipeerConeectivity framework to transmit data between two iOS devices. Sometimes the connection is not getting established even after the receiver accepts the invitation.
i.e - (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state is called with state as MCSessionStateNotConnected for sender.
Is there any workaround to get the reason of the connection failure, like dangling wifi, not in range, etc? Any help is greatly appreciated.

How to continue in the background a connection started with NSURLConnection in the foreground?

I tried the answer of this question
How can a connection started with NSURLConnection while in the foreground be continued in the background?
And works like a charm! but only if device is connected to my iMac...
Once I disconnect my iOS device the app runs for 3 minutes more in background and then the app starts again, this not happens if the iOS device is connected.
Why is happening this? Is there any way to continue the upload in the background until the 10 minutes like it must be?
I'm not implementing this code
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
// Handle the error
...
//this line
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskID];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// Save the downloaded data
...
//and this line
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskID];
}
NSURLConnection wasn't intended to be used when your app isn't running. Use an upload task in an NSURLSession background session, and it will work as you would expect.

Monitoring NSURLSession after app restart

I have a prototype single-view app which monitors download tasks.
I'm trying to deal with following use case:
Downloads are initiated via NSURLSession while app is in foreground. NSURLSession is created with background configuration.
I kill the app with "Xcode Stop", so that app continues download in background. While app is alive, I orderly receive progress callbacks from NSURLSession.
I manually start the app (not by Xcode, but tapping the launch icon), when the downloads have not been completed yet.
I don't receive any URLSession delegate calls for tasks started in previous app's life. The only thing that gets called is handleEventsForBackgroundURLSession but that's called on AppDelegate by the OS (different case than NSURLSession delegate calls).
I want to show progress of ongoing download tasks. Can this be done after app relaunch (when app was terminated by the system, not manually!)?
After app relaunch, NSURLSession is initialized with same identifier, new delegate object, so I figured delegate will continue to receive calls for session's tasks (because session identifier is the same), but apparentely that's not the case.
There is a note in Apple's documentation:
The session object keeps a strong reference to the delegate until your app explicitly invalidates the session. If you do not invalidate the session, your app leaks memory.
but I guess this only applies to case when app is alive. When the app is terminated, then all app's objects are gone.
Make sure NSURLSession is properly initialised when app launches. That's what the problem was in my case. I had TransferManager which initialised session as lazy getter which was not getting invoked...
Now that the NSURLSession is properly initialised, callbacks are fired regularly.
Stupid error, but there it is.
You goal seems to be in number 4, trying to receive URLSession delegate callbacks while in the background. I've been struggling with that myself and wasn't able to find a great solution, however I did realize that whenever I performed any actions (even simply calling the completionHandler() callback) in handleEventsForBackgroundURLSession: I received a call to
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error {
Seems like performing operations might wake up the delegate that was specified when creating your NSURLSession.
That is the correct method to perform any UI updates (such as showing progress) since that's the only location you'll know the background task is complete. Just make sure to call the completion handler callback after you are done!
Also this may be of some help to you: My NSURLSessionDelegate methods are not getting called during a background download

iOS NSURLSessionDelegate [URLSession: task: didCompleteWithError:] returns with error if app is suspended

I'm writing an app that requires background downloading. I've configured my NSURLSession to be in the background Session Configuration.
Everything is working when the app is in foreground or even in background mode (home button), but as soon as I press the power button to force the phone into sleep mode. The
NSURLSession delegate call:
- (void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
returns with a Error Domain=NSPOSIXErrorDomain Code=1 "The operation couldn’t be completed. Operation not permitted" and my download fails.
You have forgotten the bg-download entitlements (see target -> capabilities)

Resources