AFNetworking UIAlertView when in background and no network - ios

I am using AFNetworking to update location details to a server in the background (using significant location change).
Everything works fine, except when driving round and it attempts to upload to my server and my phone has no data signal, when I re-launch the application later it has UIAlertViews on the screen saying "The Internet connection appears to be offline."
I have done a search on my project for the string, but it doesn't exist. So where is it coming from?
I would like to stop this being displayed when the app is backgrounded.
Thanks

That error message is passed to [NSURLConnection connection:didFailWithError:] when the Internet is offline. I believe AFNetworking passes this to a failure code block or delegate callback depending on your implementation. You have code somewhere to make a UIAlertView display text from an NSError object but that string isn't in your project so that's why you can't find it.

Related

Box iOS SDK Issue: [BoxAPIMultipartToJSONOperation respondsToSelector:]: message sent to deallocated instance 0x1707a32c0

I get this error from the box sdk when I try to upload a file. It never occurs on the first upload. Always on the second upload. (I upload 25 files, I upload 25 again and this memory error pops up)
I tracked the problem down to box code with NSZombies. Basically the NSStream Delegate in the "BoxAPIMultiPartToJSONOperation.m" file is sending a message/calling a method on the object at this address after it gets deallocated.
My guess is that it's this line [self performSelector:#selector(retryWrite:) withObject:theStream afterDelay:0.1];
There was a github issue about this a while ago: https://github.com/box/box-ios-sdk-v2/issues/76
The issue there was that the NSStream delegate was calling a method on something after it was supposed to be cancelled. Was resolved by making sure to shut off the stream once the thing finished.
My latest idea is to try and kill the Box API threads (yeah I'm that desperate.)
If anyone has faced this specific issue I'd love to hear how you resolved it.
Thanks.

NSURLSession background upload completion method called twice after restart

I am using NSURLSession in background mode, to upload images from file using a NSURLSessionUploadTask, and the delegate callbacks. All this works perfectly fine if the app remains on the background as opposed to getting killed by the user.
However if while there are still pending uploads, and the app is killed using the home screen, once the app is restarted and the images that did not upload get requeued as upload tasks with a new NSURLSession with the same background identifier, something really odd happens:
1) The tasks are created only once, and I assign a task description to them when that happens, also NSURLSession assigns them a task identifier which is unique per session. My NSURLSession background is a singleton.
2) The tasks fail almost immediately with this error:
Error Domain=NSURLErrorDomain Code=-999 "The operation couldn’t be completed. (NSURLErrorDomain error -999.)" UserInfo=0x174669880 {NSErrorFailingURLStringKey=myURL, NSURLErrorBackgroundTaskCancelledReasonKey=0
and it calls the completion delegate method:
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
passing the aforementioned error above. At this point I print out the task identifier and the task description which matches the task I created.
3) After all this tasks fail almost immediately, that is when things start to get weird, all those tasks get somehow put again into the NSURLSession without my code doing anything, note that using Charles I can see a single request going out, which in reality never fails. This second time they succeed and they call the didCompleteWithError again this time there is no error. At this point printing the task description and task identifier, surprisingly returns the same task description I assigned, BUT a different task identifier!. Meaning iOS is somehow recreating that task with the same task identifier and queuing it up again, even though it claims it failed. Note that the network request can be seen in Charles only once and it never really fails
This is problem because I cannot distinguish between real upload errors, and this pseudo errors generated by iOS, right now since I am not explicitly canceling any of those requests, I am checking the error code for canceled, and choosing to ignore it, since I know the task will just get magically requeued. This seems like a pretty obvious bug to me, and it can be reproduced all the time.
With the workaround in place everything works as expected, but this is a hack, and I can imagine I might at some point ignore a real canceling and never notify the client that the request in fact failed.
I have only found a couple of people online describing the issue, but no responses.
Is there a radar filed for this?. Is there any way to prevent this from happening?
I am using the 8.1 SDK.

MPRemoteMediaPickerController timed out waiting for fence barrier from com.apple.MusicUIService

MPRemoteMediaPickerController timed out waiting for fence barrier from com.apple.MusicUIService
I get this error on iOS7... only.
I saw another post regarding this error, but no one responded to it.
Cant find any solution on google either
I just started receiving this when I first ran my app on iOS7.1. I'm not even using MPRemoteMediaPickerController (directly). I'm using MPMediaPickerController, but I'm purposefully reusing the object so the user goes back to the same place that they left the next time they choose a song.
In 7.1 I'm getting this warning and the picker displays a useless (can't cancel out) white view.
Solution was to toss the MPMediaPickerController after each use. The error does not seem to happen if I have a fresh one each time.

