Using +[MagicalRecord saveWithBlock:completion:], the completion is not called - ios

When I call saveWithBlock:completion: it actually saves the data but doesn't call the completion Block. Is there a bug, or am I using this method the wrong way?
I use MagicalRecord 2.2 from CocoaPods. I've tried to downgrade to 2.1 with no luck -- the problem remains.
[MagicalRecord setupCoreDataStackWithInMemoryStore];
[MagicalRecord setDefaultModelNamed:#"Model.momd"];
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
TestUser *test = [TestUser MR_createInContext:localContext];
test.name = #"Lweek";
} completion:^(BOOL success, NSError *error) {
NSLog(#"Yeah");
}];
This outputs nothing. The completion Block is not triggered, although the data are saved properly.

Related

MagicalRecord saveWithBlock - how to cancel operation

I'm using MagicalRecord with its saveWithBlock: method:
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
// some work
// ...
// -> ups! I changed my mind, I don't want to save!
}];
If I'd like to cancel the saving operation inside that block, how can I achieve that?
E.g. I have a long running download/sync operation when the user logs in - if the user logs out during this operation I'd like to cancel the saving inside the saveWithBlock:
If you want to perform cancellation then don't wrap your changes into a MagicalRecord saveWithBlock. You could simply use the Context's performBlock API and discard the changes if you are not happy.
[context performBlock:^{
// some work
// ...
if(timeToCancel) {
[context reset];
} else {
[context MR_saveToPersistentStoreWithCompletion:nil];
}
}];

Equivalent "completion handler" from MagicalRecord to Realm.io

I searched for a many days, but I can not find it. What would be the equivalent of the following MagicalRecord statement in Realm.io?
[MagicalRecord saveUsingCurrentThreadContextWithBlock:^(NSManagedObjectContext *localContext) {
// Save block
} completion:^(BOOL success, NSError *error) {
// Completion block
}];
I need "Save block", and when it finish, execute "Completion block"
Thanks!!
the equivalent in Realm is -[RLMRealm transactionWithBlock:].
Since both your MagicalRecord example and Realm's equivalent run in the current thread, the completion block is a bit redundant because it's equivalent to adding code immediately after the call to this method.

MagicalRecord saveWithBlock completion usage

I'm using the [MagicalRecord saveWithBlock: completion:] method but I'm not sure how to access the saved object on the completion block. My code is the following
NSLog(#"saving player");
__block PSPlayer *player;
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
// parse json
player = [self parsePlayer:playerInfoJson inContext:localContext];
NSLog(#"player.md5Id %#", player.md5Id);
} completion:^(BOOL success, NSError *error) {
NSLog(#"player.md5Id in success %# error %#", player.md5Id, error);
...
}];
The player.md5Id is correctly set at the end of the save block but is nil in the completion one. Is this a correct usage?
cheers,
Jan
The completion block captures the player reference before it's set so it will be nil when that block gets executed.
If you want to use the new managed object later you should store it in a property and then call a method from the completion block, (possibly switching to the main thread, not sure if MR does that for you) to find that object in the main context.
Alternatively I think you could define the completion block earlier and then pass a copy to the method, then the copy would have access to the updated player reference (I don't do that very often really but IIRC it should work).

Doesn't MagicalRecord work in background thread?

It seems I tried everything but it seems it works in main thread only. For example:
[SomeClass MR_createEntity];
[[NSManagedObjectContext MR_defaultContext] MR_saveWithOptions:MRSaveSynchronously completion:^(BOOL success, NSError *error) {
if (success) {
NSLog(#"You successfully saved your context.");
} else if (error) {
NSLog(#"Error saving context: %#", error.description);
}
}];
If this code is run in main thread then success == YES otherwise (in background thread) it gives success == NO. In both cases error == nil.
So is it impossible to call the saving in background thread?
Completion blocks are always called from the main thread, here's an example that should work:
Person *person = ...;
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext){
Person *localPerson = [person MR_inContext:localContext];
localPerson.firstName = #"John";
localPerson.lastName = #"Appleseed";
} completion:^(BOOL success, NSError *error) {
self.everyoneInTheDepartment = [Person findAll];
}];
Reference: https://github.com/magicalpanda/MagicalRecord/blob/master/Docs/Working-with-Managed-Object-Contexts.md
Finally I hadn't to create a workable project with fully background MagicalRecord work.
The best solution for me is to update database in the main thread only and to read the database in any thread (including background). Additionally I show custom progress view on database updating.

MagicalRecords importFromArray return empty array

I am using the code below for create my Team NSManagedObjects. But when I print my array object the Xcode console says me the array is empty.
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext)
{
NSArray *array = [Team MR_importFromArray:objects inContext:localContext];
}
completion:^(BOOL success, NSError *error)
{
}];
The completion block invokes but I don't understand why? The objects were not created. Any suggestions or workarounds?
The Magical records seems create the records, but with some delay.
MagicalRecord 2.2 has a bug that isn't saving imports. Use version 2.0.8. It has saveWithBlock
Add logging of the error in your completion handler to get more information about the issue:
NSLog(#"Error: %#", [error localizedDescription]);
Also, have a look into this thread on GitHub:
https://github.com/magicalpanda/MagicalRecord/issues/656

Resources