0

I am trying to clean up when the app is about to terminate/enter the background.

But, when the following code is called,

- (void)applicationWillTerminate:(UIApplication *)application
{
    NSURL* url = [NSURL URLWithString:@"http://www.mysite.com/mobile/home?sysmethod=proclogout&systype=mobile&pagetype=jquerymobile"];
    [self.webView loadRequest:[[NSURLRequest alloc] initWithURL:logoutURL]];
}

... the request starts loading, but never finishes. I read in Apple docs that apps have ~ 5 seconds to finish what they're doing once applicationWillTerminate: is called.

I don't believe the process is taking anywhere near that long, since I load this same request elsewhere in the app, and it always happens in mere milliseconds.

I have tried this both synchronously and asynchronously, with no luck either way.

Thanks for any thoughts!

Hap
  • 556
  • 1
  • 6
  • 20
  • It's unlikely that `applicationWillTerminate:` is even called. Have you verified it is called? And your app is being killed. What's the point of updating a web view at that time? The next time the user loads your app it will be started fresh. – rmaddy Dec 20 '13 at 21:22
  • applicationWillTerminate will only be called if your app goes background (the only option by pressing Home button of the device) and "Application does not run in background" key is set in your app's info.plist file to "YES". Otherwise it won't ever be called. Are you using something similar? – Ayan Sengupta Dec 20 '13 at 21:22
  • @AyanSengupta There are cases where `applicationWillTerminate` will be called from the background - at least with iOS 7. I'm not sure when exactly but I thought the same thing until iOS 7 came out and my own app started having that delegate method called under certain unknown conditions. – rmaddy Dec 20 '13 at 21:26
  • @rmaddy It is not always called. But, when it is, I have an open session (server side) that does not get deleted. My loadRequest is an attempt to manually kill that session. Also note, I went through the same steps in applicationDidEnterBackground, with the same result. – Hap Dec 20 '13 at 21:28
  • @AyanSengupta please see my reply to rmaddy. – Hap Dec 20 '13 at 21:32
  • Try using `applicationDidEnterBackground` but wrap the request in calls `beginBackgroundTaskWithExpirationHandler` and `endBackgroundTask`. – rmaddy Dec 20 '13 at 21:34
  • @rmaddy its really a new thing to know....can you search out the specific condition when you've got your delegate method fired in ios7. I could never make that work on my own :( – Ayan Sengupta Dec 20 '13 at 21:37
  • @AyanSengupta applicationWillTerminate: fired for me when I double-tapped Home and then swiped the app (now in the background) up off of the screen. – Hap Dec 20 '13 at 21:47
  • 1
    @Hap Yes thats an usual way to terminate an app. But `applicationWillTerminate` will only be called if your app has not yet been transitioned into "Suspended" state. – Ayan Sengupta Dec 20 '13 at 21:50

1 Answers1

3

Request loading in a UIWebView is asynchronous. That explains why the request begins to load but never finishes. If you want to make sure that a certain URL is called or loaded, you will have to somehow keep the applicationWillTerminate: method from exiting. If you don't need to really load the request in a web view, you could do use [NSURLConnection sendSynchronousRequest:returningResponse:error:] instead.

Also, a kind of hacky way to do it might be this:

[_webview stringByEvaluatingJavaScriptFromString:@"window.location.href=\"http://example.com/logout\""];

stringByEvaluatingJavaScriptFromString: is a blocking, synchronous method. I haven't tried, however, if it would really only return once the request is fully loaded. It might already return just after setting the location.

Johannes Fahrenkrug
  • 42,912
  • 19
  • 126
  • 165
  • 1
    Thanks. That was the root of the problem. I was loading all of my requests (throughout the app) using dispatch_async. Which, I see now was redundant. But, for the above case, I removed the dispatching in applicationWillTerminate: thinking I was making a synchronous call. [NSURLConnection sendSynchronousRequest:returningResponse:error:] does work because all I really wanted to do was request that the server kill my session (I didn't need to load the request). – Hap Dec 20 '13 at 21:45