cancel file uploading with NSURLConnection

I've got NSURLConnection with timeout = 30s which is uploading an image on server.
If connection is horrible and call delegate method didFailWithError: then i need to cancel current connection.
But if i just call the [myConnection cancel] connection will still alive but will not call delegates methods (apple docs say it - NSURLConnection cancel method). And i want to abort connection but not only remove delegate methods. How i can do what?
upd:
My problem is if connection is fails by timeout - in business logic i must recreate connection with similar request. If i have got horrible connection for 1 min and after that connection will be good - server will get a lot of (about 3 times retry count) photos. But first 2 connections is canceled. –
At the moment i make "dirty hack" like "if it's photo uploading request" - do not retry recreate connection.
I do a ton of network stuff and don't recall a scenario where everything was successfully received but the iOS app timed out. I'm trying to grok the scenario you describe, where you're seeing this happen a lot and I'm not seeing how that would happen. We might need to see some of your code.
Regardless, when you cancel a NSURLConnection, it not only stops the delegate methods from being called, but it stops the upload, too. I just did a test:
I attempting to upload a 20mb file (non-chunked request);
At the 1mb mark (as identified by didSendBodyData), I canceled the connection (by calling [connection cancel]);
I immediately stopped receiving any delegate messages at that point;
Looking at Charles, I'm only seeing 1.3mb of data in the hex log of the request. When I look at the "Network" tab of the Mac OS "Activity Monitor" and looking at by "Sent Bytes", it's at 2.1mb uploaded.
So canceling a connection will stop further data from being sent. Perhaps if there is some transmission in progress that still gets out (that's the asynchronous world we live it), but the it's not true to conclude that canceled connections will routinely send their full HTTP request. There must be something about the nature of the timeout that is unique to your environment.
In terms of your immediate problem, I might suggest that when uploading a file that the iOS app assign some unique identifier to the upload so that the server code can immediately recognize duplicate requests and handle them appropriately. But the question is why you are seeing so many time-outs and notably ones where the request appears to be successfully received in toto, but the response is not. That's very curious.
You cannot forcefully abort an ongoing connection.
In case if connection is not yet started cancel and unscheduleFromRunLoop for the NSURLConnection will work.
Try with following step
[myConnection cancel];
myConnection = nil;
Might be helpful in your case and If this step is not working then also try with myConnection.delegate = nil;

Turn based game center displays the state of game incorrect when offline

I am using iOS 6 Game Center API for turn based games.
When the device is disconnected from internet
In the completion handler of the method
[currentMatch endTurnWithNextParticipant:nextParticipant matchData:data completionHandler:^(NSError *error) {
if (error) {
NSLog(#"%#", error);
} else {
//save the new state of the game
}
I get an error. But then, game center standard UI that displays matches list, says "Their turn". when connected again it changes to "Your turn".
The code from famous tutorial at http://www.raywenderlich.com/5509/beginning-turn-based-gaming-with-ios-5-part-2 has the same exact problem.
How I should handle this problem?
If you are using iOS 6 Game Center API then you will have to use
-endTurnWithNextParticipants:turnTimeout:matchData:completionHandler:
because...
–endTurnWithNextParticipant:matchData:completionHandler: Deprecated in iOS 6.0
http://developer.apple.com/library/ios/#documentation/GameKit/Reference/GKTurnBasedMatch_Ref/Reference/Reference.html
The thing is, that when you use GC methods that change status of the match (matchData and synchronization info in this case), data is uploaded to the GC server so that other player(s) get the update. If you're disconnected and ignore the error, your local GKTurnBasedMatch and its matchData change, as well as your synchronization info (which is used to determine if it is your turn to act among other things).
However, since you are diconnected, only your local instance of GCTurnBasedMatch is updated (you get error so that you app is aware of that). When you're reconnected, your app authenticates the user and updates match state (if you're following the tutorial code). Updating match data reverts the sync data (so it's still your turn).
At this point, you should either submit the turn again (provided that you cached gameData that was passed to GC while you were disconnected) and/or call updateMatchData so that your local GKTurnBasedMatch and its matchData get in sync with what's on the server. You should also re-layout your game board with previous turn's data if you didn't re-submit turn after reconnection.

Resources