You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by fi...@apache.org on 2012/05/08 21:53:39 UTC

[3/5] ios commit: [CB-359] Updates to adhere to W3C spec for geolocation. Changing actions based on changes incorporated into cordova-js

[CB-359] Updates to adhere to W3C spec for geolocation. Changing actions based on changes incorporated into cordova-js


Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/commit/8d2b44d7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/tree/8d2b44d7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/diff/8d2b44d7

Branch: refs/heads/master
Commit: 8d2b44d7cd21c2264718983a25d48b8de9ad7b4a
Parents: c18663f
Author: Fil Maj <ma...@gmail.com>
Authored: Wed Mar 28 14:56:53 2012 -0700
Committer: Fil Maj <ma...@gmail.com>
Committed: Tue May 8 12:55:54 2012 -0700

----------------------------------------------------------------------
 CordovaLib/Classes/CDVLocation.h |   15 +++-
 CordovaLib/Classes/CDVLocation.m |  135 ++++++++++++++++++++-------------
 2 files changed, 93 insertions(+), 57 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/8d2b44d7/CordovaLib/Classes/CDVLocation.h
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVLocation.h b/CordovaLib/Classes/CDVLocation.h
index 7f47bf4..f75873d 100755
--- a/CordovaLib/Classes/CDVLocation.h
+++ b/CordovaLib/Classes/CDVLocation.h
@@ -52,16 +52,24 @@ typedef NSUInteger CDVLocationStatus;
 
 // simple ojbect to keep track of location information
 @interface CDVLocationData : NSObject {
+    CDVLocationStatus locationStatus;
+    NSMutableArray*  locationCallbacks;
+    NSMutableDictionary*  watchCallbacks;
+    CLLocation*      locationInfo;
 }
 
 @property (nonatomic, assign) CDVLocationStatus locationStatus;
 @property (nonatomic, retain) CLLocation* locationInfo;
 @property (nonatomic, retain) NSMutableArray* locationCallbacks;
+@property (nonatomic, retain) NSMutableDictionary* watchCallbacks;
 
 @end
 
 @interface CDVLocation : CDVPlugin <CLLocationManagerDelegate> {
     @private BOOL      __locationStarted;
+    @private BOOL      __highAccuracyEnabled;
+    CDVHeadingData*    headingData;
+    CDVLocationData*   locationData;
 }
 
 @property (nonatomic, retain) CLLocationManager *locationManager;
@@ -71,11 +79,12 @@ typedef NSUInteger CDVLocationStatus;
 
 - (BOOL) hasHeadingSupport;
 - (void) getLocation:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
-- (void) stopLocation:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
+- (void) addWatch:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
+- (void) clearWatch:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
 - (void) returnLocationInfo: (NSString*) callbackId;
 - (void) returnLocationError: (NSUInteger) errorCode withMessage: (NSString*) message;
-- (void) startLocation;
-- (void) _stopLocation;
+- (void) startLocation: (BOOL) enableHighAccuracy;
+- (void) stopLocation;
 
 - (void) locationManager:(CLLocationManager *)manager
     didUpdateToLocation:(CLLocation *)newLocation

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/8d2b44d7/CordovaLib/Classes/CDVLocation.m
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVLocation.m b/CordovaLib/Classes/CDVLocation.m
index 75a7ab7..194f033 100755
--- a/CordovaLib/Classes/CDVLocation.m
+++ b/CordovaLib/Classes/CDVLocation.m
@@ -84,7 +84,7 @@
 
 @implementation CDVLocationData
 
-@synthesize locationStatus, locationInfo, locationCallbacks;
+@synthesize locationStatus, locationInfo, locationCallbacks, watchCallbacks;
 -(CDVLocationData*) init
 {
     self = (CDVLocationData*)[super init];
@@ -92,6 +92,7 @@
 	{
         self.locationInfo = nil;
         self.locationCallbacks = nil;
+        self.watchCallbacks = nil;
     }
     return self;
 }
@@ -99,6 +100,7 @@
 {
     self.locationInfo = nil;
     self.locationCallbacks = nil;
+    self.watchCallbacks = nil;
     [super dealloc];  
 }
 
@@ -119,6 +121,7 @@
         self.locationManager = [[[CLLocationManager alloc] init] autorelease];
         self.locationManager.delegate = self; // Tells the location manager to send updates to this object
         __locationStarted = NO;
+        __highAccuracyEnabled = NO;
         self.headingData = nil;   
         self.locationData = nil;
     }
@@ -171,24 +174,12 @@
 	}
 }
 
-- (void) startLocation
+- (void) startLocation:(BOOL) enableHighAccuracy
 {
-    // TODO: clean up the old options that were ios-only.
     if (![self isLocationServicesEnabled])
 	{
-		BOOL forcePrompt = NO;
-		// if forcePrompt is true iPhone will still show the "Location Services not active." Settings | Cancel prompt.
-        /*
-		if ([options objectForKey:kPGLocationForcePromptKey]) 
-		{
-			forcePrompt = [[options objectForKey:kPGLocationForcePromptKey] boolValue];
-		}
-        */
-		if (!forcePrompt)
-		{
-            [self returnLocationError:PERMISSIONDENIED withMessage: nil];
-			return;
-		}
+        [self returnLocationError:PERMISSIONDENIED withMessage: @"Location services are not enabled."];
+        return;
     }
     if (![self isAuthorized]) 
     {
@@ -198,9 +189,9 @@
             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";
+                message = @"User undecided on application's use of location services.";
             } else if (code == kCLAuthorizationStatusRestricted) {
-                message = @"application use of location services is restricted";
+                message = @"Application's use of location services is restricted.";
             }
         }
         //PERMISSIONDENIED is only PositionError that makes sense when authorization denied
