UIManagedDocument: Error/crash on creating new files when network is down (saving)
Asked Answered
C

1

3

When I try to save a newly created UIManagedDocument to iCloud and the network is down (e.g. airplane mode) I get the following error(s) with a crash (hexcodes and unreadable stuff removed):

-[PFUbiquitySafeSaveFile waitForFileToUpload:](272): CoreData: Ubiquity:  <PFUbiquityPeerReceipt: ...>(0)
permanentLocation: <PFUbiquityLocation: ...>: /private/var/mobile/Library/Mobile Documents/XXXXXXXXXX~com~domain~AppName/TransactionLog/mobile.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/DocumentName/XXXXXXXXXXXXXXX/receipt.0.cdt
safeLocation: <PFUbiquityLocation: ...>: /private/var/mobile/Library/Mobile Documents/XXXXXXXXXX~com~domain~AppName/TransactionLog/mobile.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/DocumentName/XXXXXXXXXXXXXXX/mobile.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.0.cdt
currentLocation: <PFUbiquityLocation: ...>: /private/var/mobile/Library/Mobile Documents/XXXXXXXXXX~com~domain~AppName/TransactionLog/mobile.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/DocumentName/XXXXXXXXXXXXXXX/mobile.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.0.cdt

kv: (null)

Safe save failed for file, error: Error Domain=NSCocoaErrorDomain Code=512 "The file upload timed out." UserInfo=... {NSLocalizedDescription=The file upload timed out.}


*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This NSPersistentStoreCoordinator has no persistent stores.  It cannot perform a save operation.'
*** First throw call stack:
(...)
libc++abi.dylib: terminate called throwing an exception

I don't know this error but it says that document couldn't be saved because no upload is possible (of course, because there is no network). But I can't understand why I can't catch this error with the save completion handler:

[theDocumentToSave saveToURL:theDocumentToSave.fileURL
            forSaveOperation:UIDocumentSaveForCreating
           completionHandler:^(BOOL success) {
                 if (success) {
                     // Do somethings, go on, ...
                 } else {
                     // Catch error HERE, but this is never called!
                 }
}];
Cori answered 1/3, 2013 at 17:2 Comment(1)
The Error occured on a iPhone 4 device running the current iOS 6.1.2Cori
E
3

This unfortunately represents an internal bug in Core Data's iCloud integration. The UIManagedDocument is still trying to get its data store added, or else has just failed to do so, because there's no network connection. That's not how it's supposed to work, but it's common to have failures or long delays getting iCloud up and running with Core Data. The worst case should be-- as you expect-- that your completion block would be called with success set to NO. Crashing your app in this scenario is not your fault, but that also means you may have a hard time doing anything about it.

You may be able to predict this crash by something like:

NSArray *persistentStores = theDocumentToSave.managedObjectContext.persistentStoreCoordinator.persistentStores;
if ([persistentStores count] == 0) {
    // exception is likely, should be at least 1
} else {
    // exception probably won't happen
}

That's kind of a hack though, and it doesn't help you actually save the document. Plus, there's no guarantee that the document will become save-able at some later time. It could avoid crashes, though.

In general, Core Data plus iCloud is not the most reliable of combinations. I asked about the iOS version because iOS 6.x is, let's say, less bad than iOS 5. Since you're already on 6 though, I can't suggest moving to 6 in the hope of better behavior.

Ear answered 1/3, 2013 at 19:20 Comment(5)
You were right about AppDelegate.m ......apparently if you do it with the UIManagedDocument you don't need it in the AppDelegate.m, only if you set it up auto. with Core Data. Also, check out persistentStoreOptions property under the link : developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/…Keelia
@Tom: Thanks very much! Your code seems to catch the error. I'll take some time for testing on several devices/iOS versions. And yes, it is kind of a hack and that's a shame...Core Data/UIManagedDocument with iCloud seems so buggy...Cori
@Tom: Argh, sorry, next problem: This code prevents the creation of the document in general. It seems like the count of persistentStores is 0 each time on creation (even though airplane mode is off and a network connection exists)...Cori
@FrankZp, sorry to hear that. With UIManagedDocument's internals being undocumented it's hard to know what will work. It might be that the best you can do is check for network reachability (see Apple's Reachability demo app) to improve the odds.Ear
@TomHarrington: Yes, I think this is the only way to certainly catch the error. Will it be enough to check for general internet reachability ([Reachability reachabilityForInternetConnection]) or do you recommend to check additionally for a specific iCloud host (e.g. [Reachability reachabilityWithHostName: @"www.icloud.com"])?Cori

© 2022 - 2024 — McMap. All rights reserved.