Skip to content

Commit

Permalink
[IOS] call requestProgress when getting pack status
Browse files Browse the repository at this point in the history
  • Loading branch information
caspg committed Sep 16, 2024
1 parent a686eae commit a45933b
Showing 1 changed file with 61 additions and 40 deletions.
101 changes: 61 additions & 40 deletions ios/RCTMLN/MLNOfflineModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ - (instancetype)init
packRequestQueue = [NSMutableArray new];
eventThrottle = 300;
lastPackState = -1;

NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
[defaultCenter addObserver:self selector:@selector(offlinePackProgressDidChange:) name:MLNOfflinePackProgressChangedNotification object:nil];
[defaultCenter addObserver:self selector:@selector(offlinePackDidReceiveError:) name:MLNOfflinePackErrorNotification object:nil];
[defaultCenter addObserver:self selector:@selector(offlinePackDidReceiveMaxAllowedMapboxTiles:) name:MLNOfflinePackMaximumMapboxTilesReachedNotification object:nil];

[[MLNOfflineStorage sharedOfflineStorage] addObserver:self forKeyPath:@"packs" options:NSKeyValueObservingOptionInitial context:NULL];
}
return self;
Expand All @@ -72,15 +72,21 @@ - (void)dealloc

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
if ([keyPath isEqualToString:@"state"] && [object isKindOfClass:[MLNOfflinePack class]]) {
MLNOfflinePack* pack = (MLNOfflinePack*)object;
[self observerStateForPack:pack context:context];
return;
}

if (packRequestQueue.count == 0) {
return;
}

NSArray<MLNOfflinePack *> *packs = [[MLNOfflineStorage sharedOfflineStorage] packs];
if (packs == nil) {
return;
}

