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

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

Related

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

locationmanager didenterregion doesn't get called

Supposing my code looks like this:
- (void)locationManager:(CLLocationManager *)manager
didRangeBeacons:(NSArray *)beacons
inRegion:(CLBeaconRegion *)region {
//Handle beacons found during ranging
}
-(void)initBeaconRegion
{
NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDString:#"E2C56DB5-DFFB-48D2-B060-D0F5A71096E0"];
self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:proximityUUID major:345 minor:678 identifier:#"MyBeaconIdentifier"];
self.beaconRegion.notifyEntryStateOnDisplay = NO; //Used for Monitoring
self.beaconRegion.notifyOnEntry = YES; //Used for Monitoring
self.beaconRegion.notifyOnExit = YES; //Used for Monitoring
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
if ([region isKindOfClass:[CLBeaconRegion class]]) {
CLBeaconRegion *beaconRegion = (CLBeaconRegion *)region;
//now start ranging
// [_locationManager startRangingBeaconsInRegion:beaconRegion];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
[self initBeaconRegion];
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
NSLog(#"monitored regions %#",self.locationManager.monitoredRegions);
}
and some iPad app called xBeacon advertising with the same UUID, major and minor, this doesn't work. What am I doing wrong? Should I approach the advertising device with the app, or wait longer?
Tried the same with Estimote beacon app, and both apps work as I check it on Beacon Scanner on my Mac.
You are expecting a beacon monitoring callback to get called, but you aren't starting monitoring -- you are starting ranging. Try changing this line:
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
to:
[self.locationManager startMonitoringRegion:self.beaconRegion];
Also, you need to set self.locationManager.delegate = self as #luca-corti suggests.
If you still don't get the callback, try using my Locate app to verify your test beacon is actually transmitting with the identifiers you expect.
You need to set self.locationManager.delegate = self after instantiating the CLLocationManager. Otherwise delegation won't work.

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.

MagicalRecord never gives success in completion block

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.

Sending Data to Other Players - Game Center

I am developing a simple game center multiplayer game. i did manage almost everything except sending messeage to players. what i mean, i can invite player to play game, game is starts etc.
regarding apple documentation i am using following method to send data but it' doesn't work at all.
const char *bytes = "123";
NSData *packet = [NSData dataWithBytes:&bytes length:3];
[myMatch sendDataToAllPlayers: packet withDataMode: GKMatchSendDataUnreliable error:nil];
if possible a working sample would be great.
many thanks.
I did pretty much same.
NSError *errorTransmit;
const char *bytes = "asd";
NSData *packet = [NSData dataWithBytes:&bytes length:3];
[myMatch sendDataToAllPlayers: packet withDataMode: GKMatchSendDataUnreliable error:&errorTransmit];
if (errorTransmit != nil)
NSLog(#"Error sending data to peers: %#", [errorTransmit localizedDescription]);
}
but when code reach
NSLog(#"Error sending data to peers: %#", [errorTransmit localizedDescription]);
I am getting Program received signal: “EXC_BAD_ACCESS”.
that's why i can't see what is going on.
Must confess I've yet to use the GameCenter bits and pieces, but as a general approach I'd have thought you might want to see if there were any errors being generated. As such, if you use something like...
NSError *transmissionError;
[myMatch sendDataToAllPlayers: packet
withDataMode: GKMatchSendDataUnreliable
error: &transmissionError];
if(transmissionError != nil) {
NSLog(#"Transmission error: %#", transmissionError);
}
...you might get a clue what's going wrong.
Incidentally, I'm currently away from a compiler so apologies for any typos in the above. :-)
I cannot see anything wrong here, I am using this code:
NSData *data = nil;
NSError *error = nil;
int packet = 777;
data = [[NSData alloc] initWithBytes:&packet length:sizeof(int)];
[self.mMatch sendDataToAllPlayers:data withDataMode:GKMatchSendDataReliable: &error];
and it works

Resources