From 89c23381437613bb4277730cd3706e7e88748463 Mon Sep 17 00:00:00 2001 From: Stanimir Karoserov Date: Mon, 14 Apr 2014 19:03:48 +0300 Subject: [PATCH] iOS location updates --- Location/location.android.ts | 4 +- Location/location.d.ts | 26 +++++++++-- Location/location.ios.ts | 85 ++++++++++++++++++++++++++++++++---- Location/location_types.ts | 6 +-- declarations.ios.d.ts | 26 +++++++++++ 5 files changed, 129 insertions(+), 18 deletions(-) diff --git a/Location/location.android.ts b/Location/location.android.ts index 444f6ed70..320369515 100644 --- a/Location/location.android.ts +++ b/Location/location.android.ts @@ -77,11 +77,11 @@ export class LocationManager { // other - public getLastKnownLocation(): types_module.LocationPoint { + public getLastKnownLocation(): types_module.Location { return null; } - public distanceInMeters(loc1: types_module.LocationPoint, loc2: types_module.LocationPoint): number { + public distanceInMeters(loc1: types_module.Location, loc2: types_module.Location): number { return 0; } } \ No newline at end of file diff --git a/Location/location.d.ts b/Location/location.d.ts index 643ccae88..b2eb7a55b 100644 --- a/Location/location.d.ts +++ b/Location/location.d.ts @@ -27,8 +27,25 @@ export declare class LocationRegion { public raduis: number; // radius in meters } +export declare class Location { + public latitude: number; + public longitude: number; + + public altitude: number; + + public horizontalAccuracy: number; + public verticalAccuracy: number; + + public speed: number; // in m/s ? + + public direction: number; // in degrees + + public timestamp: Date; +} + export declare class LocationChangeListener { - //onLocationChange(location: Location); + onLocationChange(location: Location); + onLocationError(error: string); } export declare class RegionChangeListener { @@ -39,6 +56,7 @@ export declare class RegionChangeListener { export declare class LocationManager { isLocationEnabled(): boolean; desiredAccuracy: number; + updateDistance: number; // listeners locationChangeListener: LocationChangeListener; @@ -53,10 +71,10 @@ export declare class LocationManager { // monitoring - startLocationMonitoring(); + startLocationMonitoring(onLocation: (location: Location) => any, onError?: (error: string) => any); stopLocationMonitoring(); // other - getLastKnownLocation(): LocationPoint; - distanceInMeters(loc1: LocationPoint, loc2: LocationPoint): number; + getLastKnownLocation(): Location; + distanceInMeters(loc1: Location, loc2: Location): number; } \ No newline at end of file diff --git a/Location/location.ios.ts b/Location/location.ios.ts index 55e057f0a..9d847b860 100644 --- a/Location/location.ios.ts +++ b/Location/location.ios.ts @@ -2,39 +2,106 @@ export class LocationManager { + private isStarted: boolean; + private locationManager: CoreLocation.CLLocationManager; + public isLocationEnabled(): boolean { - // TODO add proper implementation - return true; + return CoreLocation.CLLocationManager.locationServicesEnabled(); } constructor() { - + this.isStarted = false; + this.desiredAccuracy = types.DesiredAccuracy.HIGH; + this.updateDistance = -1; // kCLDistanceFilterNone + this.locationManager = new CoreLocation.CLLocationManager(); } // in meters // we might need some predefined values here like 'any' and 'high' public desiredAccuracy: number; + // The minimum distance (measured in meters) a device must move horizontally before an update event is generated. + public updateDistance: number; + // listeners - public locationChangeListener: types.LocationChangeListener; + //public locationChangeListener: types.LocationChangeListener; // monitoring - public startLocationMonitoring() { + private static locationFromCLLocation(clLocation: CoreLocation.CLLocation): types.Location { + var location = new types.Location(); + location.latitude = clLocation.coordinate.latitude; + location.longitude = clLocation.coordinate.longitude; + location.altitude = clLocation.altitude; + location.horizontalAccuracy = clLocation.horizontalAccuracy; + location.verticalAccuracy = clLocation.verticalAccuracy; + location.speed = clLocation.speed; + location.direction = clLocation.course; + location.timestamp = new Date(clLocation.timestamp.timeIntervalSince1970() * 1000); + console.dump(location); + return location; + } + public startLocationMonitoring(onLocation: (location: types.Location) => any, onError?: (error: string) => any) { + if (!this.isStarted) { + var LocationListener = Foundation.NSObject.extends({ + setupWithFunctions: function (onLocation, onError) { + this.onLocation = onLocation; + this.onError = onError; + } + + }, {}).implements({ + + protocol: "CLLocationManagerDelegate", + + implementation: { + locationManagerDidUpdateLocations: function (manager, locations) { + console.log('location received: ' + locations.count()); + for (var i = 0; i < locations.count(); i++) { + this.onLocation(LocationManager.locationFromCLLocation(locations.objectAtIndex(i))); + } + }, + + locationManagerDidFailWithError: function (manager, error) { + console.log('location error received ' + error.localizedDescription()); + if (this.onError) { + this.onError(error.localizedDescription()); + } + } + } + }); + + var listener = new LocationListener(); + listener.setupWithFunctions(onLocation, onError); + this.locationManager.delegate = listener; + this.locationManager.desiredAccuracy = this.desiredAccuracy; + this.locationManager.distanceFilter = this.updateDistance; + this.locationManager.startUpdatingLocation(); + } + else if (onError) { + onError('location monitoring already started'); + } } public stopLocationMonitoring() { - + if (this.isStarted) { + this.locationManager.stopUpdatingLocation(); + this.isStarted = false; + } } // other - public getLastKnownLocation(): types.LocationPoint { + public getLastKnownLocation(): types.Location { + var clLocation = this.locationManager.location; + if (null != clLocation) { + return LocationManager.locationFromCLLocation(clLocation); + } return null; } - public distanceInMeters(loc1: types.LocationPoint, loc2: types.LocationPoint): number { + public distanceInMeters(loc1: types.Location, loc2: types.Location): number { + // TODO return 0; } -} \ No newline at end of file +} diff --git a/Location/location_types.ts b/Location/location_types.ts index 55bd56f61..dd52740aa 100644 --- a/Location/location_types.ts +++ b/Location/location_types.ts @@ -4,7 +4,7 @@ HIGH = 3, } -export class LocationPoint { +export class Location { public latitude: number; public longitude: number; @@ -17,7 +17,7 @@ export class LocationPoint { public direction: number; // in degrees - public timestamp: any; + public timestamp: Date; } export class LocationRegion { @@ -39,4 +39,4 @@ export class RegionChangeListener { } onRegionExit(region: LocationRegion) { } -} \ No newline at end of file +} diff --git a/declarations.ios.d.ts b/declarations.ios.d.ts index 1a4cdbdae..5c723df54 100644 --- a/declarations.ios.d.ts +++ b/declarations.ios.d.ts @@ -46,6 +46,10 @@ declare module UIKit { } declare module Foundation { + export class NSObject { + static extends(...optionalParams: any[]): any; + } + export class NSUserDefaults { static standardUserDefaults(): any; } @@ -97,3 +101,25 @@ declare module Foundation { declare module QuartzCore { function CACurrentMediaTime(): number; } + +declare module CoreLocation { + export class CLLocationManager { + static locationServicesEnabled(): boolean; + delegate: any; + distanceFilter: number; + desiredAccuracy: number; + startUpdatingLocation(): void; + stopUpdatingLocation(): void; + location: CLLocation; + } + + export class CLLocation { + coordinate: any; + altitude: number; + horizontalAccuracy: number; + verticalAccuracy: number; + timestamp: Foundation.NSDate; + speed: number; + course: number; + } +}