mirror of
https://github.com/status-im/react-native-mapbox-gl.git
synced 2026-08-27 11:01:13 +00:00
Make offline packs more robust.
- Separate the access token initialization and offline maps initialization. - Make the initialization functions return promise so that the consumer code can know when mapbox and the offline packs are ready to be used. - Expose setConnected method. - Update docs.
This commit is contained in:
@@ -404,12 +404,13 @@ To enable or disable metrics, use `Mapbox.setMetricsEnabled(enabled: boolean)`.
|
||||
|
||||
## Offline
|
||||
|
||||
There are 3 main methods for interacting with the offline API:
|
||||
There are 4 main methods for interacting with the offline API:
|
||||
* `Mapbox.initializeOfflinePacks()`: Initializes the offline packs handlers.
|
||||
* `Mapbox.addOfflinePack`: Creates an offline pack
|
||||
* `Mapbox.getOfflinePacks`: Returns an array of all offline packs on the device
|
||||
* `Mapbox.removeOfflinePack`: Removes a single pack
|
||||
|
||||
Before using them, don't forget to set an access token with `Mapbox.setAccessToken(accessToken)`
|
||||
Before using offline packs, you must call `Mapbox.initializeOfflinePacks()`.
|
||||
|
||||
These methods return a promise, but they also accept a callback as the last
|
||||
argument with the signature `(err, value) => {}`.
|
||||
|
||||
+20
-4
@@ -33,6 +33,7 @@ import com.facebook.react.bridge.ReadableNativeMap;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.bridge.WritableNativeArray;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import com.facebook.react.modules.core.RCTNativeAppEventEmitter;
|
||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||
import com.mapbox.mapboxsdk.MapboxAccountManager;
|
||||
@@ -138,15 +139,19 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
|
||||
// Access Token
|
||||
|
||||
@ReactMethod
|
||||
public void setAccessToken(final String accessToken) {
|
||||
public void setAccessToken(final String accessToken, final Promise promise) {
|
||||
if (accessToken == null || accessToken.length() == 0 || accessToken.equals("your-mapbox.com-access-token")) {
|
||||
throw new JSApplicationIllegalArgumentException("Invalid access token. Register to mapbox.com and request an access token, then pass it to setAccessToken()");
|
||||
}
|
||||
if (initialized) {
|
||||
String oldToken = MapboxAccountManager.getInstance().getAccessToken();
|
||||
if (!oldToken.equals(accessToken)) {
|
||||
throw new JSApplicationIllegalArgumentException("Mapbox access token cannot be initialized twice with different values");
|
||||
JSApplicationIllegalArgumentException error =
|
||||
new JSApplicationIllegalArgumentException("Mapbox access token cannot be initialized twice with different values");
|
||||
promise.reject(error);
|
||||
throw error;
|
||||
}
|
||||
promise.resolve(null);
|
||||
return;
|
||||
}
|
||||
initialized = true;
|
||||
@@ -154,9 +159,15 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
|
||||
@Override
|
||||
public void run() {
|
||||
MapboxAccountManager.start(context.getApplicationContext(), accessToken);
|
||||
promise.resolve(null);
|
||||
}
|
||||
});
|
||||
initializeOfflinePacks();
|
||||
}
|
||||
|
||||
// Connected
|
||||
@ReactMethod
|
||||
public void setConnected(boolean connected) {
|
||||
MapboxAccountManager.getInstance().setConnected(connected);
|
||||
}
|
||||
|
||||
// Metrics
|
||||
@@ -264,7 +275,7 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
|
||||
}
|
||||
|
||||
class OfflineRegionsInitialRequest implements OfflineManager.ListOfflineRegionsCallback {
|
||||
ReactNativeMapboxGLModule module;
|
||||
private final ReactNativeMapboxGLModule module;
|
||||
|
||||
OfflineRegionsInitialRequest(ReactNativeMapboxGLModule module) {
|
||||
this.module = module;
|
||||
@@ -293,6 +304,10 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.context
|
||||
.getJSModule(RCTNativeAppEventEmitter.class)
|
||||
.emit("MapboxOfflinePacksLoaded", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -301,6 +316,7 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
void initializeOfflinePacks() {
|
||||
final ReactNativeMapboxGLModule _this = this;
|
||||
mainHandler.post(new Runnable() {
|
||||
|
||||
@@ -85,9 +85,16 @@ function getMetricsEnabled() {
|
||||
|
||||
// Access token
|
||||
function setAccessToken(token: string) {
|
||||
MapboxGLManager.setAccessToken(token);
|
||||
const promise = MapboxGLManager.setAccessToken(token);
|
||||
return promise;
|
||||
}
|
||||
|
||||
// Connected
|
||||
function setConnected(connected: boolean) {
|
||||
MapboxGLManager.setConnected(connected);
|
||||
}
|
||||
|
||||
|
||||
// Offline
|
||||
function bindCallbackToPromise(callback, promise) {
|
||||
if (callback) {
|
||||
@@ -99,6 +106,15 @@ function bindCallbackToPromise(callback, promise) {
|
||||
}
|
||||
}
|
||||
|
||||
function initializeOfflinePacks() {
|
||||
return new Promise((resolve, reject) => {
|
||||
NativeAppEventEmitter.addListener('MapboxOfflinePacksLoaded', () => {
|
||||
resolve();
|
||||
});
|
||||
MapboxGLManager.initializeOfflinePacks();
|
||||
});
|
||||
}
|
||||
|
||||
function addOfflinePack(options, callback) {
|
||||
let _options = options;
|
||||
// Workaround the fact that RN Android can't serialize JSON correctly
|
||||
@@ -464,7 +480,11 @@ const Mapbox = {
|
||||
mapStyles, userTrackingMode, userLocationVerticalAlignment, unknownResourceCount,
|
||||
getMetricsEnabled, setMetricsEnabled,
|
||||
setAccessToken,
|
||||
addOfflinePack, getOfflinePacks, removeOfflinePack,
|
||||
setConnected,
|
||||
initializeOfflinePacks,
|
||||
addOfflinePack,
|
||||
getOfflinePacks,
|
||||
removeOfflinePack,
|
||||
addOfflinePackProgressListener,
|
||||
addOfflineMaxAllowedTilesListener,
|
||||
addOfflineErrorListener,
|
||||
|
||||
@@ -17,4 +17,4 @@
|
||||
BOOL _loadedPacks;
|
||||
NSMutableSet * _loadingPacks;
|
||||
}
|
||||
@end
|
||||
@end
|
||||
|
||||
@@ -128,13 +128,17 @@ RCT_EXPORT_METHOD(setMetricsEnabled:(BOOL)enabled)
|
||||
|
||||
// Access token
|
||||
|
||||
RCT_EXPORT_METHOD(setAccessToken:(nonnull NSString *)accessToken)
|
||||
RCT_EXPORT_METHOD(setAccessToken:(nonnull NSString *)accessToken
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (!accessToken || ![accessToken length] || [accessToken isEqual:@"your-mapbox.com-access-token"]) {
|
||||
reject(nil, @"Mapbox api token is not valid.", nil);
|
||||
return;
|
||||
}
|
||||
[MGLAccountManager setAccessToken:accessToken];
|
||||
resolve(nil);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -144,23 +148,6 @@ RCT_EXPORT_METHOD(setAccessToken:(nonnull NSString *)accessToken)
|
||||
{
|
||||
if (!(self = [super init])) { return nil; }
|
||||
|
||||
_recentPacks = [NSMutableSet new];
|
||||
_throttledPacks = [NSMutableSet new];
|
||||
_removedPacks = [NSMutableSet new];
|
||||
_throttleInterval = 300;
|
||||
|
||||
_loadingPacks = [NSMutableSet new];
|
||||
_loadedPacks = NO;
|
||||
|
||||
// Setup pack array loading notifications
|
||||
[[MGLOfflineStorage sharedOfflineStorage] addObserver:self forKeyPath:@"packs" options:NSKeyValueObservingOptionInitial context:NULL];
|
||||
_packRequests = [NSMutableArray new];
|
||||
|
||||
// Setup offline pack notification handlers.
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(offlinePackProgressDidChange:) name:MGLOfflinePackProgressChangedNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(offlinePackDidReceiveError:) name:MGLOfflinePackErrorNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(offlinePackDidReceiveMaximumAllowedMapboxTiles:) name:MGLOfflinePackMaximumMapboxTilesReachedNotification object:nil];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -187,6 +174,7 @@ RCT_EXPORT_METHOD(setAccessToken:(nonnull NSString *)accessToken)
|
||||
for (MGLOfflinePack * pack in packs) {
|
||||
[pack resume];
|
||||
}
|
||||
[_bridge.eventDispatcher sendAppEventWithName:@"MapboxOfflinePacksLoaded" body:@{}];
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
@@ -297,6 +285,26 @@ RCT_EXPORT_METHOD(setAccessToken:(nonnull NSString *)accessToken)
|
||||
[_bridge.eventDispatcher sendAppEventWithName:@"MapboxOfflineError" body:event];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(initializeOfflinePacks)
|
||||
{
|
||||
_recentPacks = [NSMutableSet new];
|
||||
_throttledPacks = [NSMutableSet new];
|
||||
_removedPacks = [NSMutableSet new];
|
||||
_throttleInterval = 300;
|
||||
|
||||
_loadingPacks = [NSMutableSet new];
|
||||
_loadedPacks = NO;
|
||||
|
||||
// Setup pack array loading notifications
|
||||
[[MGLOfflineStorage sharedOfflineStorage] addObserver:self forKeyPath:@"packs" options:NSKeyValueObservingOptionInitial context:NULL];
|
||||
_packRequests = [NSMutableArray new];
|
||||
|
||||
// Setup offline pack notification handlers.
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(offlinePackProgressDidChange:) name:MGLOfflinePackProgressChangedNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(offlinePackDidReceiveError:) name:MGLOfflinePackErrorNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(offlinePackDidReceiveMaximumAllowedMapboxTiles:) name:MGLOfflinePackMaximumMapboxTilesReachedNotification object:nil];
|
||||
}
|
||||
|
||||
RCT_REMAP_METHOD(addOfflinePack,
|
||||
pack:(NSDictionary*)options
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
|
||||
Reference in New Issue
Block a user