Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

applicationShouldTerminate and NSURLConnection

In my Mac OS X application I'm pushing database to Dropbox, kinda syncing. And when user quits application, I want to upload database before exiting. So I implemented applicationShouldTerminate: where I call syncing method and return NSTerminateLater. However, underlying NSURLConnection doesn't work at all - no delegate methods are called, and just nothing happens. All uploading code work well from other places, and even when I return NSTerminateCancel from applicationShouldTerminate: This happens on Mac OS Lion 10.7/XCode 4.6, if this metter.

So, any comments? Does returning NSTerminateLater changes something in run loop, or somewhere else?

like image 948
Nickolay Olshevsky Avatar asked Aug 30 '25 15:08

Nickolay Olshevsky


1 Answers

The documentation states that after returning NSTerminateLater, the application will run the main run loop in the NSModalPanelRunLoopMode mode until you call replyToApplicationShouldTerminate:.

By default NSURLConnection objects are not scheduled for the NSModalPanelRunLoopMode mode (only for NSDefaultRunLoopMode). So the connection is working but the delegate messages are not delivered because the main run loop needs to be in the NSDefaultRunLoopMode mode.

This allows Cocoa to suspend the observation of asynchronous tasks while presenting a modal dialog (NSModalPanelRunLoopMode) or while tracking mouse-dragging events (NSEventTrackingRunLoopMode). Though that behavior may be justified in some case, people tend to agree that modal interfaces are bad juju as they generate intrusion, frustration and mode errors (hence your problem).

So in order for your NSURLConnection to execute correctly, you need to schedule it in the NSDefaultRunLoopMode and NSModalPanelRunLoopMode modes. This can be achieved with NSRunLoopCommonModes which is an alias for all the run loop modes that have been declared as “common” (i.e. all the modes used by Cocoa).

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[connection start];
like image 138
Nicolas Bachschmidt Avatar answered Sep 03 '25 01:09

Nicolas Bachschmidt