[ios, osx] Renamed MGLOfflineTask to MGLOfflinePack
“Offline pack” more effectively communicates the persistent nature of the downloaded content.
This commit is contained in:
committed by
Minh Nguyễn
parent
ee20fd8fd8
commit
ff9c3a57b0
@@ -44,8 +44,8 @@
|
||||
'../platform/darwin/src/MGLPolyline.mm',
|
||||
'../platform/darwin/src/MGLPolygon.mm',
|
||||
'../platform/darwin/src/MGLMapCamera.mm',
|
||||
'../platform/darwin/src/MGLOfflineTask.mm',
|
||||
'../platform/darwin/src/MGLOfflineTask_Private.h',
|
||||
'../platform/darwin/src/MGLOfflinePack.mm',
|
||||
'../platform/darwin/src/MGLOfflinePack_Private.h',
|
||||
'../platform/darwin/src/MGLOfflineStorage.mm',
|
||||
'../platform/darwin/src/MGLOfflineStorage_Private.h',
|
||||
'../platform/darwin/src/MGLOfflineRegion_Private.h',
|
||||
|
||||
@@ -43,8 +43,8 @@
|
||||
'../platform/darwin/src/MGLPolyline.mm',
|
||||
'../platform/darwin/src/MGLPolygon.mm',
|
||||
'../platform/darwin/src/MGLMapCamera.mm',
|
||||
'../platform/darwin/src/MGLOfflineTask.mm',
|
||||
'../platform/darwin/src/MGLOfflineTask_Private.h',
|
||||
'../platform/darwin/src/MGLOfflinePack.mm',
|
||||
'../platform/darwin/src/MGLOfflinePack_Private.h',
|
||||
'../platform/darwin/src/MGLOfflineStorage.mm',
|
||||
'../platform/darwin/src/MGLOfflineStorage_Private.h',
|
||||
'../platform/darwin/src/MGLOfflineRegion_Private.h',
|
||||
|
||||
208
platform/darwin/include/MGLOfflinePack.h
Normal file
208
platform/darwin/include/MGLOfflinePack.h
Normal file
@@ -0,0 +1,208 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "MGLOfflineRegion.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol MGLOfflinePackDelegate;
|
||||
|
||||
/**
|
||||
The state an offline pack is currently in.
|
||||
*/
|
||||
typedef NS_ENUM (NSInteger, MGLOfflinePackState) {
|
||||
/**
|
||||
It is unknown whether the pack is inactive, active, or complete.
|
||||
|
||||
This is the initial state of a pack that is obtained using the
|
||||
`-[MGLOfflineStorage getPacksWithCompletionHandler:]` method. The state
|
||||
becomes known by the time the pack’s delegate receives its first progress
|
||||
update. For inactive packs, you must explicitly request a progress update
|
||||
using the `-[MGLOfflinePack requestProgress]` method.
|
||||
|
||||
An invalid pack always has a state of `MGLOfflinePackStateInvalid`, never
|
||||
`MGLOfflinePackStateUnknown`.
|
||||
*/
|
||||
MGLOfflinePackStateUnknown = 0,
|
||||
/**
|
||||
The pack is incomplete and is not currently downloading.
|
||||
|
||||
This is the initial state of a pack that is created using the
|
||||
`-[MGLOfflinePack addPackForRegion:withContext:completionHandler:]` method,
|
||||
as well as after the `-[MGLOfflinePack suspend]` method is
|
||||
called.
|
||||
*/
|
||||
MGLOfflinePackStateInactive = 1,
|
||||
/**
|
||||
The pack is incomplete and is currently downloading.
|
||||
|
||||
This is the state of a pack after the `-[MGLOfflinePack resume]` method is
|
||||
called.
|
||||
*/
|
||||
MGLOfflinePackStateActive = 2,
|
||||
/**
|
||||
The pack has downloaded to completion.
|
||||
*/
|
||||
MGLOfflinePackStateComplete = 3,
|
||||
/**
|
||||
The pack has been removed using the
|
||||
`-[MGLOfflineStorage removePack:withCompletionHandler:]` method. Sending
|
||||
any message to the pack will raise an exception.
|
||||
*/
|
||||
MGLOfflinePackStateInvalid = 4,
|
||||
};
|
||||
|
||||
/**
|
||||
A structure containing information about an offline pack’s current download
|
||||
progress.
|
||||
*/
|
||||
typedef struct MGLOfflinePackProgress {
|
||||
/**
|
||||
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 pack’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 pack’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;
|
||||
} MGLOfflinePackProgress;
|
||||
|
||||
/**
|
||||
An `MGLOfflinePack` represents a collection of resources necessary for viewing
|
||||
a region offline to a local database. It provides an optional
|
||||
`MGLOfflinePackDelegate` object with progress updates as data or errors arrive
|
||||
from the server.
|
||||
*/
|
||||
@interface MGLOfflinePack : NSObject
|
||||
|
||||
/**
|
||||
The region for which the pack 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 pack, such as a user-selected name.
|
||||
*/
|
||||
@property (nonatomic, readonly) NSData *context;
|
||||
|
||||
/**
|
||||
The pack’s current state.
|
||||
|
||||
The state of an inactive or completed pack is computed lazily and is set to
|
||||
`MGLOfflinePackStateUnknown` by default. If you need the state of a pack
|
||||
inside an `MGLOfflinePackListingCompletionHandler`, set the `delegate` property
|
||||
then call the `-requestProgress` method.
|
||||
*/
|
||||
@property (nonatomic, readonly) MGLOfflinePackState state;
|
||||
|
||||
/**
|
||||
The pack’s current progress.
|
||||
|
||||
The progress of an inactive or completed pack is computed lazily, and all its
|
||||
fields are set to 0 by default. If you need the progress of a pack inside an
|
||||
`MGLOfflinePackListingCompletionHandler`, set the `delegate` property then call
|
||||
the `-requestProgress` method.
|
||||
*/
|
||||
@property (nonatomic, readonly) MGLOfflinePackProgress progress;
|
||||
|
||||
/**
|
||||
The pack’s delegate.
|
||||
|
||||
You can use the offline pack delegate to be notified of any changes in the
|
||||
pack’s progress and of any errors while downloading. For more information, see
|
||||
the `MGLOfflinePackDelegate` documentation.
|
||||
*/
|
||||
@property (nonatomic, weak, nullable) id <MGLOfflinePackDelegate> delegate;
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
Resumes downloading if the pack is inactive.
|
||||
*/
|
||||
- (void)resume;
|
||||
|
||||
/**
|
||||
Temporarily stops downloading if the pack is active.
|
||||
|
||||
To resume downloading, call the `-resume` method.
|
||||
*/
|
||||
- (void)suspend;
|
||||
|
||||
/**
|
||||
Request an asynchronous update to the pack’s `state` and `progress` properties.
|
||||
|
||||
The state and progress of an inactive or completed pack are computed lazily. If
|
||||
you need the state or progress of a pack inside an
|
||||
`MGLOfflinePackListingCompletionHandler`, set the `delegate` property then call
|
||||
this method.
|
||||
*/
|
||||
- (void)requestProgress;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
The `MGLOfflinePackDelegate` protocol defines methods that a delegate of an
|
||||
`MGLOfflinePack` object can optionally implement to be notified of any changes
|
||||
in the pack’s download progress and of any errors while downloading.
|
||||
*/
|
||||
@protocol MGLOfflinePackDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
Sent whenever the pack’s state or download progress changes. Every change to a
|
||||
field in the `progress` property corresponds to an invocation of this method.
|
||||
|
||||
@param pack The pack whose state of progress changed.
|
||||
@param progress The updated progress. To get the updated state, refer to the
|
||||
`state` property.
|
||||
*/
|
||||
- (void)offlinePack:(MGLOfflinePack *)pack progressDidChange:(MGLOfflinePackProgress)progress;
|
||||
|
||||
/**
|
||||
Sent whenever the pack encounters an error while downloading.
|
||||
|
||||
Download errors may be recoverable. For example, this pack’s implementation may
|
||||
attempt to re-request failed resources based on an exponential backoff
|
||||
strategy or upon the restoration of network access.
|
||||
|
||||
@param pack The pack that encountered an error.
|
||||
@param error A download error. For a list of possible error codes, see
|
||||
`MGLErrorCode`.
|
||||
*/
|
||||
- (void)offlinePack:(MGLOfflinePack *)pack 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 `MGLOfflinePack` can download
|
||||
additional tiles from Mapbox APIs until already downloaded tiles are removed by
|
||||
calling the `-[MGLOfflineStorage removePack:withCompletionHandler:]` method.
|
||||
Contact your Mapbox sales representative to have the limit raised.
|
||||
*/
|
||||
- (void)offlinePack:(MGLOfflinePack *)pack didReceiveMaximumAllowedMapboxTiles:(uint64_t)maximumCount;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -6,8 +6,8 @@ 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`
|
||||
resources are required by an `MGLOfflinePack` object. At present, only
|
||||
instances of `MGLTilePyramidOfflineRegion` may be used as `MGLOfflinePack`
|
||||
regions, but additional conforming implementations may be added in the future.
|
||||
*/
|
||||
@protocol MGLOfflineRegion <NSObject>
|
||||
|
||||
@@ -4,43 +4,43 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class MGLOfflineTask;
|
||||
@class MGLOfflinePack;
|
||||
@protocol MGLOfflineRegion;
|
||||
|
||||
/**
|
||||
A block to be called once an offline task has been completely created and
|
||||
A block to be called once an offline pack 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 pack Contains a pointer to the newly added pack, or `nil` if there was
|
||||
an error creating or adding the pack.
|
||||
@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
|
||||
pack could not be created or added. For a list of possible error codes, see
|
||||
`MGLErrorCode`.
|
||||
*/
|
||||
typedef void (^MGLOfflineTaskAdditionCompletionHandler)(MGLOfflineTask * _Nullable task, NSError * _Nullable error);
|
||||
typedef void (^MGLOfflinePackAdditionCompletionHandler)(MGLOfflinePack * _Nullable pack, NSError * _Nullable error);
|
||||
|
||||
/**
|
||||
A block to be called once an offline task has been completely invalidated and
|
||||
A block to be called once an offline pack 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.
|
||||
pack could not be invalidated or removed.
|
||||
*/
|
||||
typedef void (^MGLOfflineTaskRemovalCompletionHandler)(NSError * _Nullable error);
|
||||
typedef void (^MGLOfflinePackRemovalCompletionHandler)(NSError * _Nullable error);
|
||||
|
||||
/**
|
||||
A block to be called with a complete list of offline tasks.
|
||||
A block to be called with a complete list of offline packs.
|
||||
|
||||
@param task Contains a pointer an array of tasks, or `nil` if there was an
|
||||
error obtaining the tasks.
|
||||
@param pack Contains a pointer an array of packs, or `nil` if there was an
|
||||
error obtaining the packs.
|
||||
@param error Contains a pointer to an error object (if any) indicating why the
|
||||
list of tasks could not be obtained.
|
||||
list of packs could not be obtained.
|
||||
*/
|
||||
typedef void (^MGLOfflineTaskListingCompletionHandler)(NS_ARRAY_OF(MGLOfflineTask *) *tasks, NSError * _Nullable error);
|
||||
typedef void (^MGLOfflinePackListingCompletionHandler)(NS_ARRAY_OF(MGLOfflinePack *) *packs, NSError * _Nullable error);
|
||||
|
||||
/**
|
||||
MGLOfflineStorage implements a singleton (shared object) that manages offline
|
||||
tasks. All of this class’s instance methods are asynchronous, reflecting the
|
||||
packs. All of this class’s instance methods are asynchronous, reflecting the
|
||||
fact that offline resources are stored in a database.
|
||||
*/
|
||||
@interface MGLOfflineStorage : NSObject
|
||||
@@ -53,53 +53,53 @@ typedef void (^MGLOfflineTaskListingCompletionHandler)(NS_ARRAY_OF(MGLOfflineTas
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
Creates and registers an offline task that downloads the resources needed to
|
||||
Creates and registers an offline pack 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.
|
||||
The resulting pack starts out with a state of `MGLOfflinePackStateInactive`. To
|
||||
begin downloading resources, call `-[MGLOfflinePack resume]`. To monitor
|
||||
download progress, set the pack’s `delegate` property to an object that
|
||||
conforms to the `MGLOfflinePackDelegate` 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.
|
||||
@param completion The completion handler to call once the pack has been added.
|
||||
This handler is executed asynchronously on the main queue.
|
||||
*/
|
||||
- (void)addTaskForRegion:(id <MGLOfflineRegion>)region withContext:(NSData *)context completionHandler:(MGLOfflineTaskAdditionCompletionHandler)completion;
|
||||
- (void)addPackForRegion:(id <MGLOfflineRegion>)region withContext:(NSData *)context completionHandler:(MGLOfflinePackAdditionCompletionHandler)completion;
|
||||
|
||||
/**
|
||||
Unregisters the given offline task and frees any resources that are no longer
|
||||
required by any remaining tasks.
|
||||
Unregisters the given offline pack and frees any resources that are no longer
|
||||
required by any remaining packs.
|
||||
|
||||
As soon as this method is called on a task, the task becomes invalid; any
|
||||
As soon as this method is called on a pack, the pack becomes invalid; any
|
||||
attempt to send it a message will result in an exception being thrown. If an
|
||||
error occurs and the task cannot be removed, do not attempt to reuse the task
|
||||
object. Instead, use the `-getTasksWithCompletionHandler:` method to obtain a
|
||||
valid pointer to the task object.
|
||||
error occurs and the pack cannot be removed, do not attempt to reuse the pack
|
||||
object. Instead, use the `-getPacksWithCompletionHandler:` method to obtain a
|
||||
valid pointer to the pack object.
|
||||
|
||||
@param task The offline task to remove.
|
||||
@param completion The completion handler to call once the task has been
|
||||
@param pack The offline pack to remove.
|
||||
@param completion The completion handler to call once the pack has been
|
||||
removed. This handler is executed asynchronously on the main queue.
|
||||
*/
|
||||
- (void)removeTask:(MGLOfflineTask *)task withCompletionHandler:(MGLOfflineTaskRemovalCompletionHandler)completion;
|
||||
- (void)removePack:(MGLOfflinePack *)pack withCompletionHandler:(MGLOfflinePackRemovalCompletionHandler)completion;
|
||||
|
||||
/**
|
||||
Asynchronously calls a completion callback with all existing offline tasks.
|
||||
Asynchronously calls a completion callback with all existing offline packs.
|
||||
|
||||
@param completion The completion handler to call with the list of tasks. This
|
||||
@param completion The completion handler to call with the list of packs. This
|
||||
handler is executed asynchronously on the main queue.
|
||||
*/
|
||||
- (void)getTasksWithCompletionHandler:(MGLOfflineTaskListingCompletionHandler)completion;
|
||||
- (void)getPacksWithCompletionHandler:(MGLOfflinePackListingCompletionHandler)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.
|
||||
`-[MGLOfflinePackDelegate offlinePack:didReceiveMaximumAllowedMapboxTiles:]` is
|
||||
called on every delegate of `MGLOfflinePack` until already downloaded tiles are
|
||||
removed by calling the `-removePack:withCompletionHandler:` method.
|
||||
|
||||
@note The [Mapbox Terms of Service](https://www.mapbox.com/tos/) prohibits
|
||||
changing or bypassing this limit without permission from Mapbox. Contact
|
||||
|
||||
@@ -1,207 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "MGLOfflineRegion.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol MGLOfflineTaskDelegate;
|
||||
|
||||
/**
|
||||
The state an offline task is currently in.
|
||||
*/
|
||||
typedef NS_ENUM (NSInteger, MGLOfflineTaskState) {
|
||||
/**
|
||||
It is unknown whether the task is inactive, active, or complete.
|
||||
|
||||
This is the initial state of a task that is obtained using the
|
||||
`-[MGLOfflineStorage getTasksWithCompletionHandler:]` method. The state
|
||||
becomes known by the time the task’s delegate receives its first progress
|
||||
update. For inactive tasks, you must explicitly request a progress update
|
||||
using the `-[MGLOfflineTask requestProgress]` method.
|
||||
|
||||
An invalid task always has a state of `MGLOfflineTaskStateInvalid`, never
|
||||
`MGLOfflineTaskStateUnknown`.
|
||||
*/
|
||||
MGLOfflineTaskStateUnknown = 0,
|
||||
/**
|
||||
The task is incomplete and is not currently downloading.
|
||||
|
||||
This is the initial state of a task that is created using the
|
||||
`-[MGLOfflineTask addTaskForRegion:withContext:completionHandler:]` method,
|
||||
as well as after the `-[MGLOfflineTask suspend]` method is
|
||||
called.
|
||||
*/
|
||||
MGLOfflineTaskStateInactive = 1,
|
||||
/**
|
||||
The task is incomplete and is currently downloading.
|
||||
|
||||
This is the state of a task after the `-[MGLOfflineTask resume]` method is
|
||||
called.
|
||||
*/
|
||||
MGLOfflineTaskStateActive = 2,
|
||||
/**
|
||||
The task has downloaded to completion.
|
||||
*/
|
||||
MGLOfflineTaskStateComplete = 3,
|
||||
/**
|
||||
The task has been removed using the
|
||||
`-[MGLOfflineStorage removeTask:withCompletionHandler:]` method. Sending
|
||||
any message to the task will raise an exception.
|
||||
*/
|
||||
MGLOfflineTaskStateInvalid = 4,
|
||||
};
|
||||
|
||||
/**
|
||||
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
|
||||
`MGLOfflineTaskStateUnknown` 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
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,4 +1,4 @@
|
||||
#import "MGLOfflineTask_Private.h"
|
||||
#import "MGLOfflinePack_Private.h"
|
||||
|
||||
#import "MGLOfflineStorage_Private.h"
|
||||
#import "MGLOfflineRegion_Private.h"
|
||||
@@ -8,56 +8,56 @@
|
||||
#include <mbgl/util/string.hpp>
|
||||
|
||||
/**
|
||||
Assert that the current offline task is valid.
|
||||
Assert that the current offline pack is valid.
|
||||
|
||||
This macro should be used at the beginning of any public-facing instance method
|
||||
of `MGLOfflineTask`. For private methods, an assertion is more appropriate.
|
||||
of `MGLOfflinePack`. For private methods, an assertion is more appropriate.
|
||||
*/
|
||||
#define MGLAssertOfflineTaskIsValid() \
|
||||
#define MGLAssertOfflinePackIsValid() \
|
||||
do { \
|
||||
if (_state == MGLOfflineTaskStateInvalid) { \
|
||||
[NSException raise:@"Invalid offline task" \
|
||||
if (_state == MGLOfflinePackStateInvalid) { \
|
||||
[NSException raise:@"Invalid offline pack" \
|
||||
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."]; \
|
||||
@"-[MGLOfflineStorage removePack:withCompletionHandler:] has been called " \
|
||||
@"on this instance of MGLOfflinePack, rendering it invalid. It is an " \
|
||||
@"error to send any message to this pack."]; \
|
||||
} \
|
||||
} while (NO);
|
||||
|
||||
class MBGLOfflineRegionObserver : public mbgl::OfflineRegionObserver {
|
||||
public:
|
||||
MBGLOfflineRegionObserver(MGLOfflineTask *offlineTask_) : offlineTask(offlineTask_) {}
|
||||
MBGLOfflineRegionObserver(MGLOfflinePack *pack_) : pack(pack_) {}
|
||||
|
||||
void statusChanged(mbgl::OfflineRegionStatus status) override;
|
||||
void responseError(mbgl::Response::Error error) override;
|
||||
void mapboxTileCountLimitExceeded(uint64_t limit) override;
|
||||
|
||||
private:
|
||||
__weak MGLOfflineTask *offlineTask = nullptr;
|
||||
__weak MGLOfflinePack *pack = nullptr;
|
||||
};
|
||||
|
||||
@interface MGLOfflineTask ()
|
||||
@interface MGLOfflinePack ()
|
||||
|
||||
@property (nonatomic, nullable, readwrite) mbgl::OfflineRegion *mbglOfflineRegion;
|
||||
@property (nonatomic, readwrite) MGLOfflineTaskState state;
|
||||
@property (nonatomic, readwrite) MGLOfflineTaskProgress progress;
|
||||
@property (nonatomic, readwrite) MGLOfflinePackState state;
|
||||
@property (nonatomic, readwrite) MGLOfflinePackProgress progress;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MGLOfflineTask
|
||||
@implementation MGLOfflinePack
|
||||
|
||||
- (instancetype)init {
|
||||
[NSException raise:@"Method unavailable"
|
||||
format:
|
||||
@"-[MGLOfflineTask init] is unavailable. "
|
||||
@"Use +[MGLOfflineStorage addTaskForRegion:withContext:completionHandler:] instead."];
|
||||
@"-[MGLOfflinePack init] is unavailable. "
|
||||
@"Use +[MGLOfflineStorage addPackForRegion:withContext:completionHandler:] instead."];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (instancetype)initWithMBGLRegion:(mbgl::OfflineRegion *)region {
|
||||
if (self = [super init]) {
|
||||
_mbglOfflineRegion = region;
|
||||
_state = MGLOfflineTaskStateUnknown;
|
||||
_state = MGLOfflinePackStateUnknown;
|
||||
|
||||
mbgl::DefaultFileSource *mbglFileSource = [[MGLOfflineStorage sharedOfflineStorage] mbglFileSource];
|
||||
mbglFileSource->setOfflineRegionObserver(*_mbglOfflineRegion, std::make_unique<MBGLOfflineRegionObserver>(self));
|
||||
@@ -66,14 +66,14 @@ private:
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
if (_mbglOfflineRegion && _state != MGLOfflineTaskStateInvalid) {
|
||||
if (_mbglOfflineRegion && _state != MGLOfflinePackStateInvalid) {
|
||||
mbgl::DefaultFileSource *mbglFileSource = [[MGLOfflineStorage sharedOfflineStorage] mbglFileSource];
|
||||
mbglFileSource->setOfflineRegionObserver(*_mbglOfflineRegion, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
- (id <MGLOfflineRegion>)region {
|
||||
MGLAssertOfflineTaskIsValid();
|
||||
MGLAssertOfflinePackIsValid();
|
||||
|
||||
const mbgl::OfflineRegionDefinition ®ionDefinition = _mbglOfflineRegion->getDefinition();
|
||||
NSAssert([MGLTilePyramidOfflineRegion conformsToProtocol:@protocol(MGLOfflineRegion_Private)], @"MGLTilePyramidOfflineRegion should conform to MGLOfflineRegion_Private.");
|
||||
@@ -81,58 +81,58 @@ private:
|
||||
}
|
||||
|
||||
- (NSData *)context {
|
||||
MGLAssertOfflineTaskIsValid();
|
||||
MGLAssertOfflinePackIsValid();
|
||||
|
||||
const mbgl::OfflineRegionMetadata &metadata = _mbglOfflineRegion->getMetadata();
|
||||
return [NSData dataWithBytes:&metadata[0] length:metadata.size()];
|
||||
}
|
||||
|
||||
- (void)resume {
|
||||
MGLAssertOfflineTaskIsValid();
|
||||
MGLAssertOfflinePackIsValid();
|
||||
|
||||
mbgl::DefaultFileSource *mbglFileSource = [[MGLOfflineStorage sharedOfflineStorage] mbglFileSource];
|
||||
mbglFileSource->setOfflineRegionDownloadState(*_mbglOfflineRegion, mbgl::OfflineRegionDownloadState::Active);
|
||||
}
|
||||
|
||||
- (void)suspend {
|
||||
MGLAssertOfflineTaskIsValid();
|
||||
MGLAssertOfflinePackIsValid();
|
||||
|
||||
mbgl::DefaultFileSource *mbglFileSource = [[MGLOfflineStorage sharedOfflineStorage] mbglFileSource];
|
||||
mbglFileSource->setOfflineRegionDownloadState(*_mbglOfflineRegion, mbgl::OfflineRegionDownloadState::Inactive);
|
||||
}
|
||||
|
||||
- (void)invalidate {
|
||||
NSAssert(_state != MGLOfflineTaskStateInvalid, @"Cannot invalidate an already invalid offline task.");
|
||||
NSAssert(_state != MGLOfflinePackStateInvalid, @"Cannot invalidate an already invalid offline pack.");
|
||||
|
||||
self.state = MGLOfflineTaskStateInvalid;
|
||||
self.state = MGLOfflinePackStateInvalid;
|
||||
self.mbglOfflineRegion = nil;
|
||||
}
|
||||
|
||||
- (void)setState:(MGLOfflineTaskState)state {
|
||||
- (void)setState:(MGLOfflinePackState)state {
|
||||
if (!self.mbglOfflineRegion) {
|
||||
// A progress update has arrived after the call to
|
||||
// -[MGLOfflineStorage removeTask:withCompletionHandler:] but before the
|
||||
// -[MGLOfflineStorage removePack:withCompletionHandler:] but before the
|
||||
// removal is complete and the completion handler is called.
|
||||
NSAssert(_state == MGLOfflineTaskStateInvalid, @"A valid MGLOfflineTask has no mbgl::OfflineRegion.");
|
||||
NSAssert(_state == MGLOfflinePackStateInvalid, @"A valid MGLOfflinePack has no mbgl::OfflineRegion.");
|
||||
return;
|
||||
}
|
||||
|
||||
NSAssert(_state != MGLOfflineTaskStateInvalid, @"Cannot change the state of an invalid offline task.");
|
||||
NSAssert(_state != MGLOfflinePackStateInvalid, @"Cannot change the state of an invalid offline pack.");
|
||||
|
||||
_state = state;
|
||||
}
|
||||
|
||||
- (void)requestProgress {
|
||||
MGLAssertOfflineTaskIsValid();
|
||||
MGLAssertOfflinePackIsValid();
|
||||
|
||||
mbgl::DefaultFileSource *mbglFileSource = [[MGLOfflineStorage sharedOfflineStorage] mbglFileSource];
|
||||
|
||||
__weak MGLOfflineTask *weakSelf = self;
|
||||
__weak MGLOfflinePack *weakSelf = self;
|
||||
mbglFileSource->getOfflineRegionStatus(*_mbglOfflineRegion, [&, weakSelf](__unused std::exception_ptr exception, mbgl::optional<mbgl::OfflineRegionStatus> status) {
|
||||
if (status) {
|
||||
mbgl::OfflineRegionStatus checkedStatus = *status;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
MGLOfflineTask *strongSelf = weakSelf;
|
||||
MGLOfflinePack *strongSelf = weakSelf;
|
||||
[strongSelf offlineRegionStatusDidChange:checkedStatus];
|
||||
});
|
||||
}
|
||||
@@ -140,27 +140,27 @@ private:
|
||||
}
|
||||
|
||||
- (void)offlineRegionStatusDidChange:(mbgl::OfflineRegionStatus)status {
|
||||
NSAssert(_state != MGLOfflineTaskStateInvalid, @"Cannot change update progress of an invalid offline task.");
|
||||
NSAssert(_state != MGLOfflinePackStateInvalid, @"Cannot change update progress of an invalid offline pack.");
|
||||
|
||||
switch (status.downloadState) {
|
||||
case mbgl::OfflineRegionDownloadState::Inactive:
|
||||
self.state = status.complete() ? MGLOfflineTaskStateComplete : MGLOfflineTaskStateInactive;
|
||||
self.state = status.complete() ? MGLOfflinePackStateComplete : MGLOfflinePackStateInactive;
|
||||
break;
|
||||
|
||||
case mbgl::OfflineRegionDownloadState::Active:
|
||||
self.state = MGLOfflineTaskStateActive;
|
||||
self.state = MGLOfflinePackStateActive;
|
||||
break;
|
||||
}
|
||||
|
||||
MGLOfflineTaskProgress progress;
|
||||
MGLOfflinePackProgress progress;
|
||||
progress.countOfResourcesCompleted = status.completedResourceCount;
|
||||
progress.countOfBytesCompleted = status.completedResourceSize;
|
||||
progress.countOfResourcesExpected = status.requiredResourceCount;
|
||||
progress.maximumResourcesExpected = status.requiredResourceCountIsPrecise ? status.requiredResourceCount : UINT64_MAX;
|
||||
self.progress = progress;
|
||||
|
||||
if ([self.delegate respondsToSelector:@selector(offlineTask:progressDidChange:)]) {
|
||||
[self.delegate offlineTask:self progressDidChange:progress];
|
||||
if ([self.delegate respondsToSelector:@selector(offlinePack:progressDidChange:)]) {
|
||||
[self.delegate offlinePack:self progressDidChange:progress];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,28 +189,28 @@ NSError *MGLErrorFromResponseError(mbgl::Response::Error error) {
|
||||
|
||||
void MBGLOfflineRegionObserver::statusChanged(mbgl::OfflineRegionStatus status) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSCAssert(offlineTask, @"MBGLOfflineRegionObserver is dangling without an associated MGLOfflineTask.");
|
||||
NSCAssert(pack, @"MBGLOfflineRegionObserver is dangling without an associated MGLOfflinePack.");
|
||||
|
||||
[offlineTask offlineRegionStatusDidChange:status];
|
||||
[pack offlineRegionStatusDidChange:status];
|
||||
});
|
||||
}
|
||||
|
||||
void MBGLOfflineRegionObserver::responseError(mbgl::Response::Error error) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSCAssert(offlineTask, @"MBGLOfflineRegionObserver is dangling without an associated MGLOfflineTask.");
|
||||
NSCAssert(pack, @"MBGLOfflineRegionObserver is dangling without an associated MGLOfflinePack.");
|
||||
|
||||
if ([offlineTask.delegate respondsToSelector:@selector(offlineTask:didReceiveError:)]) {
|
||||
[offlineTask.delegate offlineTask:offlineTask didReceiveError:MGLErrorFromResponseError(error)];
|
||||
if ([pack.delegate respondsToSelector:@selector(offlinePack:didReceiveError:)]) {
|
||||
[pack.delegate offlinePack:pack didReceiveError:MGLErrorFromResponseError(error)];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MBGLOfflineRegionObserver::mapboxTileCountLimitExceeded(uint64_t limit) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSCAssert(offlineTask, @"MBGLOfflineRegionObserver is dangling without an associated MGLOfflineTask.");
|
||||
NSCAssert(pack, @"MBGLOfflineRegionObserver is dangling without an associated MGLOfflinePack.");
|
||||
|
||||
if ([offlineTask.delegate respondsToSelector:@selector(offlineTask:didReceiveMaximumAllowedMapboxTiles:)]) {
|
||||
[offlineTask.delegate offlineTask:offlineTask didReceiveMaximumAllowedMapboxTiles:limit];
|
||||
if ([pack.delegate respondsToSelector:@selector(offlinePack:didReceiveMaximumAllowedMapboxTiles:)]) {
|
||||
[pack.delegate offlinePack:pack didReceiveMaximumAllowedMapboxTiles:limit];
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
#import "MGLOfflineTask.h"
|
||||
#import "MGLOfflinePack.h"
|
||||
|
||||
#include <mbgl/storage/default_file_source.hpp>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MGLOfflineTask (Private)
|
||||
@interface MGLOfflinePack (Private)
|
||||
|
||||
@property (nonatomic, nullable) mbgl::OfflineRegion *mbglOfflineRegion;
|
||||
|
||||
- (instancetype)initWithMBGLRegion:(mbgl::OfflineRegion *)region;
|
||||
|
||||
/**
|
||||
Invalidates the task and ensures that no future progress update can ever
|
||||
Invalidates the pack and ensures that no future progress update can ever
|
||||
revalidate it.
|
||||
*/
|
||||
- (void)invalidate;
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#import "MGLAccountManager_Private.h"
|
||||
#import "MGLGeometry_Private.h"
|
||||
#import "MGLOfflineTask_Private.h"
|
||||
#import "MGLOfflinePack_Private.h"
|
||||
#import "MGLOfflineRegion_Private.h"
|
||||
#import "MGLTilePyramidOfflineRegion.h"
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)addTaskForRegion:(id <MGLOfflineRegion>)region withContext:(NSData *)context completionHandler:(MGLOfflineTaskAdditionCompletionHandler)completion {
|
||||
- (void)addPackForRegion:(id <MGLOfflineRegion>)region withContext:(NSData *)context completionHandler:(MGLOfflinePackAdditionCompletionHandler)completion {
|
||||
if (![region conformsToProtocol:@protocol(MGLOfflineRegion_Private)]) {
|
||||
[NSException raise:@"Unsupported region type" format:
|
||||
@"Regions of type %@ are unsupported.", NSStringFromClass([region class])];
|
||||
@@ -95,17 +95,17 @@
|
||||
} : nil];
|
||||
}
|
||||
if (completion) {
|
||||
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);
|
||||
MGLOfflinePack *pack = mbglOfflineRegion ? [[MGLOfflinePack alloc] initWithMBGLRegion:new mbgl::OfflineRegion(std::move(*mbglOfflineRegion))] : nil;
|
||||
dispatch_async(dispatch_get_main_queue(), [&, completion, error, pack](void) {
|
||||
completion(pack, error);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)removeTask:(MGLOfflineTask *)task withCompletionHandler:(MGLOfflineTaskRemovalCompletionHandler)completion {
|
||||
mbgl::OfflineRegion *mbglOfflineRegion = task.mbglOfflineRegion;
|
||||
[task invalidate];
|
||||
- (void)removePack:(MGLOfflinePack *)pack withCompletionHandler:(MGLOfflinePackRemovalCompletionHandler)completion {
|
||||
mbgl::OfflineRegion *mbglOfflineRegion = pack.mbglOfflineRegion;
|
||||
[pack invalidate];
|
||||
self.mbglFileSource->deleteOfflineRegion(std::move(*mbglOfflineRegion), [&, completion](std::exception_ptr exception) {
|
||||
NSError *error;
|
||||
if (exception) {
|
||||
@@ -121,7 +121,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
- (void)getTasksWithCompletionHandler:(MGLOfflineTaskListingCompletionHandler)completion {
|
||||
- (void)getPacksWithCompletionHandler:(MGLOfflinePackListingCompletionHandler)completion {
|
||||
self.mbglFileSource->listOfflineRegions([&, completion](std::exception_ptr exception, mbgl::optional<std::vector<mbgl::OfflineRegion>> regions) {
|
||||
NSError *error;
|
||||
if (exception) {
|
||||
@@ -129,17 +129,17 @@
|
||||
NSLocalizedDescriptionKey: @(mbgl::util::toString(exception).c_str()),
|
||||
}];
|
||||
}
|
||||
NSMutableArray *tasks;
|
||||
NSMutableArray *packs;
|
||||
if (regions) {
|
||||
tasks = [NSMutableArray arrayWithCapacity:regions->size()];
|
||||
packs = [NSMutableArray arrayWithCapacity:regions->size()];
|
||||
for (mbgl::OfflineRegion ®ion : *regions) {
|
||||
MGLOfflineTask *task = [[MGLOfflineTask alloc] initWithMBGLRegion:new mbgl::OfflineRegion(std::move(region))];
|
||||
[tasks addObject:task];
|
||||
MGLOfflinePack *pack = [[MGLOfflinePack alloc] initWithMBGLRegion:new mbgl::OfflineRegion(std::move(region))];
|
||||
[packs addObject:pack];
|
||||
}
|
||||
}
|
||||
if (completion) {
|
||||
dispatch_async(dispatch_get_main_queue(), [&, completion, error, tasks](void) {
|
||||
completion(tasks, error);
|
||||
dispatch_async(dispatch_get_main_queue(), [&, completion, error, packs](void) {
|
||||
completion(packs, error);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#import "MGLOfflineStorage.h"
|
||||
|
||||
#import "MGLOfflineTask.h"
|
||||
#import "MGLOfflinePack.h"
|
||||
|
||||
#include <mbgl/storage/default_file_source.hpp>
|
||||
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
|
||||
#import <Mapbox/Mapbox.h>
|
||||
|
||||
static NSString * const MBXOfflineTaskContextNameKey = @"Name";
|
||||
static NSString * const MBXOfflinePackContextNameKey = @"Name";
|
||||
|
||||
static NSString * const MBXDownloadsTableViewInactiveCellReuseIdentifier = @"Inactive";
|
||||
static NSString * const MBXDownloadsTableViewActiveCellReuseIdentifier = @"Active";
|
||||
|
||||
@implementation MGLOfflineTask (MBXAdditions)
|
||||
@implementation MGLOfflinePack (MBXAdditions)
|
||||
|
||||
- (NSString *)name {
|
||||
NSDictionary *userInfo = [NSKeyedUnarchiver unarchiveObjectWithData:self.context];
|
||||
NSAssert([userInfo isKindOfClass:[NSDictionary class]], @"Context of offline task isn’t a dictionary.");
|
||||
NSString *name = userInfo[MBXOfflineTaskContextNameKey];
|
||||
NSAssert([name isKindOfClass:[NSString class]], @"Name of offline task isn’t a string.");
|
||||
NSAssert([userInfo isKindOfClass:[NSDictionary class]], @"Context of offline pack isn’t a dictionary.");
|
||||
NSString *name = userInfo[MBXOfflinePackContextNameKey];
|
||||
NSAssert([name isKindOfClass:[NSString class]], @"Name of offline pack isn’t a string.");
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -28,9 +28,9 @@ static NSString * const MBXDownloadsTableViewActiveCellReuseIdentifier = @"Activ
|
||||
|
||||
@end
|
||||
|
||||
@interface MBXDownloadsTableViewController () <MGLOfflineTaskDelegate>
|
||||
@interface MBXDownloadsTableViewController () <MGLOfflinePackDelegate>
|
||||
|
||||
@property (nonatomic, strong) NS_MUTABLE_ARRAY_OF(MGLOfflineTask *) *offlineTasks;
|
||||
@property (nonatomic, strong) NS_MUTABLE_ARRAY_OF(MGLOfflinePack *) *offlinePacks;
|
||||
|
||||
@end
|
||||
|
||||
@@ -42,14 +42,14 @@ static NSString * const MBXDownloadsTableViewActiveCellReuseIdentifier = @"Activ
|
||||
[super viewDidLoad];
|
||||
|
||||
__weak MBXDownloadsTableViewController *weakSelf = self;
|
||||
[[MGLOfflineStorage sharedOfflineStorage] getTasksWithCompletionHandler:^(NS_ARRAY_OF(MGLOfflineTask *) *tasks, NSError *error) {
|
||||
[[MGLOfflineStorage sharedOfflineStorage] getPacksWithCompletionHandler:^(NS_ARRAY_OF(MGLOfflinePack *) *packs, NSError *error) {
|
||||
MBXDownloadsTableViewController *strongSelf = weakSelf;
|
||||
strongSelf.offlineTasks = tasks.mutableCopy;
|
||||
strongSelf.offlinePacks = packs.mutableCopy;
|
||||
[strongSelf.tableView reloadData];
|
||||
|
||||
for (MGLOfflineTask *task in strongSelf.offlineTasks) {
|
||||
task.delegate = strongSelf;
|
||||
[task requestProgress];
|
||||
for (MGLOfflinePack *pack in strongSelf.offlinePacks) {
|
||||
pack.delegate = strongSelf;
|
||||
[pack requestProgress];
|
||||
}
|
||||
|
||||
if (error) {
|
||||
@@ -78,11 +78,11 @@ static NSString * const MBXDownloadsTableViewActiveCellReuseIdentifier = @"Activ
|
||||
|
||||
MGLTilePyramidOfflineRegion *region = [[MGLTilePyramidOfflineRegion alloc] initWithStyleURL:mapView.styleURL bounds:mapView.visibleCoordinateBounds fromZoomLevel:mapView.zoomLevel toZoomLevel:mapView.maximumZoomLevel];
|
||||
NSData *context = [NSKeyedArchiver archivedDataWithRootObject:@{
|
||||
MBXOfflineTaskContextNameKey: name,
|
||||
MBXOfflinePackContextNameKey: name,
|
||||
}];
|
||||
|
||||
__weak MBXDownloadsTableViewController *weakSelf = self;
|
||||
[[MGLOfflineStorage sharedOfflineStorage] addTaskForRegion:region withContext:context completionHandler:^(MGLOfflineTask *task, NSError *error) {
|
||||
[[MGLOfflineStorage sharedOfflineStorage] addPackForRegion:region withContext:context completionHandler:^(MGLOfflinePack *pack, NSError *error) {
|
||||
MBXDownloadsTableViewController *strongSelf = weakSelf;
|
||||
if (error) {
|
||||
NSString *message = [NSString stringWithFormat:@"Mapbox GL was unable to add the download “%@”.", name];
|
||||
@@ -90,11 +90,11 @@ static NSString * const MBXDownloadsTableViewActiveCellReuseIdentifier = @"Activ
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
|
||||
[self presentViewController:alertController animated:YES completion:nil];
|
||||
} else {
|
||||
task.delegate = strongSelf;
|
||||
[task resume];
|
||||
pack.delegate = strongSelf;
|
||||
[pack resume];
|
||||
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:strongSelf.offlineTasks.count inSection:0];
|
||||
[strongSelf.offlineTasks addObject:task];
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:strongSelf.offlinePacks.count inSection:0];
|
||||
[strongSelf.offlinePacks addObject:pack];
|
||||
[strongSelf.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
}
|
||||
}];
|
||||
@@ -108,16 +108,16 @@ static NSString * const MBXDownloadsTableViewActiveCellReuseIdentifier = @"Activ
|
||||
#pragma mark - Table view data source
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
return self.offlineTasks.count;
|
||||
return self.offlinePacks.count;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
MGLOfflineTask *task = self.offlineTasks[indexPath.row];
|
||||
MGLOfflinePack *pack = self.offlinePacks[indexPath.row];
|
||||
|
||||
NSString *reuseIdentifier = task.state == MGLOfflineTaskStateActive ? MBXDownloadsTableViewActiveCellReuseIdentifier : MBXDownloadsTableViewInactiveCellReuseIdentifier;
|
||||
NSString *reuseIdentifier = pack.state == MGLOfflinePackStateActive ? MBXDownloadsTableViewActiveCellReuseIdentifier : MBXDownloadsTableViewInactiveCellReuseIdentifier;
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier forIndexPath:indexPath];
|
||||
cell.textLabel.text = task.name;
|
||||
MGLOfflineTaskProgress progress = task.progress;
|
||||
cell.textLabel.text = pack.name;
|
||||
MGLOfflinePackProgress progress = pack.progress;
|
||||
NSString *completedString = [NSNumberFormatter localizedStringFromNumber:@(progress.countOfResourcesCompleted)
|
||||
numberStyle:NSNumberFormatterDecimalStyle];
|
||||
NSString *expectedString = [NSNumberFormatter localizedStringFromNumber:@(progress.countOfResourcesExpected)
|
||||
@@ -125,22 +125,22 @@ static NSString * const MBXDownloadsTableViewActiveCellReuseIdentifier = @"Activ
|
||||
NSString *byteCountString = [NSByteCountFormatter stringFromByteCount:progress.countOfBytesCompleted
|
||||
countStyle:NSByteCountFormatterCountStyleFile];
|
||||
NSString *statusString;
|
||||
switch (task.state) {
|
||||
case MGLOfflineTaskStateUnknown:
|
||||
switch (pack.state) {
|
||||
case MGLOfflinePackStateUnknown:
|
||||
statusString = @"Calculating progress…";
|
||||
break;
|
||||
|
||||
case MGLOfflineTaskStateInactive:
|
||||
case MGLOfflinePackStateInactive:
|
||||
statusString = [NSString stringWithFormat:@"%@ of %@ resources (%@)",
|
||||
completedString, expectedString, byteCountString];
|
||||
break;
|
||||
|
||||
case MGLOfflineTaskStateComplete:
|
||||
case MGLOfflinePackStateComplete:
|
||||
statusString = [NSString stringWithFormat:@"%@ resources (%@)",
|
||||
completedString, byteCountString];
|
||||
break;
|
||||
|
||||
case MGLOfflineTaskStateActive:
|
||||
case MGLOfflinePackStateActive:
|
||||
if (progress.countOfResourcesExpected) {
|
||||
completedString = [NSNumberFormatter localizedStringFromNumber:@(progress.countOfResourcesCompleted + 1)
|
||||
numberStyle:NSNumberFormatterDecimalStyle];
|
||||
@@ -152,8 +152,8 @@ static NSString * const MBXDownloadsTableViewActiveCellReuseIdentifier = @"Activ
|
||||
completedString, expectedString, byteCountString];
|
||||
break;
|
||||
|
||||
case MGLOfflineTaskStateInvalid:
|
||||
NSAssert(NO, @"Invalid offline task at index path %@", indexPath);
|
||||
case MGLOfflinePackStateInvalid:
|
||||
NSAssert(NO, @"Invalid offline pack at index path %@", indexPath);
|
||||
break;
|
||||
}
|
||||
cell.detailTextLabel.text = statusString;
|
||||
@@ -163,11 +163,11 @@ static NSString * const MBXDownloadsTableViewActiveCellReuseIdentifier = @"Activ
|
||||
|
||||
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
if (editingStyle == UITableViewCellEditingStyleDelete) {
|
||||
MGLOfflineTask *task = self.offlineTasks[indexPath.row];
|
||||
MGLOfflinePack *pack = self.offlinePacks[indexPath.row];
|
||||
__weak MBXDownloadsTableViewController *weakSelf = self;
|
||||
[[MGLOfflineStorage sharedOfflineStorage] removeTask:task withCompletionHandler:^(NSError *error) {
|
||||
[[MGLOfflineStorage sharedOfflineStorage] removePack:pack withCompletionHandler:^(NSError *error) {
|
||||
MBXDownloadsTableViewController *strongSelf = weakSelf;
|
||||
[strongSelf.offlineTasks removeObjectAtIndex:indexPath.row];
|
||||
[strongSelf.offlinePacks removeObjectAtIndex:indexPath.row];
|
||||
[strongSelf.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
}];
|
||||
}
|
||||
@@ -178,38 +178,38 @@ static NSString * const MBXDownloadsTableViewActiveCellReuseIdentifier = @"Activ
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
|
||||
MGLOfflineTask *task = self.offlineTasks[indexPath.row];
|
||||
switch (task.state) {
|
||||
case MGLOfflineTaskStateUnknown:
|
||||
MGLOfflinePack *pack = self.offlinePacks[indexPath.row];
|
||||
switch (pack.state) {
|
||||
case MGLOfflinePackStateUnknown:
|
||||
break;
|
||||
|
||||
case MGLOfflineTaskStateComplete:
|
||||
if ([task.region respondsToSelector:@selector(applyToMapView:)]) {
|
||||
[task.region performSelector:@selector(applyToMapView:) withObject:self.mapView];
|
||||
case MGLOfflinePackStateComplete:
|
||||
if ([pack.region respondsToSelector:@selector(applyToMapView:)]) {
|
||||
[pack.region performSelector:@selector(applyToMapView:) withObject:self.mapView];
|
||||
}
|
||||
[self performSegueWithIdentifier:@"ReturnToMap" sender:self];
|
||||
break;
|
||||
|
||||
case MGLOfflineTaskStateInactive:
|
||||
[task resume];
|
||||
case MGLOfflinePackStateInactive:
|
||||
[pack resume];
|
||||
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
break;
|
||||
|
||||
case MGLOfflineTaskStateActive:
|
||||
[task suspend];
|
||||
case MGLOfflinePackStateActive:
|
||||
[pack suspend];
|
||||
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
break;
|
||||
|
||||
case MGLOfflineTaskStateInvalid:
|
||||
NSAssert(NO, @"Invalid offline task at index path %@", indexPath);
|
||||
case MGLOfflinePackStateInvalid:
|
||||
NSAssert(NO, @"Invalid offline pack at index path %@", indexPath);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Offline task delegate
|
||||
#pragma mark - Offline pack delegate
|
||||
|
||||
- (void)offlineTask:(MGLOfflineTask *)task progressDidChange:(MGLOfflineTaskProgress)progress {
|
||||
NSUInteger index = [self.offlineTasks indexOfObject:task];
|
||||
- (void)offlinePack:(MGLOfflinePack *)pack progressDidChange:(MGLOfflinePackProgress)progress {
|
||||
NSUInteger index = [self.offlinePacks indexOfObject:pack];
|
||||
if (index == NSNotFound) {
|
||||
return;
|
||||
}
|
||||
@@ -218,12 +218,12 @@ static NSString * const MBXDownloadsTableViewActiveCellReuseIdentifier = @"Activ
|
||||
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
|
||||
}
|
||||
|
||||
- (void)offlineTask:(MGLOfflineTask *)task didReceiveError:(NSError *)error {
|
||||
NSLog(@"Offline task “%@” received error: %@", task.name, error.localizedFailureReason);
|
||||
- (void)offlinePack:(MGLOfflinePack *)pack didReceiveError:(NSError *)error {
|
||||
NSLog(@"Offline pack “%@” received error: %@", pack.name, error.localizedFailureReason);
|
||||
}
|
||||
|
||||
- (void)offlineTask:(MGLOfflineTask *)task didReceiveMaximumAllowedMapboxTiles:(uint64_t)maximumCount {
|
||||
NSLog(@"Offline task “%@” reached limit of %llu tiles.", task.name, maximumCount);
|
||||
- (void)offlinePack:(MGLOfflinePack *)pack didReceiveMaximumAllowedMapboxTiles:(uint64_t)maximumCount {
|
||||
NSLog(@"Offline pack “%@” reached limit of %llu tiles.", pack.name, maximumCount);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -16,9 +16,9 @@ FOUNDATION_EXPORT const unsigned char MapboxVersionString[];
|
||||
#import "MGLMapView+IBAdditions.h"
|
||||
#import "MGLMapView+MGLCustomStyleLayerAdditions.h"
|
||||
#import "MGLMultiPoint.h"
|
||||
#import "MGLOfflinePack.h"
|
||||
#import "MGLOfflineRegion.h"
|
||||
#import "MGLOfflineStorage.h"
|
||||
#import "MGLOfflineTask.h"
|
||||
#import "MGLOverlay.h"
|
||||
#import "MGLPointAnnotation.h"
|
||||
#import "MGLPolygon.h"
|
||||
|
||||
@@ -20,8 +20,8 @@ static void InitializeMapbox() {
|
||||
[MGLMapCamera class];
|
||||
[MGLMapView class];
|
||||
[MGLMultiPoint class];
|
||||
[MGLOfflinePack class];
|
||||
[MGLOfflineStorage class];
|
||||
[MGLOfflineTask class];
|
||||
[MGLPointAnnotation class];
|
||||
[MGLPolygon class];
|
||||
[MGLPolyline class];
|
||||
|
||||
@@ -15,9 +15,9 @@ FOUNDATION_EXPORT const unsigned char MapboxVersionString[];
|
||||
#import <Mapbox/MGLMapView+IBAdditions.h>
|
||||
#import <Mapbox/MGLMapViewDelegate.h>
|
||||
#import <Mapbox/MGLMultiPoint.h>
|
||||
#import <Mapbox/MGLOfflinePack.h>
|
||||
#import <Mapbox/MGLOfflineRegion.h>
|
||||
#import <Mapbox/MGLOfflineStorage.h>
|
||||
#import <Mapbox/MGLOfflineTask.h>
|
||||
#import <Mapbox/MGLOverlay.h>
|
||||
#import <Mapbox/MGLPointAnnotation.h>
|
||||
#import <Mapbox/MGLPolygon.h>
|
||||
|
||||
@@ -22,8 +22,8 @@ static void InitializeMapbox() {
|
||||
[MGLMapCamera class];
|
||||
[MGLMapView class];
|
||||
[MGLMultiPoint class];
|
||||
[MGLOfflinePack class];
|
||||
[MGLOfflineStorage class];
|
||||
[MGLOfflineTask class];
|
||||
[MGLPointAnnotation class];
|
||||
[MGLPolygon class];
|
||||
[MGLPolyline class];
|
||||
|
||||
Reference in New Issue
Block a user