diff --git a/API.md b/API.md index f472cc3..e35ce01 100644 --- a/API.md +++ b/API.md @@ -325,6 +325,9 @@ There are 3 main methods for interacting with the offline API: Before using them, don't forget to set an access token with `Mapbox.setAccessToken(accessToken)` +These methods return a promise, but they also accept a callback as the last +argument with the signature `(err, value) => {}`. + #### Creating a pack ```javascript @@ -341,6 +344,10 @@ Mapbox.addOfflinePack({ minZoomLevel: 10, // required maxZoomLevel: 13, // required styleURL: Mapbox.mapStyles.emerald // required. Valid styleURL +}).then(() => { + // Called after the pack has been added successfully +}).catch(err => { + console.error(err); // Handle error }); ``` @@ -349,29 +356,29 @@ Mapbox.addOfflinePack({ To delete a pack, provide the `name` of the pack to delete. ```javascript -Mapbox.removeOfflinePack('test', (err, info)=> { - if (err) { - console.error(err.message); - return; - } - if (info) { - console.log('Deleted', info.deleted); +Mapbox.removeOfflinePack('test') + .then(info => { + if (info.deleted) { + console.log(`Deleted pack named ${info.deleted}`); // The pack has been deleted successfully } else { - console.log('No packs to delete'); // There are no packs named 'test' + console.log('No packs to delete'); // There are no packs named 'test' } -}); + }) + .catch(err => { + console.error(err); // Handle error + }); ``` #### Querying progress ```javascript -Mapbox.getOfflinePacks((err, packs) => { - if (err) { - console.error(err.message); - return; - } - // packs is an array of progress objects -}); +Mapbox.getOfflinePacks() + .then(packs => { + // packs is an array of progress objects + }) + .catch(err => { + console.log(err); // Handle error + }) ``` A progress object has the following shape: diff --git a/android/src/main/java/com/mapbox/reactnativemapboxgl/ReactNativeMapboxGLModule.java b/android/src/main/java/com/mapbox/reactnativemapboxgl/ReactNativeMapboxGLModule.java index d7d4154..d02e509 100644 --- a/android/src/main/java/com/mapbox/reactnativemapboxgl/ReactNativeMapboxGLModule.java +++ b/android/src/main/java/com/mapbox/reactnativemapboxgl/ReactNativeMapboxGLModule.java @@ -13,6 +13,7 @@ import com.facebook.common.logging.FLog; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.JSApplicationIllegalArgumentException; +import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; @@ -108,6 +109,8 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule { return constants; } + // Access Token + @ReactMethod public void setAccessToken(String accessToken) { if (accessToken == null || accessToken.length() == 0 || accessToken.equals("your-mapbox.com-access-token")) { @@ -123,8 +126,28 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule { MapboxAccountManager.start(context, accessToken); } + // Metrics + @ReactMethod public void setMetricsEnabled(boolean value) { MapboxEventManager.getMapboxEventManager().setTelemetryEnabled(value); } + + // Offline packs + + @ReactMethod + public void getPacks(Promise promise) { + WritableArray result = Arguments.createArray(); + promise.resolve(result); + } + + @ReactMethod + public void addPackForRegion(ReadableMap options, Promise promise) { + promise.reject(new JSApplicationIllegalArgumentException("Mapbox.addOfflinePackForRegion not implemented on Android yet")); + } + + @ReactMethod + public void removePack(String packName, Promise promise) { + promise.reject(new JSApplicationIllegalArgumentException("Mapbox.removeOfflinePack not implemented on Android yet")); + } } \ No newline at end of file diff --git a/example.js b/example.js index f7a176f..025acf8 100644 --- a/example.js +++ b/example.js @@ -190,8 +190,8 @@ class MapExample extends Component { this._map && this._map.setVisibleCoordinateBounds(40.712, -74.227, 40.774, -74.125, 100, 0, 0, 0)}> Set visible bounds to 40.7, -74.2, 40.7, -74.1 - this.setState({ userTrackingMode: Mapbox.userTrackingMode.follow })}> - Set userTrackingMode to follow + this.setState({ userTrackingMode: Mapbox.userTrackingMode.followWithHeading })}> + Set userTrackingMode to followWithHeading this._map && this._map.getCenterCoordinateZoomLevel((location)=> { console.log(location); @@ -208,31 +208,47 @@ class MapExample extends Component { })}> Get bounds - Mapbox.addOfflinePack({ - name: 'test', - type: 'bbox', - bounds: [0, 0, 0, 0], - minZoomLevel: 0, - maxZoomLevel: 0, - metadata: { anyValue: 'you wish' }, - styleURL: Mapbox.mapStyles.emerald - })}> + { + Mapbox.addOfflinePack({ + name: 'test', + type: 'bbox', + bounds: [0, 0, 0, 0], + minZoomLevel: 0, + maxZoomLevel: 0, + metadata: { anyValue: 'you wish' }, + styleURL: Mapbox.mapStyles.emerald + }).then(() => { + console.log('Offline pack added'); + }).catch(err => { + console.log(err); + }); + }}> Create offline pack - Mapbox.getOfflinePacks((err, packs)=> { - if (err) console.log(err); - console.log(packs); - })}> + { + Mapbox.getOfflinePacks() + .then(packs => { + console.log(packs); + }) + .catch(err => { + console.log(err); + }); + }}> Get offline packs - Mapbox.removeOfflinePack('test', (err, info)=> { - if (err) console.log(err); - if (info) { - console.log('Deleted', info.deleted); - } else { - console.log('No packs to delete'); - } - })}> + { + Mapbox.removeOfflinePack('test') + .then(info => { + if (info.deleted) { + console.log('Deleted', info.deleted); + } else { + console.log('No packs to delete'); + } + }) + .catch(err => { + console.log(err); + }); + }}> Remove pack with name 'test' User tracking mode is {this.state.userTrackingMode} @@ -245,7 +261,7 @@ class MapExample extends Component { rotateEnabled={true} scrollEnabled={true} zoomEnabled={true} - showsUserLocation={true} + showsUserLocation={false} styleURL={Mapbox.mapStyles.emerald} userTrackingMode={this.state.userTrackingMode} annotations={this.state.annotations} diff --git a/index.js b/index.js index 5f2a4c1..dc91aff 100644 --- a/index.js +++ b/index.js @@ -70,16 +70,32 @@ function setAccessToken(token: string) { } // Offline -function addOfflinePack(options, callback = () => {}) { - MapboxGLManager.addPackForRegion(options, callback); +function bindCallbackToPromise(callback, promise) { + if (callback) { + promise.then(value => { + callback(null, value); + }).catch(err => { + callback(err); + }) + } +} + +function addOfflinePack(options, callback) { + const promise = MapboxGLManager.addPackForRegion(options); + bindCallbackToPromise(callback, promise); + return promise; } function getOfflinePacks(callback) { - MapboxGLManager.getPacks(callback); + const promise = MapboxGLManager.getPacks(); + bindCallbackToPromise(callback, promise); + return promise; } -function removeOfflinePack(packName, callback = () => {}) { - MapboxGLManager.removePack(packName, callback); +function removeOfflinePack(packName, callback) { + const promise = MapboxGLManager.removePack(packName); + bindCallbackToPromise(callback, promise); + return promise; } function addOfflinePackProgressListener(handler) { diff --git a/ios/RCTMapboxGL/RCTMapboxGLManager.m b/ios/RCTMapboxGL/RCTMapboxGLManager.m index 6003add..03f7a84 100644 --- a/ios/RCTMapboxGL/RCTMapboxGLManager.m +++ b/ios/RCTMapboxGL/RCTMapboxGLManager.m @@ -179,8 +179,8 @@ RCT_EXPORT_METHOD(setAccessToken:(nonnull NSString *)accessToken) if ([_packRequests count]) { NSArray * callbackArray = [self serializePacksArray:packs]; - for (RCTResponseSenderBlock callback in _packRequests) { - callback(@[[NSNull null], callbackArray]); + for (RCTPromiseResolveBlock callback in _packRequests) { + callback(callbackArray); } [_packRequests removeAllObjects]; } @@ -261,8 +261,10 @@ RCT_EXPORT_METHOD(setAccessToken:(nonnull NSString *)accessToken) [_bridge.eventDispatcher sendAppEventWithName:@"MapboxOfflineError" body:event]; } -RCT_EXPORT_METHOD(addPackForRegion:(NSDictionary*)options - callback:(RCTResponseSenderBlock)callback) +RCT_REMAP_METHOD(addPackForRegion, + pack:(NSDictionary*)options + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { if ([options objectForKey:@"name"] == nil) { return RCTLogError(@"Name is required."); @@ -302,10 +304,10 @@ RCT_EXPORT_METHOD(addPackForRegion:(NSDictionary*)options [[MGLOfflineStorage sharedOfflineStorage] addPackForRegion:region withContext:context completionHandler:^(MGLOfflinePack *pack, NSError *error) { if (error != nil) { - RCTLogError(@"Error: %@", error.localizedFailureReason); + reject(@"add_pack_failed", error.localizedFailureReason, error); } else { [pack resume]; - callback(@[[NSNull null]]); + resolve([NSNull null]); } }]; }); @@ -328,7 +330,9 @@ RCT_EXPORT_METHOD(addPackForRegion:(NSDictionary*)options return callbackArray; } -RCT_EXPORT_METHOD(getPacks:(RCTResponseSenderBlock)callback) +RCT_REMAP_METHOD(getPacks, + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { dispatch_async(dispatch_get_main_queue(), ^{ NSMutableArray* callbackArray = [NSMutableArray new]; @@ -336,15 +340,17 @@ RCT_EXPORT_METHOD(getPacks:(RCTResponseSenderBlock)callback) MGLOfflinePack *packs = [MGLOfflineStorage sharedOfflineStorage].packs; if (!packs) { - [_packRequests addObject:callback]; + [_packRequests addObject:resolve]; } else { - callback(@[[NSNull null], [self serializePacksArray:packs]]); + resolve([self serializePacksArray:packs]); } }); } -RCT_EXPORT_METHOD(removePack:(NSString*)packName - callback:(RCTResponseSenderBlock)callback) +RCT_REMAP_METHOD(removePack, + name:(NSString*)packName + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { dispatch_async(dispatch_get_main_queue(), ^{ MGLOfflinePack *packs = [MGLOfflineStorage sharedOfflineStorage].packs; @@ -359,7 +365,7 @@ RCT_EXPORT_METHOD(removePack:(NSString*)packName } if (tempPack == nil) { - return callback(@[[NSNull null]]); + return resolve(@{}); } NSDictionary *userInfo = [NSKeyedUnarchiver unarchiveObjectWithData:tempPack.context]; @@ -375,11 +381,9 @@ RCT_EXPORT_METHOD(removePack:(NSString*)packName [_removedPacks removeObject:tempPack]; [[MGLOfflineStorage sharedOfflineStorage] removePack:tempPack withCompletionHandler:^(NSError * _Nullable error) { if (error != nil) { - callback(@[@{ @"message": error.localizedFailureReason }]); + reject(@"remove_pack_failed", error.localizedFailureReason, error); } else { - NSMutableDictionary *deletedObject = [NSMutableDictionary new]; - [deletedObject setObject:userInfo[@"name"] forKey:@"deleted"]; - callback(@[[NSNull null], deletedObject]); + resolve(@{ @"deleted": userInfo[@"name"] }); } }]; });