Skip to content

Instantly share code, notes, and snippets.

@almsx
Created October 27, 2014 23:50
Show Gist options
  • Save almsx/722a9d9cd14afe9b5404 to your computer and use it in GitHub Desktop.
Save almsx/722a9d9cd14afe9b5404 to your computer and use it in GitHub Desktop.
Can modify Location Services Disabled Message Appcelerator iOS
/**
* Appcelerator_Bootstrap Appcelerator_Bootstrap_Bootstrap Mobile
* Copyright (c) 2009-2012 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*
* WARNING: This is generated code. Modify at your own risk and without support.
*/
#ifdef USE_TI_GEOLOCATION
#import "GeolocationModule.h"
#import "ASIFormDataRequest.h"
#import "TiApp.h"
#import "TiEvaluator.h"
#import "SBJSON.h"
#import <sys/utsname.h>
#import "NSData+Additions.h"
extern NSString * const TI_APPLICATION_GUID;
extern BOOL const TI_APPLICATION_ANALYTICS;
@interface GeolocationCallback : NSObject
{
id<TiEvaluator> context;
KrollCallback *callback;
}
-(id)initWithCallback:(KrollCallback*)callback context:(id<TiEvaluator>)context;
@end
@implementation GeolocationCallback
-(id)initWithCallback:(KrollCallback*)callback_ context:(id<TiEvaluator>)context_
{
if (self = [super init])
{
callback = [callback_ retain];
context = [context_ retain];
}
return self;
}
-(void)dealloc
{
RELEASE_TO_NIL(callback);
RELEASE_TO_NIL(context);
[super dealloc];
}
-(void)start:(NSDictionary*)params
{
// http://api.appcelerator.net/p/v1/geo
NSString *kGeolocationURL = stringWithHexString(@"687474703a2f2f6170692e61707063656c657261746f722e6e65742f702f76312f67656f");
NSMutableString *url = [[[NSMutableString alloc] init] autorelease];
[url appendString:kGeolocationURL];
[url appendString:@"?"];
for (id key in params)
{
NSString *value = [TiUtils stringValue:[params objectForKey:key]];
[url appendFormat:@"%@=%@&",key,[value stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:url]];
[request setDelegate:self];
[request addRequestHeader:@"User-Agent" value:[[TiApp app] userAgent]];
[request setRequestMethod:@"GET"];
[request setDefaultResponseEncoding:NSUTF8StringEncoding];
[request setAllowCompressedResponse:YES];
[request startAsynchronous];
}
-(void)requestSuccess:(NSString*)data
{
}
-(void)requestError:(NSString*)error
{
NSDictionary *event = [NSDictionary dictionaryWithObjectsAndKeys:NUMBOOL(NO),@"success",error,@"error",nil];
[context fireEvent:callback withObject:event remove:NO thisObject:nil];
}
-(void)requestFinished:(ASIHTTPRequest *)request
{
[[TiApp app] stopNetwork];
if (request!=nil && [request error]==nil)
{
NSString *data = [request responseString];
[self requestSuccess:data];
}
else
{
[self requestError:[[request error] description]];
}
[self autorelease];
}
-(void)requestFailed:(ASIHTTPRequest *)request
{
[[TiApp app] stopNetwork];
[self requestError:[[request error] description]];
[self autorelease];
}
@end
@interface ForwardGeoCallback : GeolocationCallback
@end
@interface ReverseGeoCallback : GeolocationCallback
@end
@implementation ForwardGeoCallback
-(void)requestSuccess:(NSString*)locationString
{
NSDictionary *event = nil;
NSArray *listItems = [locationString componentsSeparatedByString:@","];
if([listItems count] == 4 && [[listItems objectAtIndex:0] isEqualToString:@"200"])
{
id accuracy = [listItems objectAtIndex:1];
id latitude = [listItems objectAtIndex:2];
id longitude = [listItems objectAtIndex:3];
event = [NSDictionary dictionaryWithObjectsAndKeys:NUMBOOL(YES),@"success",accuracy,@"accuracy",latitude,@"latitude",longitude,@"longitude",nil];
}
else
{
//TODO: better error handling
event = [NSDictionary dictionaryWithObjectsAndKeys:NUMBOOL(NO),@"success",@"error obtaining geolocation",@"error",nil];
}
[context fireEvent:callback withObject:event remove:NO thisObject:nil];
}
@end
@implementation ReverseGeoCallback
-(void)requestSuccess:(NSString*)locationString
{
SBJSON *json = [[SBJSON alloc] init];
NSError * error = nil;
id event = [json fragmentWithString:locationString error:&error];
[json release];
if (error != nil) {
[self requestError:[error localizedDescription]];
}
else {
[context fireEvent:callback withObject:event remove:NO thisObject:nil];
}
}
@end
@implementation GeolocationModule
#pragma mark Internal
// TODO: Do we need to force this onto the main thread?
-(void)shutdownLocationManager
{
[lock lock];
if (locationManager == nil) {
[lock unlock];
return;
}
if (trackingHeading) {
[locationManager stopUpdatingHeading];
}
if (trackingLocation) {
[locationManager stopUpdatingLocation];
}
RELEASE_TO_NIL_AUTORELEASE(locationManager);
[lock unlock];
}
-(void)_destroy
{
[self shutdownLocationManager];
RELEASE_TO_NIL(tempManager);
RELEASE_TO_NIL(singleHeading);
RELEASE_TO_NIL(singleLocation);
RELEASE_TO_NIL(purpose);
RELEASE_TO_NIL(lock);
[super _destroy];
}
-(void)contextWasShutdown:(KrollBridge*)bridge
{
if (singleHeading!=nil)
{
for (KrollCallback *callback in [NSArray arrayWithArray:singleHeading])
{
KrollContext *ctx = (id<TiEvaluator>)[callback context];
if ([bridge krollContext] == ctx)
{
[singleHeading removeObject:callback];
}
}
if ([singleHeading count]==0)
{
RELEASE_TO_NIL(singleHeading);
[locationManager stopUpdatingHeading];
}
}
if (singleLocation!=nil)
{
for (KrollCallback *callback in [NSArray arrayWithArray:singleLocation])
{
KrollContext *ctx = (id<TiEvaluator>)[callback context];
if ([bridge krollContext] == ctx)
{
[singleLocation removeObject:callback];
}
}
if ([singleLocation count]==0)
{
RELEASE_TO_NIL(singleLocation);
[locationManager stopUpdatingLocation];
}
}
}
-(void)_configure
{
// reasonable defaults:
// accuracy by default
accuracy = kCLLocationAccuracyThreeKilometers;
// distance filter by default is notify of all movements
distance = kCLDistanceFilterNone;
// minimum heading filter by default
heading = kCLHeadingFilterNone;
// should we show heading calibration dialog? defaults to YES
calibration = YES;
lock = [[NSRecursiveLock alloc] init];
[super _configure];
}
-(CLLocationManager*)locationManager
{
[lock lock];
if (locationManager==nil)
{
RELEASE_TO_NIL(tempManager);
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
if (accuracy!=-1)
{
locationManager.desiredAccuracy = accuracy;
}
else
{
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
}
locationManager.distanceFilter = distance;
locationManager.headingFilter = heading;
if (purpose==nil)
{
NSLog(@"[ERROR] Starting in iOS 3.2, you must set the Ti.Geolocation.purpose property to indicate the purpose of using Location services for your application");
}
else
{
[locationManager setPurpose:purpose];
}
if ([CLLocationManager locationServicesEnabled]== NO)
{
//NOTE: this is from Apple example from LocateMe and it works well. the developer can still check for the
//property and do this message themselves before calling geo. But if they don't, we at least do it for them.
NSString *title = NSLocalizedString(@"Location Services Disabled",@"Location Services Disabled Alert Title");
NSString *msg = NSLocalizedString(@"You currently have all location services for this device disabled. If you proceed, you will be asked to confirm whether location services should be reenabled.",@"Location Services Disabled Alert Message");
NSString *ok = NSLocalizedString(@"OK",@"Location Services Disabled Alert OK Button");
UIAlertView *servicesDisabledAlert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:ok otherButtonTitles:nil];
[servicesDisabledAlert show];
[servicesDisabledAlert release];
}
}
[lock unlock];
return locationManager;
}
// this is useful for a few methods below that need to use an instance but we
// don't necessarily want to hold on to this guy
-(CLLocationManager*)tempLocationManager
{
if (locationManager!=nil)
{
// if we have an instance, just use it
return locationManager;
}
if (tempManager == nil) {
tempManager = [[CLLocationManager alloc] init];
}
return tempManager;
}
-(void)startStopLocationManagerIfNeeded
{
BOOL startHeading = NO;
BOOL startLocation = NO;
if (singleHeading!=nil && [singleHeading count] > 0)
{
startHeading = YES;
}
if (singleLocation!=nil && [singleLocation count] > 0)
{
startLocation = YES;
}
if (!startHeading && [self _hasListeners:@"heading"])
{
startHeading = YES;
}
if (!startLocation && [self _hasListeners:@"location"])
{
startLocation = YES;
}
if (startHeading || startLocation)
{
CLLocationManager *lm = [self locationManager];
if (startHeading && trackingHeading==NO)
{
[lm startUpdatingHeading];
trackingHeading = YES;
}
if (startLocation && trackingLocation==NO)
{
[lm startUpdatingLocation];
trackingLocation = YES;
}
}
else if ((!startHeading || !startLocation) && locationManager!=nil)
{
CLLocationManager *lm = [self locationManager];
if (startHeading==NO && trackingHeading)
{
trackingHeading = NO;
[lm stopUpdatingHeading];
}
if (startLocation==NO && trackingLocation)
{
trackingLocation = NO;
[lm stopUpdatingLocation];
}
if ((startHeading==NO && startLocation==NO) ||
(trackingHeading==NO && trackingLocation==NO))
{
[self shutdownLocationManager];
trackingLocation = NO;
trackingHeading = NO;
}
}
}
-(void)_listenerAdded:(NSString *)type count:(int)count
{
BOOL startStop = NO;
if (count == 1 && [type isEqualToString:@"heading"])
{
startStop = YES;
}
else if (count == 1 && [type isEqualToString:@"location"])
{
startStop = YES;
}
if (startStop)
{
// must be on UI thread
[self performSelectorOnMainThread:@selector(startStopLocationManagerIfNeeded) withObject:nil waitUntilDone:NO];
}
}
-(void)_listenerRemoved:(NSString *)type count:(int)count
{
BOOL check = NO;
if (count == 0 && [type isEqualToString:@"heading"])
{
check = YES;
if (trackingHeading)
{
trackingHeading = NO;
[locationManager stopUpdatingHeading];
}
}
else if (count == 0 && [type isEqualToString:@"location"])
{
check = YES;
if (trackingLocation)
{
trackingLocation = NO;
[locationManager stopUpdatingLocation];
}
}
if (check && ![self _hasListeners:@"heading"] && ![self _hasListeners:@"location"])
{
[self performSelectorOnMainThread:@selector(startStopLocationManagerIfNeeded) withObject:nil waitUntilDone:YES];
[self shutdownLocationManager];
trackingLocation = NO;
trackingHeading = NO;
RELEASE_TO_NIL(singleHeading);
RELEASE_TO_NIL(singleLocation);
}
}
-(BOOL)headingAvailable
{
return [CLLocationManager headingAvailable];
}
#pragma mark Public APIs
-(NSNumber*)hasCompass
{
UIDevice * theDevice = [UIDevice currentDevice];
NSString* version = [theDevice systemVersion];
BOOL headingAvailableBool = [self headingAvailable];
if (headingAvailableBool)
{
struct utsname u;
uname(&u);
if (!strcmp(u.machine, "i386"))
{
// 3.0 simulator headingAvailable will report YES but its not really available except post 3.0
headingAvailableBool = [version hasPrefix:@"3.0"] ? NO : [CLLocationManager headingAvailable];
}
}
return NUMBOOL(headingAvailableBool);
}
-(void)performGeo:(NSString*)direction address:(NSString*)address callback:(GeolocationCallback*)callback
{
[[TiApp app] startNetwork];
id aguid = TI_APPLICATION_GUID;
id sid = [[TiApp app] sessionId];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
direction, @"d",
aguid,@"aguid",
[TiUtils uniqueIdentifier],@"mid",
sid,@"sid",
address,@"q",
[[NSLocale currentLocale] objectForKey: NSLocaleCountryCode],@"c",
nil];
[callback start:params];
}
-(void)reverseGeocoder:(id)args
{
ENSURE_ARG_COUNT(args,3);
CGFloat lat = [TiUtils floatValue:[args objectAtIndex:0]];
CGFloat lon = [TiUtils floatValue:[args objectAtIndex:1]];
KrollCallback *callback = [args objectAtIndex:2];
ENSURE_TYPE(callback,KrollCallback);
ReverseGeoCallback *rcb = [[ReverseGeoCallback alloc] initWithCallback:callback context:[self executionContext]];
[self performGeo:@"r" address:[NSString stringWithFormat:@"%f,%f",lat,lon] callback:rcb];
}
-(void)forwardGeocoder:(id)args
{
ENSURE_ARG_COUNT(args,2);
KrollCallback *callback = [args objectAtIndex:1];
ENSURE_TYPE(callback,KrollCallback);
ForwardGeoCallback *fcb = [[ForwardGeoCallback alloc] initWithCallback:callback context:[self executionContext]];
[self performGeo:@"f" address:[TiUtils stringValue:[args objectAtIndex:0]] callback:fcb];
}
-(void)getCurrentHeading:(id)callback
{
ENSURE_UI_THREAD(getCurrentHeading,callback);
ENSURE_SINGLE_ARG(callback,KrollCallback);
if (singleHeading==nil)
{
singleHeading = [[NSMutableArray alloc] initWithCapacity:1];
}
[singleHeading addObject:callback];
[self startStopLocationManagerIfNeeded];
}
-(void)getCurrentPosition:(id)callback
{
ENSURE_UI_THREAD(getCurrentPosition,callback);
ENSURE_SINGLE_ARG(callback,KrollCallback);
if (singleLocation==nil)
{
singleLocation = [[NSMutableArray alloc] initWithCapacity:1];
}
[singleLocation addObject:callback];
[self startStopLocationManagerIfNeeded];
}
-(NSNumber*)highAccuracy
{
return NUMBOOL(accuracy==kCLLocationAccuracyBest);
}
-(void)setHighAccuracy:(NSNumber *)value
{
ENSURE_UI_THREAD(setHighAccuracy,value);
accuracy = kCLLocationAccuracyBest;
// don't prematurely start it
if (locationManager!=nil)
{
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
}
}
-(NSNumber*)accuracy
{
return NUMDOUBLE(accuracy);
}
-(void)setAccuracy:(NSNumber *)value
{
ENSURE_UI_THREAD(setAccuracy,value);
accuracy = [TiUtils doubleValue:value];
// don't prematurely start it
if (locationManager!=nil)
{
[locationManager setDesiredAccuracy:accuracy];
}
}
-(NSNumber*)distanceFilter
{
return NUMDOUBLE(distance);
}
-(void)setDistanceFilter:(NSNumber *)value
{
ENSURE_UI_THREAD(setDistanceFilter,value);
distance = [TiUtils doubleValue:value];
// don't prematurely start it
if (locationManager!=nil)
{
[locationManager setDistanceFilter:distance];
}
}
-(NSNumber*)headingFilter
{
return NUMDOUBLE(heading);
}
-(void)setHeadingFilter:(NSNumber *)value
{
ENSURE_UI_THREAD(setHeadingFilter,value);
heading = [TiUtils doubleValue:value];
// don't prematurely start it
if (locationManager!=nil)
{
[locationManager setHeadingFilter:heading];
}
}
-(NSNumber*)showCalibration
{
return NUMBOOL(calibration);
}
-(void)setShowCalibration:(NSNumber *)value
{
calibration = [TiUtils boolValue:value];
}
-(NSNumber*)locationServicesEnabled
{
return NUMBOOL([CLLocationManager locationServicesEnabled]);
}
-(NSNumber*)locationServicesAuthorization
{
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_2
if ([TiUtils isIOS4_2OrGreater]) {
return NUMINT([CLLocationManager authorizationStatus]);
}
#endif
return [self AUTHORIZATION_UNKNOWN];
}
-(void)restart:(id)arg
{
[lock lock];
[self shutdownLocationManager];
trackingHeading = NO;
trackingLocation = NO;
[lock unlock];
// must be on UI thread
[self performSelectorOnMainThread:@selector(startStopLocationManagerIfNeeded) withObject:nil waitUntilDone:NO];
}
MAKE_SYSTEM_PROP_DBL(ACCURACY_BEST,kCLLocationAccuracyBest);
MAKE_SYSTEM_PROP_DBL(ACCURACY_NEAREST_TEN_METERS,kCLLocationAccuracyNearestTenMeters);
MAKE_SYSTEM_PROP_DBL(ACCURACY_HUNDRED_METERS,kCLLocationAccuracyHundredMeters);
MAKE_SYSTEM_PROP_DBL(ACCURACY_KILOMETER,kCLLocationAccuracyKilometer);
MAKE_SYSTEM_PROP_DBL(ACCURACY_THREE_KILOMETERS,kCLLocationAccuracyThreeKilometers);
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_2
MAKE_SYSTEM_PROP(AUTHORIZATION_UNKNOWN, kCLAuthorizationStatusNotDetermined);
MAKE_SYSTEM_PROP(AUTHORIZATION_AUTHORIZED, kCLAuthorizationStatusAuthorized);
MAKE_SYSTEM_PROP(AUTHORIZATION_DENIED, kCLAuthorizationStatusDenied);
MAKE_SYSTEM_PROP(AUTHORIZATION_RESTRICTED, kCLAuthorizationStatusRestricted);
#else
// We only need auth unknown, because that's all the system will return.
MAKE_SYSTEM_PROP(AUTHORIZATION_UNKNOWN, 0);
#endif
MAKE_SYSTEM_PROP(ERROR_LOCATION_UNKNOWN, kCLErrorLocationUnknown);
MAKE_SYSTEM_PROP(ERROR_DENIED, kCLErrorDenied);
MAKE_SYSTEM_PROP(ERROR_NETWORK, kCLErrorNetwork);
MAKE_SYSTEM_PROP(ERROR_HEADING_FAILURE, kCLErrorHeadingFailure);
MAKE_SYSTEM_PROP(ERROR_REGION_MONITORING_DENIED, kCLErrorRegionMonitoringDenied);
MAKE_SYSTEM_PROP(ERROR_REGION_MONITORING_FAILURE, kCLErrorRegionMonitoringFailure);
MAKE_SYSTEM_PROP(ERROR_REGION_MONITORING_DELAYED, kCLErrorRegionMonitoringSetupDelayed);
#pragma mark Internal
-(NSDictionary*)locationDictionary:(CLLocation*)newLocation;
{
if ([newLocation timestamp] == 0)
{
// this happens when the location object is essentially null (as in no location)
return nil;
}
CLLocationCoordinate2D latlon = [newLocation coordinate];
NSDictionary * data = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat:latlon.latitude],@"latitude",
[NSNumber numberWithFloat:latlon.longitude],@"longitude",
[NSNumber numberWithFloat:[newLocation altitude]],@"altitude",
[NSNumber numberWithFloat:[newLocation horizontalAccuracy]],@"accuracy",
[NSNumber numberWithFloat:[newLocation verticalAccuracy]],@"altitudeAccuracy",
[NSNumber numberWithFloat:[newLocation course]],@"heading",
[NSNumber numberWithFloat:[newLocation speed]],@"speed",
[NSNumber numberWithLongLong:(long long)([[newLocation timestamp] timeIntervalSince1970] * 1000)],@"timestamp",
nil];
return data;
}
-(NSDictionary*)headingDictionary:(CLHeading*)newHeading
{
long long ts = (long long)[[newHeading timestamp] timeIntervalSince1970] * 1000;
NSDictionary *data = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:[newHeading magneticHeading]],@"magneticHeading",
[NSNumber numberWithDouble:[newHeading trueHeading]],@"trueHeading",
[NSNumber numberWithDouble:[newHeading headingAccuracy]],@"accuracy",
[NSNumber numberWithLongLong:ts],@"timestamp",
[NSNumber numberWithDouble:[newHeading x]],@"x",
[NSNumber numberWithDouble:[newHeading y]],@"y",
[NSNumber numberWithDouble:[newHeading z]],@"z",
nil];
return data;
}
#pragma mark Single Shot Handling
-(BOOL)fireSingleShotLocationIfNeeded:(NSDictionary*)event stopIfNeeded:(BOOL)stopIfNeeded
{
// check to see if we have any single shot location callbacks
if (singleLocation!=nil)
{
for (KrollCallback *callback in singleLocation)
{
[self _fireEventToListener:@"location" withObject:event listener:callback thisObject:nil];
}
// after firing, we remove them
RELEASE_TO_NIL(singleLocation);
// check to make sure we don't need to stop after the single shot
if (stopIfNeeded)
{
[self startStopLocationManagerIfNeeded];
}
return YES;
}
return NO;
}
-(BOOL)fireSingleShotHeadingIfNeeded:(NSDictionary*)event stopIfNeeded:(BOOL)stopIfNeeded
{
// check to see if we have any single shot heading callbacks
if (singleHeading!=nil)
{
for (KrollCallback *callback in singleHeading)
{
[self _fireEventToListener:@"heading" withObject:event listener:callback thisObject:nil];
}
// after firing, we remove them
RELEASE_TO_NIL(singleHeading);
// check to make sure we don't need to stop after the single shot
if (stopIfNeeded)
{
[self startStopLocationManagerIfNeeded];
}
return YES;
}
return NO;
}
-(NSString*)purpose
{
return purpose;
}
-(void)setPurpose:(NSString *)reason
{
ENSURE_UI_THREAD(setPurpose,reason);
RELEASE_TO_NIL(purpose);
purpose = [reason retain];
if (locationManager!=nil)
{
[locationManager setPurpose:purpose];
}
}
#pragma mark Delegates
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSDictionary *todict = [self locationDictionary:newLocation];
NSDictionary *event = [NSDictionary dictionaryWithObjectsAndKeys:
todict,@"coords",
NUMBOOL(YES),@"success",
nil];
if (TI_APPLICATION_ANALYTICS)
{
NSDictionary *data = [NSDictionary dictionaryWithObjectsAndKeys:todict,@"to",[self locationDictionary:oldLocation],@"from",nil];
NSDictionary *geo = [NSDictionary dictionaryWithObjectsAndKeys:data,@"data",@"ti.geo",@"name",@"ti.geo",@"type",nil];
WARN_IF_BACKGROUND_THREAD; //NSNotificationCenter is not threadsafe!
[[NSNotificationCenter defaultCenter] postNotificationName:kTiAnalyticsNotification object:nil userInfo:geo];
}
if ([self _hasListeners:@"location"])
{
[self fireEvent:@"location" withObject:event];
}
[self fireSingleShotLocationIfNeeded:event stopIfNeeded:YES];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSDictionary *event = [NSDictionary dictionaryWithObjectsAndKeys:[error localizedDescription],@"error",
NUMINT([error code]), @"code",
NUMBOOL(NO),@"success",nil];
if ([self _hasListeners:@"location"])
{
[self fireEvent:@"location" withObject:event];
}
BOOL recheck = [self fireSingleShotLocationIfNeeded:event stopIfNeeded:NO];
recheck = recheck || [self fireSingleShotHeadingIfNeeded:event stopIfNeeded:NO];
if (recheck)
{
// check to make sure we don't need to stop after the single shot
[self startStopLocationManagerIfNeeded];
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
NSDictionary *event = [NSDictionary dictionaryWithObjectsAndKeys:[self headingDictionary:newHeading],
@"heading", NUMBOOL(YES), @"success", nil];
[self fireEvent:@"heading" withObject:event];
[self fireSingleShotHeadingIfNeeded:event stopIfNeeded:YES];
}
- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager
{
if (calibration)
{
// fire an event in case the dev wants to hide it
if ([self _hasListeners:@"calibration"])
{
[self fireEvent:@"calibration" withObject:nil];
}
}
return calibration;
}
- (void)dismissHeadingCalibrationDisplay:(id)args
{
ENSURE_UI_THREAD(dismissHeadingCalibrationDisplay,args);
[[self locationManager] dismissHeadingCalibrationDisplay];
}
@end
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment