MagicalRecord never gives success in completion block - core-data

Magical Record 2.2:
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
NSArray *cats = [Categorization MR_importFromArray:response.result];
}completion:^(BOOL success, NSError *error) {
//Success is always NO?!
}];
However it does save my records. But they only appear when I restart my app.
I have even tried a loop with MR_importFromObject. Still saves but still no Success is true.

Related

sendAsynchronousRequest:queue:completionHandler: fails while app is in background

I am using internet availability check using NSURLConnection but it fails to call success or error block:
- (void)isNetworkAvailableWithCallBack:(SuccessCallback)successBlock onFailure:(FailureCallback)failureBlock {
NSURL *URL = [NSURL URLWithString:#"http://www.google.com/"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue new] completionHandler:^(NSURLResponse *response, NSData __unused *data, NSError *error){
if (response != nil){
NSLog(#"Connected");
dispatch_async(dispatch_get_main_queue(), ^{
successBlock(YES);
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
failureBlock(YES);
});
NSLog(#"Not Connected");
[self presentError:error];
}
}];
}
App works great when app is in foreground or loading first time. Off course my background multitasking is enabled. The issue starts when the following occurs:
Send the app to BG.
Wait some time...
The app get killed by the iOS.
When my app comes again from background to foreground, block gets called with following status code:
Code=-1001
Its a request time out error. but why it is not called whenever my app goes to background(happens not every time, something it works fine).
Is there any thing wrong in my code? And how i handle this.?
You need to enable "Project Background Mode" in Capabilities.
Please refer attached screenshot

GPUImageWriter intermittent crash

I am using the GPUImage framework to record videos. However, while recording, I like to be able to stop recording, start recording, and repeat. My code is as follow:
-(void) startRecording {
NSLog(#"begin recording ");
dispatch_async(recordingQ, ^{
#autoreleasepool {
_assetURL = [self mediaURLAsVideo:YES];
_movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:[self mediaURLAsVideo:YES] size:CGSizeMake(640, 480)];
[_overlay addTarget:_movieWriter];
[_movieWriter startRecording];
}
});
}
-(void) stopRecording {
NSLog(#"stop recording");
dispatch_sync(recordingQ, ^{
[_overlay removeTarget:_movieWriter];
[_movieWriter finishRecording];
});
}
Occasionally, I see this crash:
*** Assertion failure in -[GPUImageMovieWriter createDataFBO], /Users/.../Pods/GPUImage/framework/Source/iOS/GPUImageMovieWriter.m:548
I am not sure why this is the case but any help would be appreciated.
There's a second issue to this as well. Occasionally, the console logs
Couldn't write a frame
Couldn't write a frame
Couldn't write a frame
Couldn't write a frame

Opening a match with a stranger to hold a video chat

Hullo,
I would like to establish a voice chat between a user and a taxi driver and I selected GameKit as a solution, yet it seems the two users need to be first friends and that is qyuite a nuisance I think I may somewhat solve.
Yet when I open the voice chat with:
-(void)initializeVoiceChat:(GKMatch*) matchTaxi{
NSError* error=nil;
AVAudioSession* audioSession=[AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
[audioSession setActive:YES error:&error];
if (error){
NSLog(#"AN error occurred while starting audio session: %#", [error localizedDescription]);
}
GKVoiceChat *talkTaxi = [matchTaxi voiceChatWithName:#"redTeam"];
talkTaxi.active=YES;
talkTaxi.playerStateUpdateHandler=^(NSString* playerId, GKVoiceChatPlayerState state){
switch (state) {
case GKVoiceChatPlayerSpeaking:
[self showSpeakingPlayer: playerId];
break;
case GKVoiceChatPlayerSilent:
[self stopShowSpeakingPlayer: playerId];
default:
break;
}
};
[talkTaxi start];
}
The block in playerStateUpdateHandler seems to never be called.

core data - cannot find data for a temporary oid in mergeChangesFromContextDidSaveNotification

Occasionally I'm getting temporary oid failures while merging contexts in my app. Here is the code. I can't reproduce this bug while testing, it only seems to happen out in the wild.
- (void)didSave:(NSNotification *)note
{
if (((NSManagedObjectContext *)note.object).persistentStoreCoordinator != [self managedObjectContext].persistentStoreCoordinator)
return;
dispatch_async(dispatch_get_main_queue(), ^{
// fails on the next line
[[self managedObjectContext] mergeChangesFromContextDidSaveNotification:note];
...
});
}
randomly gives me this:
cannot find data for a temporary oid: 0x1464d6b0 <\x-coredata://52C9DDE6-A4F8-4BD7-B9B8-7D59F3876D74/ContactSet/tA3AF19CB-90CD-4610-A15E-33A2821B1AF1220>
Should I be checking the notification type?
(note the concurrency type is set to main thread)

Core Data background fetching via new NSPrivateQueueConcurrencyType

Is it really so simple now in iOS5?
I used to perform a background fetch using this code in my AppDelegate:
dispatch_queue_t downloadQueue = dispatch_queue_create("DownloadQueue", NULL);
dispatch_async(downloadQueue, ^{
self.myDownloadClass = [[MyDownloadClass alloc]initInManagedObjectContext:self.managedObjectContext];
[self.myDownloadClass download];
});
dispatch_release(downloadQueue);
My download class performs an NSURLConnection to fetch some XML data, uses NSXMLParser to parse the data, and then updates a complex schema in core data. I would always switch to the main thread to actually update the core data. Messy code, with lots of calls to dispatch_sync(dispatch_get_main_queue()....
My new code looks like this:
NSManagedObjectContext *child = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[child setParentContext:self.managedObjectContext];
[child performBlock:^{
self.myDownloadClass = [[MyDownloadClass alloc]initInManagedObjectContext:child];
[self.myDownloadClass download];
}];
along with a small change to some other code in my AppDelegate to set the parent model object context type to NSMainQueueConcurrencyType:
- (NSManagedObjectContext *)managedObjectContext
{
if (__managedObjectContext != nil)
{
return __managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil)
{
__managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[__managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return __managedObjectContext;
}
It seems to work very well. The entire update process still runs in a separate thread, but I did not have to create a thread. Seems like magic.
Just remember if you want to commit your changes to the physical core data files, you have call save: on the parent context as well.
I didn't really ask a question here. I'm posting this so it helps others because everything I found when searching for the new iOS5 managed object context methods only gave high level details with no code examples And all the other searches for fetching core data in the background are old, sometimes very old, and discuss how to do it pre-iOS5.
Yes - it is really that easy now (in iOS 5.0). For iOS 4 compatibility, the previous hurdles remain, but the documentation is not too bad on thread confinement. Maybe you should add this to a wiki section?
I'm trying to understand how this new API is implemented. My usual pattern for multithreaded core data is something like this:
Usually in a NSOperation but simplified using dispatch_async in this example:
dispatch_queue_t coredata_queue; // some static queue
dispatch_async(coredata_queue, ^() {
// get a new context for this thread, based on common persistent coordinator
NSManagedObjectContext *context = [[MyModelSingleton model] threadedContext];
// do something expensive
NSError *error = nil;
BOOL success = [context save:&error];
if (!success) {
// the usual.
}
// callback on mainthread using dispatch_get_main_queue();
});
Then the main thread will respond by updating the UI based on NSManagedObjectContextDidSaveNotification to merge the main context.
The new API's seem to be a wrapper around this pattern, where the child context looks like it just takes the persistent coordinator from its parent to create a new context. And specifying NSPrivateQueueConcurrencyType on init will make sure the performBlock parameter is executed on the private queue.
The new API doesn't seem to be much less code to type. Any advantages over the 'traditional' threading?

Resources