@@ -215,37 +206,18 @@
     [self.locationManager stopUpdatingLocation];
     [self.locationManager startUpdatingLocation];
     __locationStarted = YES;
-    /*
-    if ([options objectForKey:kPGLocationDistanceFilterKey]) 
-	{
-        CLLocationDistance distanceFilter = [(NSString *)[options objectForKey:kPGLocationDistanceFilterKey] doubleValue];
-        self.locationManager.distanceFilter = distanceFilter;
-    }
-    
-    if ([options objectForKey:kPGLocationDesiredAccuracyKey]) 
-    {
-        int desiredAccuracy_num = [(NSString *)[options objectForKey:kPGLocationDesiredAccuracyKey] integerValue];
-        CLLocationAccuracy desiredAccuracy = kCLLocationAccuracyBest;
-        
-        if (desiredAccuracy_num < 10) {
-            desiredAccuracy = kCLLocationAccuracyBest;
-        }
-        else if (desiredAccuracy_num < 100) {
-            desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
-        }
-        else if (desiredAccuracy_num < 1000) {
-            desiredAccuracy = kCLLocationAccuracyHundredMeters;
-        }
-        else if (desiredAccuracy_num < 3000) {
-            desiredAccuracy = kCLLocationAccuracyKilometer;
-        }
-        else {
-            desiredAccuracy = kCLLocationAccuracyThreeKilometers;
-        }
-        
-        self.locationManager.desiredAccuracy = desiredAccuracy;
+    if (enableHighAccuracy) {
+        __highAccuracyEnabled = YES;
+        // Set to distance filter to "none" - which should be the minimum for best results.
+        self.locationManager.distanceFilter = kCLDistanceFilterNone;
+        // 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
@@ -258,6 +230,7 @@
         
 		[self.locationManager stopUpdatingLocation];
 		__locationStarted = NO;
+        __highAccuracyEnabled = NO;
 	}
 }
 
@@ -273,16 +246,28 @@
         }
         [self.locationData.locationCallbacks removeAllObjects];
     }
+    if (self.locationData.watchCallbacks.count > 0) {
+        for (NSString *callbackId in self.locationData.watchCallbacks) {
+            [self returnLocationInfo:callbackId];
+        }
+    } else {
+        // No callbacks waiting on us anymore, turn off listening.
+        [self stopLocation];
+    }
 }
 
 - (void) getLocation:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options
 {
     NSUInteger argc = [arguments count];
     NSString* callbackId = (argc > 0)? [arguments objectAtIndex:0] : @"INVALID";
-    
+    BOOL enableHighAccuracy = [[arguments objectAtIndex:1] boolValue];
+
     if ([self isLocationServicesEnabled] == NO)
     {
-        CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageToErrorObject:2];
+        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];
         [super writeJavascript:[result toErrorCallbackString:callbackId]];
     } else {
         if (!self.locationData) {
@@ -293,16 +278,55 @@
             lData.locationCallbacks = [NSMutableArray arrayWithCapacity:1];
         }
         
-        if (!__locationStarted) {
+        if (!__locationStarted || __highAccuracyEnabled != enableHighAccuracy) {
             // add the callbackId into the array so we can call back when get data
             [lData.locationCallbacks addObject:callbackId];
             // Tell the location manager to start notifying us of heading updates
-            [self startLocation];
+            [self startLocation: enableHighAccuracy];
         }
         else {
             [self returnLocationInfo: callbackId]; 
         }
-
+    }
+}
+- (void) addWatch:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options
+{
+    NSString* callbackId = [arguments objectAtIndex:0];
+    NSString* timerId = [arguments objectAtIndex:1];
+    BOOL enableHighAccuracy = [[arguments objectAtIndex:2] boolValue];
+    
+    if (!self.locationData) {
+        self.locationData = [[[CDVLocationData alloc] init] autorelease];
+    }
+    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];
+        [super writeJavascript:[result toErrorCallbackString:callbackId]];
+    } else {
+        if (!__locationStarted || __highAccuracyEnabled != enableHighAccuracy) {
+            // Tell the location manager to start notifying us of location updates
+            [self startLocation: enableHighAccuracy];
+        }
+    }
+}
+- (void) clearWatch:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options
+{
+    //NSString* callbackId = [arguments objectAtIndex:0];
+    NSString* timerId = [arguments objectAtIndex:1];
+    if (self.locationData && self.locationData.watchCallbacks && [self.locationData.watchCallbacks objectForKey:timerId]) {
+        [self.locationData.watchCallbacks removeObjectForKey:timerId];
     }
 }
 
@@ -353,6 +377,9 @@
         [super writeJavascript:[result toErrorCallbackString:callbackId]];
     }
     [self.locationData.locationCallbacks removeAllObjects];
+    for (NSString *callbackId in self.locationData.watchCallbacks) {
+        [super writeJavascript:[result toErrorCallbackString:callbackId]];
+    }
 }
 // called to get the current heading
 // Will call location manager to startUpdatingHeading if necessary
@@ -631,4 +658,4 @@
             ];
 }
 
-@end
\ No newline at end of file
+@end