Sending Data to Other Players - Game Center - ios4

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

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

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.

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