expo-location 12.1.2 → 13.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -2
- package/android/build.gradle +4 -13
- package/android/src/main/java/expo/modules/location/LocationHelpers.java +2 -2
- package/android/src/main/java/expo/modules/location/LocationModule.java +13 -12
- package/android/src/main/java/expo/modules/location/LocationPackage.java +2 -2
- package/android/src/main/java/expo/modules/location/LocationRequestCallbacks.java +1 -1
- package/android/src/main/java/expo/modules/location/exceptions/LocationBackgroundUnauthorizedException.java +2 -2
- package/android/src/main/java/expo/modules/location/exceptions/LocationRequestRejectedException.java +2 -2
- package/android/src/main/java/expo/modules/location/exceptions/LocationSettingsUnsatisfiedException.java +2 -2
- package/android/src/main/java/expo/modules/location/exceptions/LocationUnauthorizedException.java +2 -2
- package/android/src/main/java/expo/modules/location/exceptions/LocationUnavailableException.java +2 -2
- package/android/src/main/java/expo/modules/location/taskConsumers/LocationTaskConsumer.java +7 -6
- package/build/ExpoLocation.d.ts +1 -1
- package/build/ExpoLocation.js +1 -1
- package/build/ExpoLocation.js.map +1 -1
- package/build/ExpoLocation.web.js +6 -5
- package/build/ExpoLocation.web.js.map +1 -1
- package/build/GeolocationPolyfill.js +2 -2
- package/build/GeolocationPolyfill.js.map +1 -1
- package/build/Location.d.ts +22 -2
- package/build/Location.js +30 -3
- package/build/Location.js.map +1 -1
- package/build/LocationEventEmitter.d.ts +1 -1
- package/build/LocationEventEmitter.js +1 -1
- package/build/LocationEventEmitter.js.map +1 -1
- package/build/LocationEventEmitter.web.d.ts +1 -1
- package/build/LocationEventEmitter.web.js +1 -1
- package/build/LocationEventEmitter.web.js.map +1 -1
- package/build/LocationGoogleGeocoding.js +2 -2
- package/build/LocationGoogleGeocoding.js.map +1 -1
- package/build/LocationSubscribers.js +4 -2
- package/build/LocationSubscribers.js.map +1 -1
- package/ios/EXLocation/EXLocation.h +4 -4
- package/ios/EXLocation/EXLocation.m +83 -83
- package/ios/EXLocation/Requesters/EXBaseLocationRequester.h +2 -2
- package/ios/EXLocation/Requesters/EXBaseLocationRequester.m +7 -12
- package/ios/EXLocation/Requesters/EXForegroundPermissionRequester.m +1 -1
- package/ios/EXLocation/TaskConsumers/EXGeofencingTaskConsumer.m +4 -4
- package/ios/EXLocation/TaskConsumers/EXLocationTaskConsumer.m +5 -7
- package/ios/EXLocation.podspec +2 -2
- package/ios/EXLocation.xcframework/Info.plist +5 -5
- package/ios/EXLocation.xcframework/ios-arm64/EXLocation.framework/EXLocation +0 -0
- package/ios/EXLocation.xcframework/ios-arm64/EXLocation.framework/Info.plist +0 -0
- package/ios/EXLocation.xcframework/ios-arm64_x86_64-simulator/EXLocation.framework/EXLocation +0 -0
- package/ios/EXLocation.xcframework/ios-arm64_x86_64-simulator/EXLocation.framework/Info.plist +0 -0
- package/package.json +5 -5
- package/plugin/build/withLocation.d.ts +1 -0
- package/plugin/build/withLocation.js +30 -17
- package/plugin/src/withLocation.ts +40 -15
- package/src/ExpoLocation.ts +1 -1
- package/src/ExpoLocation.web.ts +5 -5
- package/src/GeolocationPolyfill.ts +2 -2
- package/src/Location.ts +40 -4
- package/src/LocationEventEmitter.ts +1 -1
- package/src/LocationEventEmitter.web.ts +1 -1
- package/src/LocationGoogleGeocoding.ts +2 -2
- package/src/LocationSubscribers.ts +1 -1
- package/android/src/main/java/expo/modules/location/utils/TimeoutObject.java +0 -55
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CodedError } from '
|
|
1
|
+
import { CodedError } from 'expo-modules-core';
|
|
2
2
|
const GOOGLE_API_URL = 'https://maps.googleapis.com/maps/api/geocode/json';
|
|
3
3
|
let googleApiKey;
|
|
4
4
|
export function setGoogleApiKey(apiKey) {
|
|
@@ -50,7 +50,7 @@ function assertGoogleApiKey() {
|
|
|
50
50
|
*/
|
|
51
51
|
async function requestGoogleApiAsync(params) {
|
|
52
52
|
const query = Object.entries(params)
|
|
53
|
-
.map(entry => `${entry[0]}=${encodeURI(entry[1])}`)
|
|
53
|
+
.map((entry) => `${entry[0]}=${encodeURI(entry[1])}`)
|
|
54
54
|
.join('&');
|
|
55
55
|
const result = await fetch(`${GOOGLE_API_URL}?key=${googleApiKey}&${query}`);
|
|
56
56
|
return await result.json();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocationGoogleGeocoding.js","sourceRoot":"","sources":["../src/LocationGoogleGeocoding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"LocationGoogleGeocoding.js","sourceRoot":"","sources":["../src/LocationGoogleGeocoding.ts"],"names":[],"mappings":"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","sourcesContent":["import { CodedError } from 'expo-modules-core';\n\nimport { LocationGeocodedAddress, LocationGeocodedLocation } from './Location.types';\n\nconst GOOGLE_API_URL = 'https://maps.googleapis.com/maps/api/geocode/json';\nlet googleApiKey;\n\ntype GoogleApiGeocodingAddressComponent = {\n long_name: string;\n short_name: string;\n types: string[];\n};\n\ntype GoogleApiGeocodingResult = {\n address_components: GoogleApiGeocodingAddressComponent[];\n formatted_address: string;\n geometry: {\n location: {\n lat: number;\n lng: number;\n };\n };\n};\n\ntype GoogleApiGeocodingResponse = {\n results: GoogleApiGeocodingResult[];\n status: string;\n};\n\nexport function setGoogleApiKey(apiKey: string) {\n googleApiKey = apiKey;\n}\n\nexport async function googleGeocodeAsync(address: string): Promise<LocationGeocodedLocation[]> {\n assertGoogleApiKey();\n\n const result = await requestGoogleApiAsync({ address });\n\n if (result.status === 'ZERO_RESULTS') {\n return [];\n }\n assertGeocodeResults(result);\n return result.results.map(geocodingResultToLocation);\n}\n\nexport async function googleReverseGeocodeAsync(options: {\n latitude: number;\n longitude: number;\n}): Promise<LocationGeocodedAddress[]> {\n assertGoogleApiKey();\n\n const result = await requestGoogleApiAsync({\n latlng: `${options.latitude},${options.longitude}`,\n });\n\n if (result.status === 'ZERO_RESULTS') {\n return [];\n }\n assertGeocodeResults(result);\n return result.results.map(reverseGeocodingResultToAddress);\n}\n\n// https://developers.google.com/maps/documentation/geocoding/intro\nfunction assertGeocodeResults(resultObject: any): void {\n const { status, error_message } = resultObject;\n if (status !== 'ZERO_RESULTS' && status !== 'OK') {\n if (error_message) {\n throw new CodedError(status, error_message);\n } else if (status === 'UNKNOWN_ERROR') {\n throw new CodedError(\n status,\n 'the request could not be processed due to a server error. The request may succeed if you try again.'\n );\n }\n throw new CodedError(status, `An error occurred during geocoding.`);\n }\n}\n\n/**\n * Makes sure the Google API key is set.\n */\nfunction assertGoogleApiKey() {\n if (!googleApiKey) {\n throw new Error(\n 'Google API key is required to use geocoding. Please set it using `setGoogleApiKey` method.'\n );\n }\n}\n\n/**\n * Generic and handy method for sending requests to Google Maps API endpoint.\n */\nasync function requestGoogleApiAsync(\n params: { address: string } | { latlng: string }\n): Promise<GoogleApiGeocodingResponse> {\n const query = Object.entries(params)\n .map((entry) => `${entry[0]}=${encodeURI(entry[1])}`)\n .join('&');\n const result = await fetch(`${GOOGLE_API_URL}?key=${googleApiKey}&${query}`);\n return await result.json();\n}\n\n/**\n * Converts Google's result to the location object.\n */\nfunction geocodingResultToLocation(result: GoogleApiGeocodingResult): LocationGeocodedLocation {\n const { location } = result.geometry;\n return {\n latitude: location.lat,\n longitude: location.lng,\n };\n}\n\n/**\n * Converts Google's result to address object.\n */\nfunction reverseGeocodingResultToAddress(\n result: GoogleApiGeocodingResult\n): LocationGeocodedAddress {\n const address: Partial<LocationGeocodedAddress> = {};\n\n for (const { long_name, short_name, types } of result.address_components) {\n if (types.includes('locality')) {\n address.city = long_name;\n continue;\n }\n if (types.includes('sublocality')) {\n address.district = long_name;\n continue;\n }\n if (types.includes('street_address') || types.includes('route')) {\n address.street = long_name;\n continue;\n }\n if (types.includes('administrative_area_level_1')) {\n address.region = long_name;\n continue;\n }\n if (types.includes('administrative_area_level_2')) {\n address.subregion = long_name;\n continue;\n }\n if (types.includes('country')) {\n address.country = long_name;\n address.isoCountryCode = short_name;\n continue;\n }\n if (types.includes('postal_code')) {\n address.postalCode = long_name;\n continue;\n }\n if (types.includes('point_of_interest')) {\n address.name = long_name;\n continue;\n }\n }\n if (!address.name) {\n address.name = result.formatted_address.replace(/,.*$/, '');\n }\n return address as LocationGeocodedAddress;\n}\n"]}
|
|
@@ -2,9 +2,11 @@ import ExpoLocation from './ExpoLocation';
|
|
|
2
2
|
import { LocationEventEmitter } from './LocationEventEmitter';
|
|
3
3
|
let nextWatchId = 0;
|
|
4
4
|
class Subscriber {
|
|
5
|
+
eventName;
|
|
6
|
+
eventDataField;
|
|
7
|
+
callbacks = {};
|
|
8
|
+
eventSubscription = null;
|
|
5
9
|
constructor(eventName, eventDataField) {
|
|
6
|
-
this.callbacks = {};
|
|
7
|
-
this.eventSubscription = null;
|
|
8
10
|
this.eventName = eventName;
|
|
9
11
|
this.eventDataField = eventDataField;
|
|
10
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocationSubscribers.js","sourceRoot":"","sources":["../src/LocationSubscribers.ts"],"names":[],"mappings":"AAEA,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAO9D,IAAI,WAAW,GAAG,CAAC,CAAC;AAEpB,MAAM,UAAU;
|
|
1
|
+
{"version":3,"file":"LocationSubscribers.js","sourceRoot":"","sources":["../src/LocationSubscribers.ts"],"names":[],"mappings":"AAEA,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAO9D,IAAI,WAAW,GAAG,CAAC,CAAC;AAEpB,MAAM,UAAU;IACN,SAAS,CAAS;IAClB,cAAc,CAAS;IACvB,SAAS,GAAmC,EAAE,CAAC;IAC/C,iBAAiB,GAAwB,IAAI,CAAC;IAEtD,YAAY,SAAiB,EAAE,cAAsB;QACnD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACvC,CAAC;IAED,2BAA2B;QACzB,IAAI,IAAI,CAAC,iBAAiB,EAAE;YAC1B,OAAO;SACR;QACD,IAAI,CAAC,iBAAiB,GAAG,oBAAoB,CAAC,WAAW,CACvD,IAAI,CAAC,SAAS,EACd,CAAC,KAAkB,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAC5C,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,QAAsB;QACrC,IAAI,CAAC,2BAA2B,EAAE,CAAC;QACnC,MAAM,EAAE,GAAG,EAAE,WAAW,CAAC;QACzB,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC;QAC9B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,EAAU;QAC3B,2DAA2D;QAC3D,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE;YACvB,OAAO;SACR;QAED,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC1B,YAAY,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAElC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,iBAAiB,EAAE;YACtE,oBAAoB,CAAC,kBAAkB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAChE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;SAC/B;IACH,CAAC;IAED,OAAO,CAAC,KAAkB;QACxB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAEzC,IAAI,QAAQ,EAAE;YACZ,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;SACtC;aAAM;YACL,YAAY,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;SACxC;IACH,CAAC;CACF;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,UAAU,CAC9C,sBAAsB,EACtB,UAAU,CACX,CAAC;AACF,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,UAAU,CAC7C,qBAAqB,EACrB,SAAS,CACV,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,WAAW,CAAC;AACrB,CAAC","sourcesContent":["import { Subscription } from 'expo-modules-core';\n\nimport ExpoLocation from './ExpoLocation';\nimport { LocationCallback, LocationHeadingCallback } from './Location.types';\nimport { LocationEventEmitter } from './LocationEventEmitter';\n\ntype EventObject = {\n watchId: number;\n [key: string]: any;\n};\n\nlet nextWatchId = 0;\n\nclass Subscriber<CallbackType extends LocationCallback | LocationHeadingCallback> {\n private eventName: string;\n private eventDataField: string;\n private callbacks: { [id: string]: CallbackType } = {};\n private eventSubscription: Subscription | null = null;\n\n constructor(eventName: string, eventDataField: string) {\n this.eventName = eventName;\n this.eventDataField = eventDataField;\n }\n\n maybeInitializeSubscription() {\n if (this.eventSubscription) {\n return;\n }\n this.eventSubscription = LocationEventEmitter.addListener(\n this.eventName,\n (event: EventObject) => this.trigger(event)\n );\n }\n\n /**\n * Registers given callback under new id which is then returned.\n */\n registerCallback(callback: CallbackType): number {\n this.maybeInitializeSubscription();\n const id = ++nextWatchId;\n this.callbacks[id] = callback;\n return id;\n }\n\n /**\n * Unregisters a callback with given id and revokes the subscription if possible.\n */\n unregisterCallback(id: number): void {\n // Do nothing if we have already unregistered the callback.\n if (!this.callbacks[id]) {\n return;\n }\n\n delete this.callbacks[id];\n ExpoLocation.removeWatchAsync(id);\n\n if (Object.keys(this.callbacks).length === 0 && this.eventSubscription) {\n LocationEventEmitter.removeSubscription(this.eventSubscription);\n this.eventSubscription = null;\n }\n }\n\n trigger(event: EventObject): void {\n const watchId = event.watchId;\n const callback = this.callbacks[watchId];\n\n if (callback) {\n callback(event[this.eventDataField]);\n } else {\n ExpoLocation.removeWatchAsync(watchId);\n }\n }\n}\n\nexport const LocationSubscriber = new Subscriber<LocationCallback>(\n 'Expo.locationChanged',\n 'location'\n);\nexport const HeadingSubscriber = new Subscriber<LocationHeadingCallback>(\n 'Expo.headingChanged',\n 'heading'\n);\n\n/**\n * Necessary for some unit tests.\n */\nexport function _getCurrentWatchId(): number {\n return nextWatchId;\n}\n"]}
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
#import <CoreLocation/CLLocation.h>
|
|
4
4
|
#import <CoreLocation/CLLocationManager.h>
|
|
5
5
|
|
|
6
|
-
#import <
|
|
7
|
-
#import <
|
|
8
|
-
#import <
|
|
6
|
+
#import <ExpoModulesCore/EXEventEmitter.h>
|
|
7
|
+
#import <ExpoModulesCore/EXExportedModule.h>
|
|
8
|
+
#import <ExpoModulesCore/EXModuleRegistryConsumer.h>
|
|
9
9
|
|
|
10
10
|
// Location accuracies
|
|
11
11
|
typedef NS_ENUM(NSUInteger, EXLocationAccuracy) {
|
|
@@ -30,7 +30,7 @@ typedef NS_ENUM(NSUInteger, EXGeofencingRegionState) {
|
|
|
30
30
|
EXGeofencingRegionStateOutside = 2,
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
@interface EXLocation :
|
|
33
|
+
@interface EXLocation : EXExportedModule <EXEventEmitter, EXModuleRegistryConsumer>
|
|
34
34
|
|
|
35
35
|
+ (NSDictionary *)exportLocation:(CLLocation *)location;
|
|
36
36
|
+ (CLLocationAccuracy)CLLocationAccuracyFromOption:(EXLocationAccuracy)accuracy;
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
#import <CoreLocation/CLError.h>
|
|
17
17
|
#import <CoreLocation/CLCircularRegion.h>
|
|
18
18
|
|
|
19
|
-
#import <
|
|
19
|
+
#import <ExpoModulesCore/EXEventEmitterService.h>
|
|
20
20
|
|
|
21
21
|
#import <ExpoModulesCore/EXPermissionsInterface.h>
|
|
22
22
|
#import <ExpoModulesCore/EXPermissionsMethodsDelegate.h>
|
|
@@ -32,7 +32,7 @@ NSString * const EXHeadingChangedEventName = @"Expo.headingChanged";
|
|
|
32
32
|
|
|
33
33
|
@property (nonatomic, strong) NSMutableDictionary<NSNumber *, EXLocationDelegate*> *delegates;
|
|
34
34
|
@property (nonatomic, strong) NSMutableSet<EXLocationDelegate *> *retainedDelegates;
|
|
35
|
-
@property (nonatomic, weak) id<
|
|
35
|
+
@property (nonatomic, weak) id<EXEventEmitterService> eventEmitter;
|
|
36
36
|
@property (nonatomic, weak) id<EXPermissionsInterface> permissionsManager;
|
|
37
37
|
@property (nonatomic, weak) id<UMTaskManagerInterface> tasksManager;
|
|
38
38
|
|
|
@@ -40,7 +40,7 @@ NSString * const EXHeadingChangedEventName = @"Expo.headingChanged";
|
|
|
40
40
|
|
|
41
41
|
@implementation EXLocation
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
EX_EXPORT_MODULE(ExpoLocation);
|
|
44
44
|
|
|
45
45
|
- (instancetype)init
|
|
46
46
|
{
|
|
@@ -51,9 +51,9 @@ UM_EXPORT_MODULE(ExpoLocation);
|
|
|
51
51
|
return self;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
- (void)setModuleRegistry:(
|
|
54
|
+
- (void)setModuleRegistry:(EXModuleRegistry *)moduleRegistry
|
|
55
55
|
{
|
|
56
|
-
_eventEmitter = [moduleRegistry getModuleImplementingProtocol:@protocol(
|
|
56
|
+
_eventEmitter = [moduleRegistry getModuleImplementingProtocol:@protocol(EXEventEmitterService)];
|
|
57
57
|
_tasksManager = [moduleRegistry getModuleImplementingProtocol:@protocol(UMTaskManagerInterface)];
|
|
58
58
|
|
|
59
59
|
_permissionsManager = [moduleRegistry getModuleImplementingProtocol:@protocol(EXPermissionsInterface)];
|
|
@@ -70,7 +70,7 @@ UM_EXPORT_MODULE(ExpoLocation);
|
|
|
70
70
|
return dispatch_get_main_queue();
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
# pragma mark -
|
|
73
|
+
# pragma mark - EXEventEmitter
|
|
74
74
|
|
|
75
75
|
- (NSArray<NSString *> *)supportedEvents
|
|
76
76
|
{
|
|
@@ -82,9 +82,9 @@ UM_EXPORT_MODULE(ExpoLocation);
|
|
|
82
82
|
|
|
83
83
|
# pragma mark - Exported methods
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
resolver:(
|
|
87
|
-
rejecter:(
|
|
85
|
+
EX_EXPORT_METHOD_AS(getProviderStatusAsync,
|
|
86
|
+
resolver:(EXPromiseResolveBlock)resolve
|
|
87
|
+
rejecter:(EXPromiseRejectBlock)reject)
|
|
88
88
|
{
|
|
89
89
|
resolve(@{
|
|
90
90
|
@"locationServicesEnabled": @([CLLocationManager locationServicesEnabled]),
|
|
@@ -93,10 +93,10 @@ UM_EXPORT_METHOD_AS(getProviderStatusAsync,
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
EX_EXPORT_METHOD_AS(getCurrentPositionAsync,
|
|
97
97
|
options:(NSDictionary *)options
|
|
98
|
-
resolver:(
|
|
99
|
-
rejecter:(
|
|
98
|
+
resolver:(EXPromiseResolveBlock)resolve
|
|
99
|
+
rejecter:(EXPromiseRejectBlock)reject)
|
|
100
100
|
{
|
|
101
101
|
if (![self checkForegroundPermissions:reject]) {
|
|
102
102
|
return;
|
|
@@ -128,11 +128,11 @@ UM_EXPORT_METHOD_AS(getCurrentPositionAsync,
|
|
|
128
128
|
[locMgr requestLocation];
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
EX_EXPORT_METHOD_AS(watchPositionImplAsync,
|
|
132
132
|
watchId:(nonnull NSNumber *)watchId
|
|
133
133
|
options:(NSDictionary *)options
|
|
134
|
-
resolver:(
|
|
135
|
-
rejecter:(
|
|
134
|
+
resolver:(EXPromiseResolveBlock)resolve
|
|
135
|
+
rejecter:(EXPromiseRejectBlock)reject)
|
|
136
136
|
{
|
|
137
137
|
if (![self checkForegroundPermissions:reject]) {
|
|
138
138
|
return;
|
|
@@ -167,10 +167,10 @@ UM_EXPORT_METHOD_AS(watchPositionImplAsync,
|
|
|
167
167
|
resolve([NSNull null]);
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
|
|
170
|
+
EX_EXPORT_METHOD_AS(getLastKnownPositionAsync,
|
|
171
171
|
getLastKnownPositionWithOptions:(NSDictionary *)options
|
|
172
|
-
resolve:(
|
|
173
|
-
rejecter:(
|
|
172
|
+
resolve:(EXPromiseResolveBlock)resolve
|
|
173
|
+
rejecter:(EXPromiseRejectBlock)reject)
|
|
174
174
|
{
|
|
175
175
|
if (![self checkForegroundPermissions:reject]) {
|
|
176
176
|
return;
|
|
@@ -185,10 +185,10 @@ UM_EXPORT_METHOD_AS(getLastKnownPositionAsync,
|
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
// Watch method for getting compass updates
|
|
188
|
-
|
|
188
|
+
EX_EXPORT_METHOD_AS(watchDeviceHeading,
|
|
189
189
|
watchHeadingWithWatchId:(nonnull NSNumber *)watchId
|
|
190
|
-
resolve:(
|
|
191
|
-
reject:(
|
|
190
|
+
resolve:(EXPromiseResolveBlock)resolve
|
|
191
|
+
reject:(EXPromiseRejectBlock)reject) {
|
|
192
192
|
if (![self checkForegroundPermissions:reject]) {
|
|
193
193
|
return;
|
|
194
194
|
}
|
|
@@ -235,10 +235,10 @@ UM_EXPORT_METHOD_AS(watchDeviceHeading,
|
|
|
235
235
|
resolve([NSNull null]);
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
|
|
238
|
+
EX_EXPORT_METHOD_AS(removeWatchAsync,
|
|
239
239
|
watchId:(nonnull NSNumber *)watchId
|
|
240
|
-
resolver:(
|
|
241
|
-
rejecter:(
|
|
240
|
+
resolver:(EXPromiseResolveBlock)resolve
|
|
241
|
+
rejecter:(EXPromiseRejectBlock)reject)
|
|
242
242
|
{
|
|
243
243
|
EXLocationDelegate *delegate = _delegates[watchId];
|
|
244
244
|
|
|
@@ -252,10 +252,10 @@ UM_EXPORT_METHOD_AS(removeWatchAsync,
|
|
|
252
252
|
resolve([NSNull null]);
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
|
|
255
|
+
EX_EXPORT_METHOD_AS(geocodeAsync,
|
|
256
256
|
address:(nonnull NSString *)address
|
|
257
|
-
resolver:(
|
|
258
|
-
rejecter:(
|
|
257
|
+
resolver:(EXPromiseResolveBlock)resolve
|
|
258
|
+
rejecter:(EXPromiseRejectBlock)reject)
|
|
259
259
|
{
|
|
260
260
|
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
|
|
261
261
|
|
|
@@ -282,10 +282,10 @@ UM_EXPORT_METHOD_AS(geocodeAsync,
|
|
|
282
282
|
}];
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
-
|
|
285
|
+
EX_EXPORT_METHOD_AS(reverseGeocodeAsync,
|
|
286
286
|
locationMap:(nonnull NSDictionary *)locationMap
|
|
287
|
-
resolver:(
|
|
288
|
-
rejecter:(
|
|
287
|
+
resolver:(EXPromiseResolveBlock)resolve
|
|
288
|
+
rejecter:(EXPromiseRejectBlock)reject)
|
|
289
289
|
{
|
|
290
290
|
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
|
|
291
291
|
CLLocation *location = [[CLLocation alloc] initWithLatitude:[locationMap[@"latitude"] floatValue] longitude:[locationMap[@"longitude"] floatValue]];
|
|
@@ -295,16 +295,16 @@ UM_EXPORT_METHOD_AS(reverseGeocodeAsync,
|
|
|
295
295
|
NSMutableArray *results = [NSMutableArray arrayWithCapacity:placemarks.count];
|
|
296
296
|
for (CLPlacemark* placemark in placemarks) {
|
|
297
297
|
NSDictionary *address = @{
|
|
298
|
-
@"city":
|
|
299
|
-
@"district":
|
|
300
|
-
@"street":
|
|
301
|
-
@"region":
|
|
302
|
-
@"subregion":
|
|
303
|
-
@"country":
|
|
304
|
-
@"postalCode":
|
|
305
|
-
@"name":
|
|
306
|
-
@"isoCountryCode":
|
|
307
|
-
@"timezone":
|
|
298
|
+
@"city": EXNullIfNil(placemark.locality),
|
|
299
|
+
@"district": EXNullIfNil(placemark.subLocality),
|
|
300
|
+
@"street": EXNullIfNil(placemark.thoroughfare),
|
|
301
|
+
@"region": EXNullIfNil(placemark.administrativeArea),
|
|
302
|
+
@"subregion": EXNullIfNil(placemark.subAdministrativeArea),
|
|
303
|
+
@"country": EXNullIfNil(placemark.country),
|
|
304
|
+
@"postalCode": EXNullIfNil(placemark.postalCode),
|
|
305
|
+
@"name": EXNullIfNil(placemark.name),
|
|
306
|
+
@"isoCountryCode": EXNullIfNil(placemark.ISOcountryCode),
|
|
307
|
+
@"timezone": EXNullIfNil(placemark.timeZone.name),
|
|
308
308
|
};
|
|
309
309
|
[results addObject:address];
|
|
310
310
|
}
|
|
@@ -319,9 +319,9 @@ UM_EXPORT_METHOD_AS(reverseGeocodeAsync,
|
|
|
319
319
|
}];
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
-
|
|
323
|
-
getPermissionsAsync:(
|
|
324
|
-
rejecter:(
|
|
322
|
+
EX_EXPORT_METHOD_AS(getPermissionsAsync,
|
|
323
|
+
getPermissionsAsync:(EXPromiseResolveBlock)resolve
|
|
324
|
+
rejecter:(EXPromiseRejectBlock)reject)
|
|
325
325
|
{
|
|
326
326
|
[EXPermissionsMethodsDelegate getPermissionWithPermissionsManager:_permissionsManager
|
|
327
327
|
withRequester:[EXLocationPermissionRequester class]
|
|
@@ -329,9 +329,9 @@ UM_EXPORT_METHOD_AS(getPermissionsAsync,
|
|
|
329
329
|
reject:reject];
|
|
330
330
|
}
|
|
331
331
|
|
|
332
|
-
|
|
333
|
-
requestPermissionsAsync:(
|
|
334
|
-
rejecter:(
|
|
332
|
+
EX_EXPORT_METHOD_AS(requestPermissionsAsync,
|
|
333
|
+
requestPermissionsAsync:(EXPromiseResolveBlock)resolve
|
|
334
|
+
rejecter:(EXPromiseRejectBlock)reject)
|
|
335
335
|
{
|
|
336
336
|
[EXPermissionsMethodsDelegate askForPermissionWithPermissionsManager:_permissionsManager
|
|
337
337
|
withRequester:[EXLocationPermissionRequester class]
|
|
@@ -339,9 +339,9 @@ UM_EXPORT_METHOD_AS(requestPermissionsAsync,
|
|
|
339
339
|
reject:reject];
|
|
340
340
|
}
|
|
341
341
|
|
|
342
|
-
|
|
343
|
-
getForegroundPermissionsAsync:(
|
|
344
|
-
rejecter:(
|
|
342
|
+
EX_EXPORT_METHOD_AS(getForegroundPermissionsAsync,
|
|
343
|
+
getForegroundPermissionsAsync:(EXPromiseResolveBlock)resolve
|
|
344
|
+
rejecter:(EXPromiseRejectBlock)reject)
|
|
345
345
|
{
|
|
346
346
|
[EXPermissionsMethodsDelegate getPermissionWithPermissionsManager:_permissionsManager
|
|
347
347
|
withRequester:[EXForegroundPermissionRequester class]
|
|
@@ -349,9 +349,9 @@ UM_EXPORT_METHOD_AS(getForegroundPermissionsAsync,
|
|
|
349
349
|
reject:reject];
|
|
350
350
|
}
|
|
351
351
|
|
|
352
|
-
|
|
353
|
-
requestForegroundPermissionsAsync:(
|
|
354
|
-
rejecter:(
|
|
352
|
+
EX_EXPORT_METHOD_AS(requestForegroundPermissionsAsync,
|
|
353
|
+
requestForegroundPermissionsAsync:(EXPromiseResolveBlock)resolve
|
|
354
|
+
rejecter:(EXPromiseRejectBlock)reject)
|
|
355
355
|
{
|
|
356
356
|
[EXPermissionsMethodsDelegate askForPermissionWithPermissionsManager:_permissionsManager
|
|
357
357
|
withRequester:[EXForegroundPermissionRequester class]
|
|
@@ -359,9 +359,9 @@ UM_EXPORT_METHOD_AS(requestForegroundPermissionsAsync,
|
|
|
359
359
|
reject:reject];
|
|
360
360
|
}
|
|
361
361
|
|
|
362
|
-
|
|
363
|
-
getBackgroundPermissionsAsync:(
|
|
364
|
-
rejecter:(
|
|
362
|
+
EX_EXPORT_METHOD_AS(getBackgroundPermissionsAsync,
|
|
363
|
+
getBackgroundPermissionsAsync:(EXPromiseResolveBlock)resolve
|
|
364
|
+
rejecter:(EXPromiseRejectBlock)reject)
|
|
365
365
|
{
|
|
366
366
|
[EXPermissionsMethodsDelegate getPermissionWithPermissionsManager:_permissionsManager
|
|
367
367
|
withRequester:[EXBackgroundLocationPermissionRequester class]
|
|
@@ -369,9 +369,9 @@ UM_EXPORT_METHOD_AS(getBackgroundPermissionsAsync,
|
|
|
369
369
|
reject:reject];
|
|
370
370
|
}
|
|
371
371
|
|
|
372
|
-
|
|
373
|
-
requestBackgroundPermissionsAsync:(
|
|
374
|
-
rejecter:(
|
|
372
|
+
EX_EXPORT_METHOD_AS(requestBackgroundPermissionsAsync,
|
|
373
|
+
requestBackgroundPermissionsAsync:(EXPromiseResolveBlock)resolve
|
|
374
|
+
rejecter:(EXPromiseRejectBlock)reject)
|
|
375
375
|
{
|
|
376
376
|
[EXPermissionsMethodsDelegate askForPermissionWithPermissionsManager:_permissionsManager
|
|
377
377
|
withRequester:[EXBackgroundLocationPermissionRequester class]
|
|
@@ -379,9 +379,9 @@ UM_EXPORT_METHOD_AS(requestBackgroundPermissionsAsync,
|
|
|
379
379
|
reject:reject];
|
|
380
380
|
}
|
|
381
381
|
|
|
382
|
-
|
|
383
|
-
hasServicesEnabled:(
|
|
384
|
-
reject:(
|
|
382
|
+
EX_EXPORT_METHOD_AS(hasServicesEnabledAsync,
|
|
383
|
+
hasServicesEnabled:(EXPromiseResolveBlock)resolve
|
|
384
|
+
reject:(EXPromiseRejectBlock)reject)
|
|
385
385
|
{
|
|
386
386
|
BOOL servicesEnabled = [CLLocationManager locationServicesEnabled];
|
|
387
387
|
resolve(@(servicesEnabled));
|
|
@@ -389,11 +389,11 @@ UM_EXPORT_METHOD_AS(hasServicesEnabledAsync,
|
|
|
389
389
|
|
|
390
390
|
# pragma mark - Background location
|
|
391
391
|
|
|
392
|
-
|
|
392
|
+
EX_EXPORT_METHOD_AS(startLocationUpdatesAsync,
|
|
393
393
|
startLocationUpdatesForTaskWithName:(nonnull NSString *)taskName
|
|
394
394
|
withOptions:(nonnull NSDictionary *)options
|
|
395
|
-
resolve:(
|
|
396
|
-
reject:(
|
|
395
|
+
resolve:(EXPromiseResolveBlock)resolve
|
|
396
|
+
reject:(EXPromiseRejectBlock)reject)
|
|
397
397
|
{
|
|
398
398
|
// There are two ways of starting this service.
|
|
399
399
|
// 1. As a background location service, this requires the background location permission.
|
|
@@ -416,10 +416,10 @@ UM_EXPORT_METHOD_AS(startLocationUpdatesAsync,
|
|
|
416
416
|
resolve(nil);
|
|
417
417
|
}
|
|
418
418
|
|
|
419
|
-
|
|
419
|
+
EX_EXPORT_METHOD_AS(stopLocationUpdatesAsync,
|
|
420
420
|
stopLocationUpdatesForTaskWithName:(NSString *)taskName
|
|
421
|
-
resolve:(
|
|
422
|
-
reject:(
|
|
421
|
+
resolve:(EXPromiseResolveBlock)resolve
|
|
422
|
+
reject:(EXPromiseRejectBlock)reject)
|
|
423
423
|
{
|
|
424
424
|
if (![self checkTaskManagerExists:reject]) {
|
|
425
425
|
return;
|
|
@@ -433,10 +433,10 @@ UM_EXPORT_METHOD_AS(stopLocationUpdatesAsync,
|
|
|
433
433
|
resolve(nil);
|
|
434
434
|
}
|
|
435
435
|
|
|
436
|
-
|
|
436
|
+
EX_EXPORT_METHOD_AS(hasStartedLocationUpdatesAsync,
|
|
437
437
|
hasStartedLocationUpdatesForTaskWithName:(nonnull NSString *)taskName
|
|
438
|
-
resolve:(
|
|
439
|
-
reject:(
|
|
438
|
+
resolve:(EXPromiseResolveBlock)resolve
|
|
439
|
+
reject:(EXPromiseRejectBlock)reject)
|
|
440
440
|
{
|
|
441
441
|
if (![self checkTaskManagerExists:reject]) {
|
|
442
442
|
return;
|
|
@@ -447,11 +447,11 @@ UM_EXPORT_METHOD_AS(hasStartedLocationUpdatesAsync,
|
|
|
447
447
|
|
|
448
448
|
# pragma mark - Geofencing
|
|
449
449
|
|
|
450
|
-
|
|
450
|
+
EX_EXPORT_METHOD_AS(startGeofencingAsync,
|
|
451
451
|
startGeofencingWithTaskName:(nonnull NSString *)taskName
|
|
452
452
|
withOptions:(nonnull NSDictionary *)options
|
|
453
|
-
resolve:(
|
|
454
|
-
reject:(
|
|
453
|
+
resolve:(EXPromiseResolveBlock)resolve
|
|
454
|
+
reject:(EXPromiseRejectBlock)reject)
|
|
455
455
|
{
|
|
456
456
|
if (![self checkBackgroundPermissions:reject] || ![self checkTaskManagerExists:reject]) {
|
|
457
457
|
return;
|
|
@@ -468,10 +468,10 @@ UM_EXPORT_METHOD_AS(startGeofencingAsync,
|
|
|
468
468
|
resolve(nil);
|
|
469
469
|
}
|
|
470
470
|
|
|
471
|
-
|
|
471
|
+
EX_EXPORT_METHOD_AS(stopGeofencingAsync,
|
|
472
472
|
stopGeofencingWithTaskName:(nonnull NSString *)taskName
|
|
473
|
-
resolve:(
|
|
474
|
-
reject:(
|
|
473
|
+
resolve:(EXPromiseResolveBlock)resolve
|
|
474
|
+
reject:(EXPromiseRejectBlock)reject)
|
|
475
475
|
{
|
|
476
476
|
if (![self checkTaskManagerExists:reject]) {
|
|
477
477
|
return;
|
|
@@ -485,10 +485,10 @@ UM_EXPORT_METHOD_AS(stopGeofencingAsync,
|
|
|
485
485
|
resolve(nil);
|
|
486
486
|
}
|
|
487
487
|
|
|
488
|
-
|
|
488
|
+
EX_EXPORT_METHOD_AS(hasStartedGeofencingAsync,
|
|
489
489
|
hasStartedGeofencingForTaskWithName:(NSString *)taskName
|
|
490
|
-
resolve:(
|
|
491
|
-
reject:(
|
|
490
|
+
resolve:(EXPromiseResolveBlock)resolve
|
|
491
|
+
reject:(EXPromiseRejectBlock)reject)
|
|
492
492
|
{
|
|
493
493
|
if (![self checkTaskManagerExists:reject]) {
|
|
494
494
|
return;
|
|
@@ -515,7 +515,7 @@ UM_EXPORT_METHOD_AS(hasStartedGeofencingAsync,
|
|
|
515
515
|
return locMgr;
|
|
516
516
|
}
|
|
517
517
|
|
|
518
|
-
- (BOOL)checkForegroundPermissions:(
|
|
518
|
+
- (BOOL)checkForegroundPermissions:(EXPromiseRejectBlock)reject
|
|
519
519
|
{
|
|
520
520
|
if (![CLLocationManager locationServicesEnabled]) {
|
|
521
521
|
reject(@"E_LOCATION_SERVICES_DISABLED", @"Location services are disabled", nil);
|
|
@@ -528,7 +528,7 @@ UM_EXPORT_METHOD_AS(hasStartedGeofencingAsync,
|
|
|
528
528
|
return YES;
|
|
529
529
|
}
|
|
530
530
|
|
|
531
|
-
- (BOOL)checkBackgroundPermissions:(
|
|
531
|
+
- (BOOL)checkBackgroundPermissions:(EXPromiseRejectBlock)reject
|
|
532
532
|
{
|
|
533
533
|
if (![CLLocationManager locationServicesEnabled]) {
|
|
534
534
|
reject(@"E_LOCATION_SERVICES_DISABLED", @"Location services are disabled", nil);
|
|
@@ -541,7 +541,7 @@ UM_EXPORT_METHOD_AS(hasStartedGeofencingAsync,
|
|
|
541
541
|
return YES;
|
|
542
542
|
}
|
|
543
543
|
|
|
544
|
-
- (BOOL)checkTaskManagerExists:(
|
|
544
|
+
- (BOOL)checkTaskManagerExists:(EXPromiseRejectBlock)reject
|
|
545
545
|
{
|
|
546
546
|
if (_tasksManager == nil) {
|
|
547
547
|
reject(@"E_TASKMANAGER_NOT_FOUND", @"`expo-task-manager` module is required to use background services.", nil);
|
|
@@ -550,7 +550,7 @@ UM_EXPORT_METHOD_AS(hasStartedGeofencingAsync,
|
|
|
550
550
|
return YES;
|
|
551
551
|
}
|
|
552
552
|
|
|
553
|
-
- (BOOL)checkBackgroundServices:(
|
|
553
|
+
- (BOOL)checkBackgroundServices:(EXPromiseRejectBlock)reject
|
|
554
554
|
{
|
|
555
555
|
if (![_tasksManager hasBackgroundModeEnabled:@"location"]) {
|
|
556
556
|
reject(@"E_BACKGROUND_SERVICES_DISABLED", @"Background Location has not been configured. To enable it, add `location` to `UIBackgroundModes` in Info.plist file.", nil);
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
@interface EXBaseLocationRequester : NSObject<EXPermissionsRequester>
|
|
8
8
|
|
|
9
9
|
@property (nonatomic, strong) CLLocationManager *locationManager;
|
|
10
|
-
@property (nonatomic, strong)
|
|
11
|
-
@property (nonatomic, strong)
|
|
10
|
+
@property (nonatomic, strong) EXPromiseResolveBlock resolve;
|
|
11
|
+
@property (nonatomic, strong) EXPromiseRejectBlock reject;
|
|
12
12
|
|
|
13
13
|
+ (BOOL)isConfiguredForWhenInUseAuthorization;
|
|
14
14
|
+ (BOOL)isConfiguredForAlwaysAuthorization;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright 2016-present 650 Industries. All rights reserved.
|
|
2
2
|
|
|
3
3
|
#import <EXLocation/EXBaseLocationRequester.h>
|
|
4
|
-
#import <
|
|
4
|
+
#import <ExpoModulesCore/EXUtilities.h>
|
|
5
5
|
|
|
6
6
|
#import <objc/message.h>
|
|
7
7
|
#import <CoreLocation/CLLocationManagerDelegate.h>
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
|
|
38
38
|
CLAuthorizationStatus systemStatus;
|
|
39
39
|
if (![EXBaseLocationRequester isConfiguredForAlwaysAuthorization] && ![EXBaseLocationRequester isConfiguredForWhenInUseAuthorization]) {
|
|
40
|
-
|
|
40
|
+
EXFatal(EXErrorWithMessage(@"This app is missing usage descriptions, so location services will fail. Add one of the `NSLocation*UsageDescription` keys to your bundle's Info.plist. See https://bit.ly/2P5fEbG (https://docs.expo.io/versions/latest/guides/app-stores.html#system-permissions-dialogs-on-ios) for more information."));
|
|
41
41
|
systemStatus = kCLAuthorizationStatusDenied;
|
|
42
42
|
} else {
|
|
43
43
|
systemStatus = [CLLocationManager authorizationStatus];
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
return [self parsePermissions:systemStatus];
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
- (void)requestPermissionsWithResolver:(
|
|
49
|
+
- (void)requestPermissionsWithResolver:(EXPromiseResolveBlock)resolve rejecter:(EXPromiseRejectBlock)reject {
|
|
50
50
|
NSDictionary *existingPermissions = [self getPermissions];
|
|
51
51
|
if (existingPermissions && [existingPermissions[@"status"] intValue] != EXPermissionStatusUndetermined) {
|
|
52
52
|
// since permissions are already determined, the iOS request methods will be no-ops.
|
|
@@ -56,9 +56,9 @@
|
|
|
56
56
|
_resolve = resolve;
|
|
57
57
|
_reject = reject;
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
[
|
|
61
|
-
|
|
59
|
+
EX_WEAKIFY(self)
|
|
60
|
+
[EXUtilities performSynchronouslyOnMainThread:^{
|
|
61
|
+
EX_ENSURE_STRONGIFY(self)
|
|
62
62
|
self.locationManagerWasCalled = false;
|
|
63
63
|
self.locationManager = [[CLLocationManager alloc] init];
|
|
64
64
|
self.locationManager.delegate = self;
|
|
@@ -157,12 +157,7 @@
|
|
|
157
157
|
|
|
158
158
|
+ (BOOL)isConfiguredForAlwaysAuthorization
|
|
159
159
|
{
|
|
160
|
-
|
|
161
|
-
return [self isConfiguredForWhenInUseAuthorization] && [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysAndWhenInUseUsageDescription"];
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// iOS 10 fallback
|
|
165
|
-
return [self isConfiguredForWhenInUseAuthorization] && [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"];
|
|
160
|
+
return [self isConfiguredForWhenInUseAuthorization] && [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysAndWhenInUseUsageDescription"];
|
|
166
161
|
}
|
|
167
162
|
|
|
168
163
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright 2016-present 650 Industries. All rights reserved.
|
|
2
2
|
|
|
3
3
|
#import <EXLocation/EXForegroundPermissionRequester.h>
|
|
4
|
-
#import <
|
|
4
|
+
#import <ExpoModulesCore/EXUtilities.h>
|
|
5
5
|
|
|
6
6
|
#import <objc/message.h>
|
|
7
7
|
#import <CoreLocation/CLLocationManagerDelegate.h>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
#import <CoreLocation/CLLocationManager.h>
|
|
5
5
|
#import <CoreLocation/CLErrorDomain.h>
|
|
6
6
|
|
|
7
|
-
#import <
|
|
7
|
+
#import <ExpoModulesCore/EXUtilities.h>
|
|
8
8
|
#import <EXLocation/EXLocation.h>
|
|
9
9
|
#import <EXLocation/EXGeofencingTaskConsumer.h>
|
|
10
10
|
#import <UMTaskManagerInterface/UMTaskInterface.h>
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
- (void)reset
|
|
53
53
|
{
|
|
54
54
|
[self stopMonitoringAllRegions];
|
|
55
|
-
[
|
|
55
|
+
[EXUtilities performSynchronouslyOnMainThread:^{
|
|
56
56
|
self->_locationManager = nil;
|
|
57
57
|
self->_task = nil;
|
|
58
58
|
}];
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
|
|
61
61
|
- (void)startMonitoringRegionsForTask:(id<UMTaskInterface>)task
|
|
62
62
|
{
|
|
63
|
-
[
|
|
63
|
+
[EXUtilities performSynchronouslyOnMainThread:^{
|
|
64
64
|
CLLocationManager *locationManager = [CLLocationManager new];
|
|
65
65
|
NSMutableDictionary *regionStates = [NSMutableDictionary new];
|
|
66
66
|
NSDictionary *options = [task options];
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
|
|
96
96
|
- (void)stopMonitoringAllRegions
|
|
97
97
|
{
|
|
98
|
-
[
|
|
98
|
+
[EXUtilities performSynchronouslyOnMainThread:^{
|
|
99
99
|
for (CLRegion *region in self->_locationManager.monitoredRegions) {
|
|
100
100
|
[self->_locationManager stopMonitoringForRegion:region];
|
|
101
101
|
}
|