Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

iOS 5 crash with "Database appears corrupt" while fetching in saveDataInBackgroundWithBlock #111

Closed
appsperhaps opened this Issue · 16 comments
@appsperhaps

Great framework, loved it so much after a recent project, that I'm now refactoring my production app to use it. Deleting lots of boilerplate code as I go.

However, I come across an issue running MR in iOS 5:

  • App launches, and seeds about 20 entities on the default context (main thread) then saves.
  • The app then downloads some data via ASIHTTPRequest, then in its download completion block I run MRCoreDataAction saveDataInBackgroundWithBlock that attempts to save those data. Within this block, it fetches (on the localContext) one of the seeded entity to be associated with new entities. This executeFetch will crash with the message:

Core Data: annotation: -executeRequest: encountered exception = The database appears corrupt. (invalid primary key) with userInfo...

The way I got around it at the moment is to increase the kCFCoreFoundationVersionNumber_iPhoneOS_5_0 (in CoreData+MagicalRecord.h) to something really large so that THREAD_ISOLATION_MODE is used instead of PRIVATE_QUEUES_ENABLED.

Is this a known issue in the framework? Has anyone comes across this issue, or have other ideas?

Thanks!
Jeff

@magicalpanda
@appsperhaps

Hi Saul, thanks for the quick response. What are the benefits of the new model vs thread isolation - I guess I'll look it up :)
Shouldn't the local thread context be associated with a single application-wide coordinator anyway?

I'll look into creating a test for this.

Oh and yes, I'm slowly refactoring the code, the existing ASIHTTPRequest has been serving me well with no issues. MR was too good to pass up, had to use it :)

Jeff

@appsperhaps

This is weird. I managed to get it to work using the intended iOS 5 private queues. And only if I set my finder in the saveDataInBackgroundWithBlock to use the MR_findFirstWithPredicate:inContext method as opposed to MR_findFirstByAttribute:withValue:inContext. So basically I've made an NSPredicate with a single comparison.

The underlying code looked very similar except for the line setPropertiesToFetch. I suppose it has something to do with faulting in relationship properties, but then again shouldn't it fault anyway for those properties that are not specified in setPropertiesToFetch?

@duanefields

Seeing this too... it's something introduced in the last week or so.

@magicalpanda
@duanefields

Why does it even call setPropertiesToFetch, according to the docs:

http://developer.apple.com/library/ios/documentation/Cocoa/Reference/CoreDataFramework/Classes/NSFetchRequest_Class/NSFetchRequest.html#//apple_ref/occ/instm/NSFetchRequest/setPropertiesToFetch:

This value is only used if resultType is set to NSDictionaryResultType.

@XMLSDK

I also do this: #define kCFCoreFoundationVersionNumber_iPhoneOS_5_0 9999.0 to fall back using THREAD_ISOLATION_MODE. And my old merge-changes-back-to-main-thread-code works again. It will take time to rewrite and test projects with block.

BTW, ASIHTTPRequest is obviously having issues in iOS 5. I had a case that in iOS 5 the code had executed one HTTP POST request, shown once in NSLog, but the actual result was two HTTP POST sent. I found this by monitoring traffic by Wireshark. I replace ASIHTTPRequest with AFNetworking and the problem is solved.

@duanefields

I do not see the error before this revision

6d94f4a

@magicalpanda

Ok, so I finally encountered this problem in my own code. As @appsperhaps hinted, the findFirstWithPredicate: method was working, while the findFirstByAttribute: method was not. It seems that in iOS5, setting the propertiesToFetch on a request kills the request (or sets something else under the covers). So, for me, removing the setPropertiesToFetch call fixes the problem. I'll be on the lookout for more, similar issues as I'm migrating to iOS5 Core Data ...

@kostiakoval

I had similar issue. I created very simple project. I figure out that this line of code was the reason of exception -
NSFetchRequest *fetchRequest = [Word MR_requestAllSortedBy:@"index" ascending:NO];
// [fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:@"index", @"name", nil]];
I solved it just by commented it.

@ajesler

I just encountered the same issue. Solved by switching my findFirstByAttribute calls to findFirstWithPredicate methods.

Error shown was "Core Data: annotation: -executeRequest: encountered exception: The database appears to be corrupt. (invalid primary key) with userInfo".

@maystroh

I'm encountered this issue :
CoreData: error: (522) I/O error for database at /Users/admin/Library/Application Support/iPhone Simulator/6.0/Applications/F8038670-847A-4B55-B94A-B8F2325817B5/Library/Application Support/app/app.sqlite. SQLite error code:522, 'not an error'
2013-04-21 22:31:28.126 SubwayDA[498:1cd03] Core Data: annotation: -executeRequest: encountered exception = I/O error for database at /Users/admin/Library/Application Support/iPhone Simulator/6.0/Applications/F8038670-847A-4B55-B94A-B8F2325817B5/Library/Application Support/app/app.sqlite. SQLite error code:522, 'not an error' with userInfo = {
NSFilePath = "/Users/admin/Library/Application Support/iPhone Simulator/6.0/Applications/F8038670-847A-4B55-B94A-B8F2325817B5/Library/Application Support/app/app.sqlite";
NSSQLiteErrorDomain = 522;
}

is it the same issue you talk about? so replacing the findFirstByAttribute bu findFirstWithPredicate will fix it ?

@danilNil

I got this issue when try to use NSExpression:

    NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"ChatMessage"];

    NSExpression *date = [NSExpression expressionForKeyPath:@"sentDate"];
    NSExpression *maxDate = [NSExpression expressionForFunction:@"max:"
                                                      arguments:[NSArray arrayWithObject:date]];
    NSExpressionDescription *d = [[NSExpressionDescription alloc] init];
    [d setName:@"maxDate"];
    [d setExpression:maxDate];
    [d setExpressionResultType:NSDateAttributeType];

    [request setPropertiesToFetch:[NSArray arrayWithObject:d]];

    NSError *error = nil;
    NSArray *objects = [[NSManagedObjectContext MR_contextForCurrentThread] executeFetchRequest:request error:&error];

Here is error:

Core Data: annotation: -executeRequest: encountered exception = The database appears corrupt. (invalid primary key) with userInfo = {
NSFilePath = "/Users/danil/Library/Application Support/iPhone Simulator/6.1/Applications/4E628768-973A-41FF-AA8B-8FD20593A78C/Library/Application Support/ProfileCode/test@a1.com";
}

@donholly

I filed a Radar Ticket (16008160) for Apple about this.

I had this same issue with our Core Data stack (not using Magical Record). If you have a parent/child context setup and you try to use propertiesToFetch on non-NSDictionaryResultType fetches, the "Database appears corrupt" message appears and causes all sorts of bad things to happen. Just make sure not to specify specific fields for Core Data to fetch when using NSManagedObjects :)

@casademora
Owner
@tonyarnold
Owner

As this is a bug in the OS, rather than MagicalRecord I'm closing this issue. It'll still show up in searches for people who also experience this problem. Thank you all for your input and the information you've shared here!

@tonyarnold tonyarnold closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.