while (packRequestQueue.count > 0) {
RCTPromiseResolveBlock resolve = [packRequestQueue objectAtIndex:0];
resolve([self _convertPacksToJson:packs]);
Expand All @@ -94,13 +100,13 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
{
NSString *styleURL = options[@"styleURL"];
MLNCoordinateBounds bounds = [RCTMLNUtils fromFeatureCollection:options[@"bounds"]];

id<MLNOfflineRegion> offlineRegion = [[MLNTilePyramidOfflineRegion alloc] initWithStyleURL:[NSURL URLWithString:styleURL]
bounds:bounds
fromZoomLevel:[options[@"minZoom"] doubleValue]
toZoomLevel:[options[@"maxZoom"] doubleValue]];
NSData *context = [self _archiveMetadata:options[@"metadata"]];

[[MLNOfflineStorage sharedOfflineStorage] addPackForRegion:offlineRegion
withContext:context
completionHandler:^(MLNOfflinePack *pack, NSError *error) {
Expand Down Expand Up @@ -129,7 +135,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
return reject(@"asset_does_not_exist", [NSString stringWithFormat:@"The given assetName, %@, can't be found in the app's bundle.", path], nil);
}
}

[[MLNOfflineStorage sharedOfflineStorage] addContentsOfFile:absolutePath withCompletionHandler:^(NSURL *fileURL, NSArray<MLNOfflinePack *> *packs, NSError *error) {
if (error != nil) {
reject(@"mergeOfflineRegions", error.description, error);
Expand All @@ -143,7 +149,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
{
dispatch_async(dispatch_get_main_queue(), ^{
NSArray<MLNOfflinePack *> *packs = [[MLNOfflineStorage sharedOfflineStorage] packs];

if (packs == nil) {
// packs have not loaded yet
[self->packRequestQueue addObject:resolve];
Expand Down Expand Up @@ -187,7 +193,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
}
resolve(nil);
}];

}

RCT_EXPORT_METHOD(resetDatabase:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
Expand All @@ -199,22 +205,37 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
}
resolve(nil);
}];

}

RCT_EXPORT_METHOD(getPackStatus:(NSString *)name
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
MLNOfflinePack *pack = [self _getPackFromName:name];

if (pack == nil) {
resolve(nil);
NSLog(@"getPackStatus - Unknown offline region");
return;
}

resolve([self _makeRegionStatusPayload:name pack:pack]);

if (pack.state == MLNOfflinePackStateUnknown) {
[pack addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionNew context:(__bridge_retained void*)resolve];
[pack requestProgress];
} else {
resolve([self _makeRegionStatusPayload:name pack:pack]);
}
}

-(void)observerStateForPack:(MLNOfflinePack*)pack context:(nullable void*) context {
RCTPromiseResolveBlock resolve = (__bridge_transfer RCTPromiseResolveBlock)context;
dispatch_async(dispatch_get_main_queue(), ^{
NSDictionary* metadata = [self _unarchiveMetadata:pack];
NSString* name = metadata[@"name"];
resolve([self _makeRegionStatusPayload:name pack:pack]);
});
[pack removeObserver:self forKeyPath:@"state" context:context];
}

RCT_EXPORT_METHOD(invalidatePack:(NSString *)name
Expand All @@ -241,7 +262,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
rejecter:(RCTPromiseRejectBlock)reject)
{
MLNOfflinePack *pack = [self _getPackFromName:name];

if (pack == nil) {
resolve(nil);
return;
Expand All @@ -265,17 +286,17 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
rejecter:(RCTPromiseRejectBlock)reject)
{
MLNOfflinePack *pack = [self _getPackFromName:name];

if (pack == nil) {
reject(@"pausePackDownload", @"Unknown offline region", nil);
return;
}

if (pack.state == MLNOfflinePackStateInactive || pack.state == MLNOfflinePackStateComplete) {
resolve(nil);
return;
}

[pack suspend];
resolve(nil);
}
Expand All @@ -285,17 +306,17 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
rejecter:(RCTPromiseRejectBlock)reject)
{
MLNOfflinePack *pack = [self _getPackFromName:name];

if (pack == nil) {
reject(@"resumePack", @"Unknown offline region", nil);
return;
}

if (pack.state == MLNOfflinePackStateActive || pack.state == MLNOfflinePackStateComplete) {
resolve(nil);
return;
}

[pack resume];
resolve(nil);
}
Expand All @@ -313,18 +334,18 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
- (void)offlinePackProgressDidChange:(NSNotification *)notification
{
MLNOfflinePack *pack = notification.object;

if (pack.state == MLNOfflinePackStateInvalid) {
return; // Avoid invalid offline pack exception
}

if ([self _shouldSendProgressEvent:[self _getCurrentTimestamp] pack:pack]) {
NSDictionary *metadata = [self _unarchiveMetadata:pack];
RCTMLNEvent *event = [self _makeProgressEvent:metadata[@"name"] pack:pack];
[self _sendEvent:RCT_MAPBOX_OFFLINE_CALLBACK_PROGRESS event:event];
lastPackTimestamp = [self _getCurrentTimestamp];
}

lastPackState = pack.state;
}

Expand All @@ -335,7 +356,7 @@ - (void)offlinePackDidReceiveError:(NSNotification *)notification
return; // Avoid invalid offline pack exception
}
NSDictionary *metadata = [self _unarchiveMetadata:pack];

NSString *name = metadata[@"name"];
if (name != nil) {
NSError *error = notification.userInfo[MLNOfflinePackUserInfoKeyError];
Expand All @@ -350,7 +371,7 @@ - (void)offlinePackDidReceiveMaxAllowedMapboxTiles:(NSNotification *)notificatio
{
MLNOfflinePack *pack = notification.object;
NSDictionary *metadata = [self _unarchiveMetadata:pack];

NSString *name = metadata[@"name"];
if (name != nil) {
RCTMLNEvent *event = [self _makeErrorEvent:name
Expand Down Expand Up @@ -386,11 +407,11 @@ - (NSDictionary *)_unarchiveMetadata:(MLNOfflinePack *)pack
if ([data isKindOfClass:[NSDictionary class]]) {
return data;
}

if (data == nil) {
return @{};
}

return [NSJSONSerialization JSONObjectWithData:[data dataUsingEncoding:NSUTF8StringEncoding]
options:NSJSONReadingMutableContainers
error:nil];
Expand All @@ -406,7 +427,7 @@ - (NSDictionary *)_makeRegionStatusPayload:(NSString *)name pack:(MLNOfflinePack
if(expectedResources == 0) {
progressPercentage = 0;
}

return @{
@"state": @(pack.state),
@"name": name,
Expand All @@ -433,15 +454,15 @@ - (RCTMLNEvent *)_makeErrorEvent:(NSString *)name type:(NSString *)type message:
- (NSArray<NSDictionary *> *)_convertPacksToJson:(NSArray<MLNOfflinePack *> *)packs
{
NSMutableArray<NSDictionary *> *jsonPacks = [NSMutableArray new];

if (packs == nil) {
return jsonPacks;
}

for (MLNOfflinePack *pack in packs) {
[jsonPacks addObject:[self _convertPackToDict:pack]];
}

return jsonPacks;
}

Expand All @@ -452,12 +473,12 @@ - (NSDictionary *)_convertPackToDict:(MLNOfflinePack *)pack
if (region == nil) {
return nil;
}

NSArray *jsonBounds = @[
@[@(region.bounds.ne.longitude), @(region.bounds.ne.latitude)],
@[@(region.bounds.sw.longitude), @(region.bounds.sw.latitude)]
];

// format metadata
NSDictionary *metadata = [self _unarchiveMetadata:pack];
NSData *jsonMetadata = [NSJSONSerialization dataWithJSONObject:metadata
Expand All @@ -472,19 +493,19 @@ - (NSDictionary *)_convertPackToDict:(MLNOfflinePack *)pack
- (MLNOfflinePack *)_getPackFromName:(NSString *)name
{
NSArray<MLNOfflinePack *> *packs = [[MLNOfflineStorage sharedOfflineStorage] packs];

if (packs == nil) {
return nil;
}

for (MLNOfflinePack *pack in packs) {
NSDictionary *metadata = [self _unarchiveMetadata:pack];

if ([name isEqualToString:metadata[@"name"]]) {
return pack;
}
}

return nil;
}

Expand All @@ -501,15 +522,15 @@ - (BOOL)_shouldSendProgressEvent:(double)currentTimestamp pack:(MLNOfflinePack *
if (lastPackState == -1) {
return YES;
}

if (lastPackState != currentPack.state) {
return YES;
}

if (currentTimestamp - lastPackTimestamp > eventThrottle) {
return YES;
}

return NO;
}

Expand Down

0 comments on commit a45933b

Please sign in to comment.