Game Center authentication always results in sigabrt - ios

This is driving me crazy. Every time I try to authenticate the local player with Game Center I get a thread-1 sigkill. It happens asynchronously after I set the localPlayer's authenticateHandler like so:
- (void)authenticateLocalPlayer
{
if([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0)
{
GKLocalPlayer __weak *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error)
{
if (viewController != nil)
{
[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:viewController animated:YES completion:nil];
}
else if (localPlayer.isAuthenticated)
{
NSLog(#"Player authenticated");
}
else
{
NSLog(#"Player authentication failed");
}
};
}
}
Any ideas?

I've often seen the systemVersion tested with a string comparison instead of a number comparison. Try just printing the value of
[[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0
to verify there's nothing wrong with that expression. I know the following method works:
-(BOOL) os6 {
NSString *targetSystemVersion = #"6.0";
NSString *currentSystemVersion = [[UIDevice currentDevice] systemVersion];
if ([currentSystemVersion compare:targetSystemVersion options:NSNumericSearch] == NSOrderedAscending) {
return NO; //current system version is less than 6.0
} else {
return YES;
}
}

[GKLocalPlayer localPlayer] returns a singleton and __weak releases it at some time (I don't understand when that happens, but at some future time). localPlayer might be getting released, along with the block, before the block finishes executing. There's no need to release a singleton. Try removing __weak.

Try putting __weak before GKLocalPlayer.
It's the only difference I can see between your code and the code I use...

Related

Send Action on rotation of device iOS

here is what I'm trying to achieve, it would be to send an action on rotation of the device...
the point is i'm having a 360 player, I would like the video to start only once the device is on landscape. If it's in portrait i'd like to display a message a saying "rotate your device in landscape to start", and when the user rotate the device, the video play.
below is my code so far:
- (IBAction)test:(id)sender forEvent:(UIEvent *)event {
if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft || [[UIDevice currentDevice] orientation ]== UIDeviceOrientationLandscapeRight)
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"demo1" ofType:#"mp4"];
NSURL *url = [NSURL fileURLWithPath:path];
Video360ViewController *videoController = [[Video360ViewController alloc] initWithNibName:#"HTY360PlayerVC" bundle:nil url:url];
[videoController VRMode:true];
if (![[self presentedViewController] isBeingDismissed]) {
[self presentViewController:videoController animated:YES completion:nil];
}
}
if([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown )
{
NSLog(#"UIDeviceOrientationPortrait");
}
}
The problem of this code is than it trigger only on TouchUp Inside in the Sent Event . . . anyway to have the action starting on rotation ?
Thanks for all your help !
EDIT---
TRYIED THE FOLLOWING ASWELL:
- (IBAction)test:(id)sender forEvent:(UIEvent *)event {
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft || [[UIDevice currentDevice] orientation ]== UIDeviceOrientationLandscapeRight)
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"demo1" ofType:#"mp4"];
NSURL *url = [NSURL fileURLWithPath:path];
Video360ViewController *videoController = [[Video360ViewController alloc] initWithNibName:#"HTY360PlayerVC" bundle:nil url:url];
[videoController VRMode:true];
if (![[self presentedViewController] isBeingDismissed]) {
[self presentViewController:videoController animated:YES completion:nil];
}
}
if([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown )
{
NSLog(#"UIDeviceOrientationPortrait");
}
}
Have you tried
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
Try put your code inside:
- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
}
and write this methods in your UIViewController. This method is called when the device (interface really) is rotated; if you want do something before the rotation of interface, use willRotateFromInterfaceOrientation

Cordova katzer plugin background mode not working on iOS-9

in my ionic/angularjs application I use https://github.com/katzer/cordova-plugin-background-mode/ for backgrounding my application.
It's working quiet well on iOS-8 but with the new iOS-9 its not working any more. I did a few tests and it looks like the app is really working in the background but the user gets no information about it. On iOS-8 I get a message like "YourApp is using your location" or something like that on top of the display. On iOS-9 this message is missing.
Did someone the same experience with this plugin?
I found out that there are some changes in core location functions on iOS9:
allowsBackgroundLocationUpdates in CLLocationManager in iOS9
Like suggested in the post I add a default property allowsBackgroundLocationUpdates with the value YES to the org.apache.cordova.geolocation plugin.
With this fix on CDVLocation.m which is located in /plugins/org.apache.cordova-geolocation/src/ios/ it now works.
To bring it to work I removed platform ios with cordova platform remove ios and added it again with cordova platform add ios back so it builds the plugins new.
Now I'm getting the blue bar on the display again :-)
This fix will break the geolocation support on iOS < 9.0. To bring it to work with older versions than 9.0 use this CDVLocation.m file:
The code I changed is marked with: //Edited by kingalione
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVLocation.h"
#import <Cordova/NSArray+Comparisons.h>
#pragma mark Constants
#define kPGLocationErrorDomain #"kPGLocationErrorDomain"
#define kPGLocationDesiredAccuracyKey #"desiredAccuracy"
#define kPGLocationForcePromptKey #"forcePrompt"
#define kPGLocationDistanceFilterKey #"distanceFilter"
#define kPGLocationFrequencyKey #"frequency"
//Edited by kingalione: START
#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
//Edited by kingalione: END
#pragma mark -
#pragma mark Categories
#implementation CDVLocationData
#synthesize locationStatus, locationInfo, locationCallbacks, watchCallbacks;
- (CDVLocationData*)init
{
self = (CDVLocationData*)[super init];
if (self) {
self.locationInfo = nil;
self.locationCallbacks = nil;
self.watchCallbacks = nil;
}
return self;
}
#end
#pragma mark -
#pragma mark CDVLocation
#implementation CDVLocation
#synthesize locationManager, locationData;
- (CDVPlugin*)initWithWebView:(UIWebView*)theWebView
{
self = (CDVLocation*)[super initWithWebView:(UIWebView*)theWebView];
if (self) {
self.locationManager = [[CLLocationManager alloc] init];
//Edited by kingalione: START
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"9.0")) {
self.locationManager.allowsBackgroundLocationUpdates = YES;
}
//Edited by kingalione: END
self.locationManager.delegate = self; // Tells the location manager to send updates to this object
__locationStarted = NO;
__highAccuracyEnabled = NO;
self.locationData = nil;
}
return self;
}
- (BOOL)isAuthorized
{
BOOL authorizationStatusClassPropertyAvailable = [CLLocationManager respondsToSelector:#selector(authorizationStatus)]; // iOS 4.2+
if (authorizationStatusClassPropertyAvailable) {
NSUInteger authStatus = [CLLocationManager authorizationStatus];
#ifdef __IPHONE_8_0
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) { //iOS 8.0+
return (authStatus == kCLAuthorizationStatusAuthorizedWhenInUse) || (authStatus == kCLAuthorizationStatusAuthorizedAlways) || (authStatus == kCLAuthorizationStatusNotDetermined);
}
#endif
return (authStatus == kCLAuthorizationStatusAuthorized) || (authStatus == kCLAuthorizationStatusNotDetermined);
}
// by default, assume YES (for iOS < 4.2)
return YES;
}
- (BOOL)isLocationServicesEnabled
{
BOOL locationServicesEnabledInstancePropertyAvailable = [self.locationManager respondsToSelector:#selector(locationServicesEnabled)]; // iOS 3.x
BOOL locationServicesEnabledClassPropertyAvailable = [CLLocationManager respondsToSelector:#selector(locationServicesEnabled)]; // iOS 4.x
if (locationServicesEnabledClassPropertyAvailable) { // iOS 4.x
return [CLLocationManager locationServicesEnabled];
} else if (locationServicesEnabledInstancePropertyAvailable) { // iOS 2.x, iOS 3.x
return [(id)self.locationManager locationServicesEnabled];
} else {
return NO;
}
}
- (void)startLocation:(BOOL)enableHighAccuracy
{
if (![self isLocationServicesEnabled]) {
[self returnLocationError:PERMISSIONDENIED withMessage:#"Location services are not enabled."];
return;
}
if (![self isAuthorized]) {
NSString* message = nil;
BOOL authStatusAvailable = [CLLocationManager respondsToSelector:#selector(authorizationStatus)]; // iOS 4.2+
if (authStatusAvailable) {
NSUInteger code = [CLLocationManager authorizationStatus];
if (code == kCLAuthorizationStatusNotDetermined) {
// could return POSITION_UNAVAILABLE but need to coordinate with other platforms
message = #"User undecided on application's use of location services.";
} else if (code == kCLAuthorizationStatusRestricted) {
message = #"Application's use of location services is restricted.";
}
}
// PERMISSIONDENIED is only PositionError that makes sense when authorization denied
[self returnLocationError:PERMISSIONDENIED withMessage:message];
return;
}
#ifdef __IPHONE_8_0
NSUInteger code = [CLLocationManager authorizationStatus];
if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])) { //iOS8+
__highAccuracyEnabled = enableHighAccuracy;
if([[NSBundle mainBundle] objectForInfoDictionaryKey:#"NSLocationAlwaysUsageDescription"]){
[self.locationManager requestAlwaysAuthorization];
} else if([[NSBundle mainBundle] objectForInfoDictionaryKey:#"NSLocationWhenInUseUsageDescription"]) {
[self.locationManager requestWhenInUseAuthorization];
} else {
NSLog(#"[Warning] No NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription key is defined in the Info.plist file.");
}
return;
}
#endif
// Tell the location manager to start notifying us of location updates. We
// first stop, and then start the updating to ensure we get at least one
// update, even if our location did not change.
[self.locationManager stopUpdatingLocation];
[self.locationManager startUpdatingLocation];
__locationStarted = YES;
if (enableHighAccuracy) {
__highAccuracyEnabled = YES;
// Set distance filter to 5 for a high accuracy. Setting it to "kCLDistanceFilterNone" could provide a
// higher accuracy, but it's also just spamming the callback with useless reports which drain the battery.
self.locationManager.distanceFilter = 5;
// Set desired accuracy to Best.
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
} else {
__highAccuracyEnabled = NO;
// TODO: Set distance filter to 10 meters? and desired accuracy to nearest ten meters? arbitrary.
self.locationManager.distanceFilter = 10;
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
}
}
- (void)_stopLocation
{
if (__locationStarted) {
if (![self isLocationServicesEnabled]) {
return;
}
[self.locationManager stopUpdatingLocation];
__locationStarted = NO;
__highAccuracyEnabled = NO;
}
}
- (void)locationManager:(CLLocationManager*)manager
didUpdateToLocation:(CLLocation*)newLocation
fromLocation:(CLLocation*)oldLocation
{
CDVLocationData* cData = self.locationData;
cData.locationInfo = newLocation;
if (self.locationData.locationCallbacks.count > 0) {
for (NSString* callbackId in self.locationData.locationCallbacks) {
[self returnLocationInfo:callbackId andKeepCallback:NO];
}
[self.locationData.locationCallbacks removeAllObjects];
}
if (self.locationData.watchCallbacks.count > 0) {
for (NSString* timerId in self.locationData.watchCallbacks) {
[self returnLocationInfo:[self.locationData.watchCallbacks objectForKey:timerId] andKeepCallback:YES];
}
} else {
// No callbacks waiting on us anymore, turn off listening.
[self _stopLocation];
}
}
- (void)getLocation:(CDVInvokedUrlCommand*)command
{
NSString* callbackId = command.callbackId;
BOOL enableHighAccuracy = [[command argumentAtIndex:0] boolValue];
if ([self isLocationServicesEnabled] == NO) {
NSMutableDictionary* posError = [NSMutableDictionary dictionaryWithCapacity:2];
[posError setObject:[NSNumber numberWithInt:PERMISSIONDENIED] forKey:#"code"];
[posError setObject:#"Location services are disabled." forKey:#"message"];
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:posError];
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
} else {
if (!self.locationData) {
self.locationData = [[CDVLocationData alloc] init];
}
CDVLocationData* lData = self.locationData;
if (!lData.locationCallbacks) {
lData.locationCallbacks = [NSMutableArray arrayWithCapacity:1];
}
if (!__locationStarted || (__highAccuracyEnabled != enableHighAccuracy)) {
// add the callbackId into the array so we can call back when get data
if (callbackId != nil) {
[lData.locationCallbacks addObject:callbackId];
}
// Tell the location manager to start notifying us of heading updates
[self startLocation:enableHighAccuracy];
} else {
[self returnLocationInfo:callbackId andKeepCallback:NO];
}
}
}
- (void)addWatch:(CDVInvokedUrlCommand*)command
{
NSString* callbackId = command.callbackId;
NSString* timerId = [command argumentAtIndex:0];
BOOL enableHighAccuracy = [[command argumentAtIndex:1] boolValue];
if (!self.locationData) {
self.locationData = [[CDVLocationData alloc] init];
}
CDVLocationData* lData = self.locationData;
if (!lData.watchCallbacks) {
lData.watchCallbacks = [NSMutableDictionary dictionaryWithCapacity:1];
}
// add the callbackId into the dictionary so we can call back whenever get data
[lData.watchCallbacks setObject:callbackId forKey:timerId];
if ([self isLocationServicesEnabled] == NO) {
NSMutableDictionary* posError = [NSMutableDictionary dictionaryWithCapacity:2];
[posError setObject:[NSNumber numberWithInt:PERMISSIONDENIED] forKey:#"code"];
[posError setObject:#"Location services are disabled." forKey:#"message"];
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:posError];
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
} else {
if (!__locationStarted || (__highAccuracyEnabled != enableHighAccuracy)) {
// Tell the location manager to start notifying us of location updates
[self startLocation:enableHighAccuracy];
}
}
}
- (void)clearWatch:(CDVInvokedUrlCommand*)command
{
NSString* timerId = [command argumentAtIndex:0];
if (self.locationData && self.locationData.watchCallbacks && [self.locationData.watchCallbacks objectForKey:timerId]) {
[self.locationData.watchCallbacks removeObjectForKey:timerId];
if([self.locationData.watchCallbacks count] == 0) {
[self _stopLocation];
}
}
}
- (void)stopLocation:(CDVInvokedUrlCommand*)command
{
[self _stopLocation];
}
- (void)returnLocationInfo:(NSString*)callbackId andKeepCallback:(BOOL)keepCallback
{
CDVPluginResult* result = nil;
CDVLocationData* lData = self.locationData;
if (lData && !lData.locationInfo) {
// return error
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageToErrorObject:POSITIONUNAVAILABLE];
} else if (lData && lData.locationInfo) {
CLLocation* lInfo = lData.locationInfo;
NSMutableDictionary* returnInfo = [NSMutableDictionary dictionaryWithCapacity:8];
NSNumber* timestamp = [NSNumber numberWithDouble:([lInfo.timestamp timeIntervalSince1970] * 1000)];
[returnInfo setObject:timestamp forKey:#"timestamp"];
[returnInfo setObject:[NSNumber numberWithDouble:lInfo.speed] forKey:#"velocity"];
[returnInfo setObject:[NSNumber numberWithDouble:lInfo.verticalAccuracy] forKey:#"altitudeAccuracy"];
[returnInfo setObject:[NSNumber numberWithDouble:lInfo.horizontalAccuracy] forKey:#"accuracy"];
[returnInfo setObject:[NSNumber numberWithDouble:lInfo.course] forKey:#"heading"];
[returnInfo setObject:[NSNumber numberWithDouble:lInfo.altitude] forKey:#"altitude"];
[returnInfo setObject:[NSNumber numberWithDouble:lInfo.coordinate.latitude] forKey:#"latitude"];
[returnInfo setObject:[NSNumber numberWithDouble:lInfo.coordinate.longitude] forKey:#"longitude"];
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:returnInfo];
[result setKeepCallbackAsBool:keepCallback];
}
if (result) {
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
}
}
- (void)returnLocationError:(NSUInteger)errorCode withMessage:(NSString*)message
{
NSMutableDictionary* posError = [NSMutableDictionary dictionaryWithCapacity:2];
[posError setObject:[NSNumber numberWithUnsignedInteger:errorCode] forKey:#"code"];
[posError setObject:message ? message:#"" forKey:#"message"];
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:posError];
for (NSString* callbackId in self.locationData.locationCallbacks) {
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
}
[self.locationData.locationCallbacks removeAllObjects];
for (NSString* callbackId in self.locationData.watchCallbacks) {
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
}
}
- (void)locationManager:(CLLocationManager*)manager didFailWithError:(NSError*)error
{
NSLog(#"locationManager::didFailWithError %#", [error localizedFailureReason]);
CDVLocationData* lData = self.locationData;
if (lData && __locationStarted) {
// TODO: probably have to once over the various error codes and return one of:
// PositionError.PERMISSION_DENIED = 1;
// PositionError.POSITION_UNAVAILABLE = 2;
// PositionError.TIMEOUT = 3;
NSUInteger positionError = POSITIONUNAVAILABLE;
if (error.code == kCLErrorDenied) {
positionError = PERMISSIONDENIED;
}
[self returnLocationError:positionError withMessage:[error localizedDescription]];
}
if (error.code != kCLErrorLocationUnknown) {
[self.locationManager stopUpdatingLocation];
__locationStarted = NO;
}
}
//iOS8+
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
if(!__locationStarted){
[self startLocation:__highAccuracyEnabled];
}
}
- (void)dealloc
{
self.locationManager.delegate = nil;
}
- (void)onReset
{
[self _stopLocation];
[self.locationManager stopUpdatingHeading];
}
#end
Thank you for updating the geolocation plugin so that it allows an app to run in the background with iOS 9.
It took me quite a while to get it all working in my Phonegap Build app. It may be helpful to others to see what I needed to include in my config.xml file:
<plugin spec="https://github.com/ionberry/cordova-plugin-geolocation-ios9-fix.git" source="git" />
<gap:config-file platform="ios" parent="UIBackgroundModes" overwrite="true">
<array>
<string>location</string>
</array>
</gap:config-file>

ios game center authentication keeps failing

Basically under ViewController's viewdidload method, I put:
[self authenticateLocalUser];
And authenticateLocalUser method is:
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
if (localPlayer.isAuthenticated == NO)
{
NSLog(#"FAILED");
}
Why doesn't it authenticate? Shouldn't the class method for GKLocalPlayer authenticate automatically? Also, if it does authenticate, should I get the "welcome back __" on the top? I am not getting this banner at all. Is there something I need to do beforehand?
In iOS6 and above you need to present Game Center login view with setAuthenticateHandler api.
Here is Code:
#define CHECK_IOS_LESS_THAN(version) ([[[UIDevice currentDevice] systemVersion] \
compare:version options:NSNumericSearch] == NSOrderedAscending)
- (void) authenticateLocalUser
{
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
if (CHECK_IOS_LESS_THAN(#"6.0"))
{
// ios 5.x and below
[localPlayer authenticateWithCompletionHandler:^(NSError *error)
{
[self checkLocalPlayer];
}];
}
else
{
// ios 6.0 and above
[localPlayer setAuthenticateHandler:(^(UIViewController* viewcontroller, NSError *error)
{
if (!error && viewcontroller)
{
[self.navController
presentViewController:viewcontroller animated:YES completion:nil];
}
else
{
[self checkLocalPlayer];
}
})];
}
}
- (void)checkLocalPlayer
{
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
if (localPlayer.isAuthenticated)
{
/* Perform additional tasks for the authenticated player here */
[self processGameCenterLoginSuccess];
}
else
{
/* Perform additional tasks for the non-authenticated player here */
[self processGameCenterLoginFaild];
}
}
After adding this code, goto device settings and Reset:
Device: Settings->General->Reset->Reset All Settings
Simulator: Settings->General->Reset->Reset Locations and Privacy
You need to install an authenticateHandler. A section in Apple's Game Center Programming Guide gives a verbatim example. The code starts like this (see that section as linked for full source code):
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = // ...

UIIMagePicker camera landscape orientation issue

I have a view controller and i have added UIImagePicker as subview. On changing device orientation from portrait to landscape, camera appears to be on half screen rather than full screen. the images in the camera is also rotated 90 degrees. I am supporting device orientation in my app. how to fix this camera orientation issue. Any help is appreciated.
//Code for presenting camera
- (id)init
{
self = [super init];
if (self) {
UIImagePickerController * picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera ;
picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
picker.allowsEditing = YES;
self.cameraPicker = picker;
cameraPicker.view.frame = CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height );;
//cameraPicker.view.frame = CGRectMake(0,0,[UIScreen mainScreen].bounds.size.width,[UIScreen mainScreen].bounds.size.height );
[self.view addSubview:cameraPicker.view];
}
return self;
}
//Code for supporting device orientation
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[self setFramesForControls:toInterfaceOrientation];
}
-(void)setFramesForControls :(UIInterfaceOrientation)orientation
{
if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
{
cameraPicker.view.frame = CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height );
}
else if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
{
cameraPicker.view.frame = CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height );
}
}
Try this its working fine
declare this in viewdidload method
picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera ;
picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
picker.allowsEditing = YES;
and on button click event do the following
[self presentModalViewController:picker animated:YES];
no matter to check device orientation;
To prevent your image this code will help you-
Define these macros on the top of your ViewController class-
#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
Then manage your delegate method in this way-
#pragma mark- Delegate methods of UIImagePickerController Class
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *pickedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
NSString *imgType = [info objectForKey:UIImagePickerControllerReferenceURL];
//NSLog(#"%#",imgType);
imgType = [imgType lastPathComponent];
NSData *imageData;
if (SYSTEM_VERSION_LESS_THAN(#"6.0"))
{
// code here
imageData = UIImagePNGRepresentation(pickedImage);
}
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"6.0"))
{
// code here
imageData = UIImageJPEGRepresentation(pickedImage, 0.5);
}
NSError * error = nil;
[imageData writeToFile:path options:NSDataWritingAtomic error:&error];
if (error != nil)
{
NSLog(#"ERROR: %#", error);
return;
}
[picker dismissViewControllerAnimated:YES completion: nil];
}
It will capture the images according to your requirement.

IOS Game Center GKLocalPlayerListener

I was trying to implement an event listener in a turn based game so a player can receive when his turn is active or when he is invited by a friend. GKTurnBasedEventHandler is deprecated in IOS 7 and i read in the documentation that i should use GKLocalPlayerListener; but that's the extend of it. Is there someone who used it already, because there is no info anywhere.
This is what i tried before, and it does not work.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
[localPlayer authenticateWithCompletionHandler:^(NSError *error)
{
if (localPlayer.isAuthenticated)
{
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
[localPlayer registerListener:self];
}
}];
return YES;
}
-(void)handleInviteFromGameCenter:(NSArray *)playersToInvite
{
NSLog(#"test");
}
- (void)player:(GKPlayer *)player receivedTurnEventForMatch:(GKTurnBasedMatch *)match didBecomeActive:(BOOL)didBecomeActive
{
NSLog(#"test");
}
Here is some code that I use in order to register GKLocalPlayerListener
__weak GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error) {
if (viewController) {
[authenticateFromViewController presentViewController:viewController animated:YES completion:^{
[localPlayer registerListener:self];
NSLog(#"Authenticated. Registering Turn Based Events listener");
}];
} else if (localPlayer.authenticated) {
[localPlayer registerListener:self];
NSLog(#"User Already Authenticated. Registering Turn Based Events listener");
} else {
NSLog(#"Unable to Authenticate with Game Center: %#", [error localizedDescription]);
}
};
The documentation states that you should only register for an GKLocalPlayerEventListener once so you could improve this code by checking if you've already registered.
Note that authenticateWithCompletionHandler is deprecated in iOS 6 and they recommend setting the authenticateHandler property like I did above.
I believe you were there. Just this time do a couple of things. Make sure you dont add multiple listeners also before you add a listener, just incase unregister all listeners.
I made sure I only did this once in my whole project, but I get the local player multiple times.
-(void) onLocalPlayerAuthChanged:(GKLocalPlayer*)authPlayer {
[authPlayer unregisterAllListeners];
[authPlayer registerListener:_Whatever_];
}
I might be a little late, but hopefully it will help someone out there...
This is what I do. According to Apple's documentation I create [my] own method that displays an authentication view when appropriate for [my] app.
- (void)authenticateLocalUser
{
if ([GKLocalPlayer localPlayer].authenticated == NO) {
__weak typeof(self) weakSelf = self;
__weak GKLocalPlayer *weakPlayer = [GKLocalPlayer localPlayer];
weakPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error) {
if (viewController != nil) {
[weakSelf showAuthenticationDialogWhenReasonable:viewController];
} else if (weakPlayer.isAuthenticated) {
// Player has been authenticated!
[weakPlayer registerListener:weakSelf];
} else {
// Should disable Game Center?
}
};
} else {
// Already authenticated
[[GKLocalPlayer localPlayer] registerListener:self];
}
}
-(void)showAuthenticationDialogWhenReasonable:(UIViewController *)controller
{
[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:controller animated:YES completion:nil];
}
This code is inside a singleton helper class, it might be simplified if you have it on your own class.

Resources