summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2016-03-07 03:25:21 -0800
committerMinh Nguyễn <mxn@1ec5.org>2016-03-10 17:08:58 -0800
commit8824237e2df9d9bfb9cd618e762e74d8ab08c099 (patch)
tree58cc45ca983cb487606b185d99a2de2b6a089703
parent0348c1ee967cf3e19d9dc91918d28e42b40b5b19 (diff)
downloadqtlocation-mapboxgl-8824237e2df9d9bfb9cd618e762e74d8ab08c099.tar.gz
[ios, osx] Documented offline APIs
Also categorized offline symbols for jazzy and moved styleURL from MGLOfflineRegion to MGLTilePyramidOfflineRegion, since you never know if there will be a region type not constrained by a style in the future.
-rw-r--r--.jazzy.yaml12
-rw-r--r--platform/darwin/include/MGLOfflineRegion.h8
-rw-r--r--platform/darwin/include/MGLOfflineStorage.h87
-rw-r--r--platform/darwin/include/MGLOfflineTask.h141
-rw-r--r--platform/darwin/include/MGLTilePyramidOfflineRegion.h58
-rw-r--r--platform/darwin/src/MGLOfflineStorage.mm11
-rw-r--r--platform/darwin/src/MGLOfflineTask.mm25
-rw-r--r--platform/darwin/src/MGLOfflineTask_Private.h2
-rw-r--r--platform/ios/app/MBXDownloadsTableViewController.m8
9 files changed, 340 insertions, 12 deletions
diff --git a/.jazzy.yaml b/.jazzy.yaml
index 867c77e6b9..0f6e8b0625 100644
--- a/.jazzy.yaml
+++ b/.jazzy.yaml
@@ -37,6 +37,18 @@ custom_categories:
- MGLOverlay
- MGLShape
- MGLUserLocation
+ - name: Offline Viewing
+ children:
+ - MGLOfflineRegion
+ - MGLOfflineStorage
+ - MGLOfflineTask
+ - MGLOfflineTaskAdditionCompletionHandler
+ - MGLOfflineTaskDelegate
+ - MGLOfflineTaskListingCompletionHandler
+ - MGLOfflineTaskProgress
+ - MGLOfflineTaskRemovalCompletionHandler
+ - MGLOfflineTaskState
+ - MGLTilePyramidOfflineRegion
- name: Geometry
children:
- MGLCoordinateBounds
diff --git a/platform/darwin/include/MGLOfflineRegion.h b/platform/darwin/include/MGLOfflineRegion.h
index 6958e3bffe..04d2327293 100644
--- a/platform/darwin/include/MGLOfflineRegion.h
+++ b/platform/darwin/include/MGLOfflineRegion.h
@@ -4,10 +4,14 @@
NS_ASSUME_NONNULL_BEGIN
+/**
+ An object conforming to the `MGLOfflineRegion` protocol determines which
+ resources are required by an `MGLOfflineTask` object. At present, only
+ instances of `MGLTilePyramidOfflineRegion` may be used as `MGLOfflineTask`
+ regions, but additional conforming implementations may be added in the future.
+ */
@protocol MGLOfflineRegion <NSObject>
-@property (nonatomic, readonly) NSURL *styleURL;
-
@end
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/include/MGLOfflineStorage.h b/platform/darwin/include/MGLOfflineStorage.h
index 2d33f3ba69..459371d9f7 100644
--- a/platform/darwin/include/MGLOfflineStorage.h
+++ b/platform/darwin/include/MGLOfflineStorage.h
@@ -7,22 +7,99 @@ NS_ASSUME_NONNULL_BEGIN
@class MGLOfflineTask;
@protocol MGLOfflineRegion;
-typedef void (^MGLOfflineTaskRegistrationCompletionHandler)(MGLOfflineTask *task, NSError *error);
-typedef void (^MGLOfflineTaskRemovalCompletionHandler)(NSError *error);
-typedef void (^MGLOfflineTasksRetrievalCompletionHandler)(NS_ARRAY_OF(MGLOfflineTask *) *tasks, NSError *error);
+/**
+ A block to be called once an offline task has been completely created and
+ added.
+
+ @param task Contains a pointer to the newly added task, or `nil` if there was
+ an error creating or adding the task.
+ @param error Contains a pointer to an error object (if any) indicating why the
+ task could not be created or added. For a list of possible error codes, see
+ `MGLErrorCode`.
+ */
+typedef void (^MGLOfflineTaskAdditionCompletionHandler)(MGLOfflineTask * _Nullable task, NSError * _Nullable error);
+/**
+ A block to be called once an offline task has been completely invalidated and
+ removed.
+
+ @param error Contains a pointer to an error object (if any) indicating why the
+ task could not be invalidated or removed.
+ */
+typedef void (^MGLOfflineTaskRemovalCompletionHandler)(NSError * _Nullable error);
+
+/**
+ A block to be called with a complete list of offline tasks.
+
+ @param task Contains a pointer an array of tasks, or `nil` if there was an
+ error obtaining the tasks.
+ @param error Contains a pointer to an error object (if any) indicating why the
+ list of tasks could not be obtained.
+ */
+typedef void (^MGLOfflineTaskListingCompletionHandler)(NS_ARRAY_OF(MGLOfflineTask *) *tasks, NSError * _Nullable error);
+
+/**
+ MGLOfflineStorage implements a singleton (shared object) that manages offline
+ tasks. All of this class’s instance methods are asynchronous, reflecting the
+ fact that offline resources are stored in a database.
+ */
@interface MGLOfflineStorage : NSObject
+/**
+ Returns the shared offline storage object.
+ */
+ (instancetype)sharedOfflineStorage;
- (instancetype)init NS_UNAVAILABLE;
-- (void)addTaskForRegion:(id <MGLOfflineRegion>)region withContext:(NSData *)context completionHandler:(MGLOfflineTaskRegistrationCompletionHandler)completion;
+/**
+ Creates and registers an offline task that downloads the resources needed to
+ use the given region offline.
+
+ The resulting task starts out with a state of `MGLOfflineTaskStateInactive`. To
+ begin downloading resources, call `-[MGLOfflineTask resume]`. To monitor
+ download progress, set the task’s `delegate` property to an object that
+ conforms to the `MGLOfflineTaskDelegate` protocol.
+
+ @param region A region to download.
+ @param context Arbitrary data to store alongside the downloaded resources.
+ @param completion The completion handler to call once the task has been added.
+ This handler is executed asynchronously on the main queue.
+ */
+- (void)addTaskForRegion:(id <MGLOfflineRegion>)region withContext:(NSData *)context completionHandler:(MGLOfflineTaskAdditionCompletionHandler)completion;
+/**
+ Unregisters the given offline task and frees any resources that are no longer
+ required by any remaining tasks. After this task is removed, it is invalid; any
+ attempt to interact with it will result in an exception being thrown.
+
+ @param task The offline task to remove.
+ @param completion The completion handler to call once the task has been
+ removed. This handler is executed asynchronously on the main queue.
+ */
- (void)removeTask:(MGLOfflineTask *)task withCompletionHandler:(MGLOfflineTaskRemovalCompletionHandler)completion;
-- (void)getTasksWithCompletionHandler:(MGLOfflineTasksRetrievalCompletionHandler)completion;
+/**
+ Asynchronously calls a completion callback with all existing offline tasks.
+
+ @param completion The completion handler to call with the list of tasks. This
+ handler is executed asynchronously on the main queue.
+ */
+- (void)getTasksWithCompletionHandler:(MGLOfflineTaskListingCompletionHandler)completion;
+/**
+ Sets the maximum number of Mapbox-hosted tiles that may be downloaded and
+ stored on the current device.
+
+ Once this limit is reached,
+ `-[MGLOfflineTaskDelegate offlineTask:didReceiveMaximumAllowedMapboxTiles:]` is
+ called on every delegate of `MGLOfflineTask` until already downloaded tiles are
+ removed by calling the `-removeTask:withCompletionHandler:` method.
+
+ @note The [Mapbox Terms of Service](https://www.mapbox.com/tos/) prohibits
+ changing or bypassing this limit without permission from Mapbox. Contact
+ your Mapbox sales representative to have the limit raised.
+ */
- (void)setMaximumAllowedMapboxTiles:(uint64_t)maximumCount;
@end
diff --git a/platform/darwin/include/MGLOfflineTask.h b/platform/darwin/include/MGLOfflineTask.h
index 72e66a50f5..504416aeb9 100644
--- a/platform/darwin/include/MGLOfflineTask.h
+++ b/platform/darwin/include/MGLOfflineTask.h
@@ -6,42 +6,183 @@ NS_ASSUME_NONNULL_BEGIN
@protocol MGLOfflineTaskDelegate;
+/**
+ The state an offline task is currently in.
+ */
typedef NS_ENUM (NSInteger, MGLOfflineTaskState) {
+ /**
+ The task is incomplete and is not currently downloading. This is the
+ initial state of a task that is added using the
+ `-[MGLOfflineStorage addTaskForRegion:withContext:completionHandler:]`
+ method.
+ */
MGLOfflineTaskStateInactive = 0,
+ /**
+ The task is incomplete and is currently downloading. This is the state of a
+ task after the `-[MGLOfflineTask resume]` method is called.
+ */
MGLOfflineTaskStateActive = 1,
+ /**
+ The task has downloaded to completion.
+ */
MGLOfflineTaskStateComplete = 2,
+ /**
+ The task has been removed using the
+ `-[MGLOfflineStorage removeTask:withCompletionHandler:]` method. Any
+ messages sent to the task will raise an exception.
+ */
+ MGLOfflineTaskStateInvalid = 3,
};
+/**
+ A structure containing information about an offline task’s current download
+ progress.
+ */
typedef struct MGLOfflineTaskProgress {
+ /**
+ The number of resources that have been completely downloaded and are ready
+ to use offline.
+ */
uint64_t countOfResourcesCompleted;
+ /**
+ The cumulative size of the downloaded resources on disk, measured in bytes.
+ */
uint64_t countOfBytesCompleted;
+ /**
+ The minimum number of resources that must be downloaded in order to view
+ the task’s full region without any omissions.
+
+ At the beginning of a download, this count is a lower bound; the number of
+ expected resources may increase as the download progresses.
+ */
uint64_t countOfResourcesExpected;
+ /**
+ The maximum number of resources that must be downloaded in order to view
+ the task’s full region without any omissions.
+
+ At the beginning of a download, when the exact number of required resources
+ is unknown, this field is set to `UINT64_MAX`. Thus this count is always an
+ upper bound.
+ */
uint64_t maximumResourcesExpected;
} MGLOfflineTaskProgress;
+/**
+ An `MGLOfflineTask` writes the resources necessary for viewing a region offline
+ to a local database, providing an optional `MGLOfflineTaskDelegate` object with
+ progress updates as data or errors arrive from the server.
+ */
@interface MGLOfflineTask : NSObject
+/**
+ The region for which the task manages resources.
+ */
@property (nonatomic, readonly) id <MGLOfflineRegion> region;
+
+/**
+ Arbitrary data stored alongside the downloaded resources.
+
+ The context typically holds application-specific information for identifying
+ the task, such as a user-selected name.
+ */
@property (nonatomic, readonly) NSData *context;
+
+/**
+ The task’s current state.
+
+ The state of an inactive or completed task is computed lazily and is set to
+ `MGLOfflineTaskStateInactive` by default. If you need the state of a task
+ inside an `MGLOfflineTaskListingCompletionHandler`, set the `delegate` property
+ then call the `-requestProgress` method.
+ */
@property (nonatomic, readonly) MGLOfflineTaskState state;
+
+/**
+ The task’s current progress.
+
+ The progress of an inactive or completed task is computed lazily, and all its
+ fields are set to 0 by default. If you need the progress of a task inside an
+ `MGLOfflineTaskListingCompletionHandler`, set the `delegate` property then call
+ the `-requestProgress` method.
+ */
@property (nonatomic, readonly) MGLOfflineTaskProgress progress;
+
+/**
+ The task’s delegate.
+
+ You can use the offline task delegate to be notified of any changes in the
+ task’s progress and of any errors while downloading. For more information, see
+ the `MGLOfflineTaskDelegate` documentation.
+ */
@property (nonatomic, weak, nullable) id <MGLOfflineTaskDelegate> delegate;
- (instancetype)init NS_UNAVAILABLE;
+/**
+ Resumes downloading if the task is inactive.
+ */
- (void)resume;
+
+/**
+ Temporarily stops downloading if the task is active.
+
+ To resume downloading, call the `-resume` method.
+ */
- (void)suspend;
+/**
+ Request an asynchronous update to the task’s `state` and `progress` properties.
+
+ The state and progress of an inactive or completed task are computed lazily. If
+ you need the state or progress of a task inside an
+ `MGLOfflineTaskListingCompletionHandler`, set the `delegate` property then call
+ this method.
+ */
- (void)requestProgress;
@end
+/**
+ The `MGLOfflineTaskDelegate` protocol defines methods that a delegate of an
+ `MGLOfflineTask` object can optionally implement to be notified of any changes
+ in the task’s download progress and of any errors while downloading.
+ */
@protocol MGLOfflineTaskDelegate <NSObject>
@optional
+/**
+ Sent whenever the task’s state or download progress changes. Every change to a
+ field in the `progress` property corresponds to an invocation of this method.
+
+ @param task The task whose state of progress changed.
+ @param progress The updated progress. To get the updated state, refer to the
+ `state` property.
+ */
- (void)offlineTask:(MGLOfflineTask *)task progressDidChange:(MGLOfflineTaskProgress)progress;
+
+/**
+ Sent whenever the task encounters an error while downloading.
+
+ Download errors may be recoverable. For example, this task’s implementation may
+ attempt to re-request failed resources based on an exponential backoff
+ strategy or upon the restoration of network access.
+
+ @param task The task that encountered an error.
+ @param error A download error. For a list of possible error codes, see
+ `MGLErrorCode`.
+ */
- (void)offlineTask:(MGLOfflineTask *)task didReceiveError:(NSError *)error;
+
+/**
+ Sent when the maximum number of Mapbox-hosted tiles has been downloaded and
+ stored on the current device.
+
+ Once this limit is reached, no instance of `MGLOfflineTask` can download
+ additional tiles from Mapbox APIs until already downloaded tiles are removed by
+ calling the `-[MGLOfflineStorage removeTask:withCompletionHandler:]` method.
+ Contact your Mapbox sales representative to have the limit raised.
+ */
- (void)offlineTask:(MGLOfflineTask *)task didReceiveMaximumAllowedMapboxTiles:(uint64_t)maximumCount;
@end
diff --git a/platform/darwin/include/MGLTilePyramidOfflineRegion.h b/platform/darwin/include/MGLTilePyramidOfflineRegion.h
index 7beca3390f..89920adcc5 100644
--- a/platform/darwin/include/MGLTilePyramidOfflineRegion.h
+++ b/platform/darwin/include/MGLTilePyramidOfflineRegion.h
@@ -5,13 +5,71 @@
NS_ASSUME_NONNULL_BEGIN
+/**
+ An offline region defined by a style URL, geographic coordinate bounds, and
+ range of zoom levels.
+ */
@interface MGLTilePyramidOfflineRegion : NSObject <MGLOfflineRegion>
+/**
+ URL of the style whose resources are required for offline viewing.
+
+ In addition to the JSON stylesheet, different styles may require different font
+ glyphs, sprite sheets, and other resources.
+
+ The URL may be a full HTTP or HTTPS URL, a Mapbox URL indicating the style’s
+ map ID (`mapbox://styles/{user}/{style}`), or a path to a local file
+ relative to the application’s resource path.
+ */
+@property (nonatomic, readonly) NSURL *styleURL;
+
+/**
+ The coordinate bounds for the geographic region covered by the downloaded
+ tiles.
+ */
@property (nonatomic, readonly) MGLCoordinateBounds bounds;
+
+/**
+ The minimum zoom level for which to download tiles and other resources.
+
+ For more information about zoom levels, `-[MGLMapView zoomLevel]`.
+ */
@property (nonatomic, readonly) double minimumZoomLevel;
+
+/**
+ The maximum zoom level for which to download tiles and other resources.
+
+ For more information about zoom levels, `-[MGLMapView zoomLevel]`.
+ */
@property (nonatomic, readonly) double maximumZoomLevel;
- (instancetype)init NS_UNAVAILABLE;
+
+/**
+ Initializes a newly created offline region with the given style URL, geographic
+ coordinate bounds, and range of zoom levels.
+
+ This is the designated initializer for `MGLTilePyramidOfflineRegion`.
+
+ @param styleURL URL of the map style for which to download resources. The URL
+ may be a full HTTP or HTTPS URL, a Mapbox URL indicating the style’s map ID
+ (`mapbox://styles/{user}/{style}`), or a path to a local file relative to
+ the application’s resource path. Specify `nil` for the default style.
+ @param bounds The coordinate bounds for the geographic region to be covered by
+ the downloaded tiles.
+ @param minimumZoomLevel The minimum zoom level to be covered by the downloaded
+ tiles. This parameter should be set to at least 0 but no greater than the
+ value of the `maximumZoomLevel` parameter. For each required tile source, if
+ this parameter is set to a value less than the tile source’s minimum zoom
+ level, the download covers zoom levels down to the tile source’s minimum
+ zoom level.
+ @param maximumZoomLevel The maximum zoom level to be covered by the downloaded
+ tiles. This parameter should be set to at least the value of the
+ `minimumZoomLevel` parameter. For each required tile source, if this
+ parameter is set to a value greater than the tile source’s minimum zoom
+ level, the download covers zoom levels up to the tile source’s maximum zoom
+ level.
+ */
- (instancetype)initWithStyleURL:(nullable NSURL *)styleURL bounds:(MGLCoordinateBounds)bounds fromZoomLevel:(double)minimumZoomLevel toZoomLevel:(double)maximumZoomLevel NS_DESIGNATED_INITIALIZER;
@end
diff --git a/platform/darwin/src/MGLOfflineStorage.mm b/platform/darwin/src/MGLOfflineStorage.mm
index 17537452a3..f2061b4a3f 100644
--- a/platform/darwin/src/MGLOfflineStorage.mm
+++ b/platform/darwin/src/MGLOfflineStorage.mm
@@ -76,7 +76,7 @@
}
}
-- (void)addTaskForRegion:(id <MGLOfflineRegion>)region withContext:(NSData *)context completionHandler:(MGLOfflineTaskRegistrationCompletionHandler)completion {
+- (void)addTaskForRegion:(id <MGLOfflineRegion>)region withContext:(NSData *)context completionHandler:(MGLOfflineTaskAdditionCompletionHandler)completion {
if (![region conformsToProtocol:@protocol(MGLOfflineRegion_Private)]) {
[NSException raise:@"Unsupported region type" format:
@"Regions of type %@ are unsupported.", NSStringFromClass([region class])];
@@ -95,7 +95,7 @@
} : nil];
}
if (completion) {
- MGLOfflineTask *task = [[MGLOfflineTask alloc] initWithMBGLRegion:new mbgl::OfflineRegion(std::move(*mbglOfflineRegion))];
+ MGLOfflineTask *task = mbglOfflineRegion ? [[MGLOfflineTask alloc] initWithMBGLRegion:new mbgl::OfflineRegion(std::move(*mbglOfflineRegion))] : nil;
dispatch_async(dispatch_get_main_queue(), [&, completion, error, task](void) {
completion(task, error);
});
@@ -104,7 +104,7 @@
}
- (void)removeTask:(MGLOfflineTask *)task withCompletionHandler:(MGLOfflineTaskRemovalCompletionHandler)completion {
- self.mbglFileSource->deleteOfflineRegion(std::move(*task.mbglOfflineRegion), [&, completion](std::exception_ptr exception) {
+ self.mbglFileSource->deleteOfflineRegion(std::move(*task.mbglOfflineRegion), [&, task, completion](std::exception_ptr exception) {
NSError *error;
if (exception) {
error = [NSError errorWithDomain:MGLErrorDomain code:-1 userInfo:@{
@@ -112,14 +112,15 @@
}];
}
if (completion) {
- dispatch_async(dispatch_get_main_queue(), [&, completion, error](void) {
+ dispatch_async(dispatch_get_main_queue(), [&, task, completion, error](void) {
+ [task invalidate];
completion(error);
});
}
});
}
-- (void)getTasksWithCompletionHandler:(MGLOfflineTasksRetrievalCompletionHandler)completion {
+- (void)getTasksWithCompletionHandler:(MGLOfflineTaskListingCompletionHandler)completion {
self.mbglFileSource->listOfflineRegions([&, completion](std::exception_ptr exception, mbgl::optional<std::vector<mbgl::OfflineRegion>> regions) {
NSError *error;
if (exception) {
diff --git a/platform/darwin/src/MGLOfflineTask.mm b/platform/darwin/src/MGLOfflineTask.mm
index a5b6e66031..f1e8bdb566 100644
--- a/platform/darwin/src/MGLOfflineTask.mm
+++ b/platform/darwin/src/MGLOfflineTask.mm
@@ -7,6 +7,13 @@
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/util/string.hpp>
+#define MGLAssertOfflineTaskIsValid() \
+ [NSException raise:@"Invalid offline task" \
+ format: \
+ @"-[MGLOfflineStorage removeTask:withCompletionHandler:] has been called " \
+ @"on this instance of MGLOfflineTask, rendering it invalid. It is an " \
+ @"error to send any message to this task."]
+
class MBGLOfflineRegionObserver;
@interface MGLOfflineTask ()
@@ -46,29 +53,45 @@ class MBGLOfflineRegionObserver;
}
- (id <MGLOfflineRegion>)region {
+ MGLAssertOfflineTaskIsValid();
+
const mbgl::OfflineRegionDefinition &regionDefinition = _mbglOfflineRegion->getDefinition();
NSAssert([MGLTilePyramidOfflineRegion conformsToProtocol:@protocol(MGLOfflineRegion_Private)], @"MGLTilePyramidOfflineRegion should conform to MGLOfflineRegion_Private.");
return [(id <MGLOfflineRegion_Private>)[MGLTilePyramidOfflineRegion alloc] initWithOfflineRegionDefinition:regionDefinition];
}
- (NSData *)context {
+ MGLAssertOfflineTaskIsValid();
+
const mbgl::OfflineRegionMetadata &metadata = _mbglOfflineRegion->getMetadata();
return [NSData dataWithBytes:&metadata[0] length:metadata.size()];
}
- (void)resume {
+ MGLAssertOfflineTaskIsValid();
+
mbgl::DefaultFileSource *mbglFileSource = [[MGLOfflineStorage sharedOfflineStorage] mbglFileSource];
mbglFileSource->setOfflineRegionDownloadState(*_mbglOfflineRegion, mbgl::OfflineRegionDownloadState::Active);
self.state = MGLOfflineTaskStateActive;
}
- (void)suspend {
+ MGLAssertOfflineTaskIsValid();
+
mbgl::DefaultFileSource *mbglFileSource = [[MGLOfflineStorage sharedOfflineStorage] mbglFileSource];
mbglFileSource->setOfflineRegionDownloadState(*_mbglOfflineRegion, mbgl::OfflineRegionDownloadState::Inactive);
self.state = MGLOfflineTaskStateInactive;
}
+- (void)invalidate {
+ MGLAssertOfflineTaskIsValid();
+
+ self.state = MGLOfflineTaskStateInvalid;
+}
+
- (void)requestProgress {
+ MGLAssertOfflineTaskIsValid();
+
mbgl::DefaultFileSource *mbglFileSource = [[MGLOfflineStorage sharedOfflineStorage] mbglFileSource];
__weak MGLOfflineTask *weakSelf = self;
@@ -84,6 +107,8 @@ class MBGLOfflineRegionObserver;
}
- (void)offlineRegionStatusDidChange:(mbgl::OfflineRegionStatus)status {
+ MGLAssertOfflineTaskIsValid();
+
switch (status.downloadState) {
case mbgl::OfflineRegionDownloadState::Inactive:
self.state = status.complete() ? MGLOfflineTaskStateComplete : MGLOfflineTaskStateInactive;
diff --git a/platform/darwin/src/MGLOfflineTask_Private.h b/platform/darwin/src/MGLOfflineTask_Private.h
index ad0e597a8d..0b630ff6ff 100644
--- a/platform/darwin/src/MGLOfflineTask_Private.h
+++ b/platform/darwin/src/MGLOfflineTask_Private.h
@@ -11,6 +11,8 @@ class MBGLOfflineRegionObserver;
- (instancetype)initWithMBGLRegion:(mbgl::OfflineRegion *)region;
+- (void)invalidate;
+
@end
class MBGLOfflineRegionObserver : public mbgl::OfflineRegionObserver {
diff --git a/platform/ios/app/MBXDownloadsTableViewController.m b/platform/ios/app/MBXDownloadsTableViewController.m
index 1748310be6..e5edc336a4 100644
--- a/platform/ios/app/MBXDownloadsTableViewController.m
+++ b/platform/ios/app/MBXDownloadsTableViewController.m
@@ -147,6 +147,10 @@ static NSString * const MBXDownloadsTableViewActiveCellReuseIdentifier = @"Activ
statusString = [NSString stringWithFormat:@"Downloading %@ of %@ resources (%@ so far)…",
completedString, expectedString, byteCountString];
break;
+
+ case MGLOfflineTaskStateInvalid:
+ NSAssert(NO, @"Invalid offline task at index path %@", indexPath);
+ break;
}
cell.detailTextLabel.text = statusString;
@@ -188,6 +192,10 @@ static NSString * const MBXDownloadsTableViewActiveCellReuseIdentifier = @"Activ
[task suspend];
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
+
+ case MGLOfflineTaskStateInvalid:
+ NSAssert(NO, @"Invalid offline task at index path %@", indexPath);
+ break;
}
}