[ios, osx] Include progress in progress change notification

An MGLOfflinePackProgressChangedNotification notification now includes the pack’s state and progress values, which match the values in the corresponding MGLOfflinePack properties. Implemented NSValue category methods to store MGLOfflinePackProgress inside a dictionary.
This commit is contained in:
Minh Nguyễn
2016-03-27 22:40:15 -07:00
committed by Minh Nguyễn
parent aff1196d02
commit 8c8b058038
7 changed files with 100 additions and 7 deletions

View File

@@ -49,9 +49,12 @@ custom_categories:
- MGLOfflinePackMaximumMapboxTilesReachedNotification
- MGLOfflinePackProgress
- MGLOfflinePackProgressChangedNotification
- MGLOfflinePackProgressUserInfoKey
- MGLOfflinePackRemovalCompletionHandler
- MGLOfflinePackState
- MGLOfflinePackStateUserInfoKey
- MGLTilePyramidOfflineRegion
- NSValue(MGLOfflinePackAdditions)
- name: Geometry
children:
- MGLCoordinateBounds

View File

@@ -161,4 +161,25 @@ typedef struct MGLOfflinePackProgress {
@end
/**
Methods for round-tripping `MGLOfflinePackProgress` values.
*/
@interface NSValue (MGLOfflinePackAdditions)
/**
Creates a new value object containing the given `MGLOfflinePackProgress`
structure.
@param progress The value for the new object.
@return A new value object that contains the offline pack progress information.
*/
+ (NSValue *)valueWithMGLOfflinePackProgress:(MGLOfflinePackProgress)progress;
/**
The `MGLOfflinePackProgress` structure representation of the value.
*/
@property (readonly) MGLOfflinePackProgress MGLOfflinePackProgressValue;
@end
NS_ASSUME_NONNULL_END

View File

@@ -14,8 +14,11 @@ NS_ASSUME_NONNULL_BEGIN
resources are required for offline viewing. This notification is posted
whenever any field in the `progress` property changes.
The `object` is the `MGLOfflinePack` object whose progress changed. For details
about the pack’s current progress, use the pack’s `progress` property.
The `object` is the `MGLOfflinePack` object whose progress changed. The
`userInfo` dictionary contains the pack’s current state in the
`MGLOfflinePackStateUserInfoKey` key and details about the pack’s current
progress in the `MGLOfflinePackProgressUserInfoKey` key. You may also consult
the pack’s `state` and `progress` properties, which provide the same values.
If you only need to observe changes in a particular pack’s progress, you can
alternatively observe KVO change notifications to the pack’s `progress` key
@@ -51,18 +54,38 @@ extern NSString * const MGLOfflinePackErrorNotification;
*/
extern NSString * const MGLOfflinePackMaximumMapboxTilesReachedNotification;
/**
The key for an `NSNumber` object that indicates an offline pack’s current
state. This key is used in the `userInfo` dictionary of an
`MGLOfflinePackProgressChangedNotification` notification. Call `-integerValue`
on the object to receive the `MGLOfflinePackState`-typed state.
*/
extern NSString * const MGLOfflinePackStateUserInfoKey;
/**
The key for an `NSValue` object that indicates an offline pack’s current
progress. This key is used in the `userInfo` dictionary of an
`MGLOfflinePackProgressChangedNotification` notification. Call
`-MGLOfflinePackProgressValue` on the object to receive the
`MGLOfflinePackProgress`-typed progress.
*/
extern NSString * const MGLOfflinePackProgressUserInfoKey;
/**
The key for an `NSError` object that is encountered in the course of
downloading an offline pack. The error’s domain is `MGLErrorDomain`. See
`MGLErrorCode` for possible error codes.
downloading an offline pack. This key is used in the `userInfo` dictionary of
an `MGLOfflinePackErrorNotification` notification. The error’s domain is
`MGLErrorDomain`. See `MGLErrorCode` for possible error codes.
*/
extern NSString * const MGLOfflinePackErrorUserInfoKey;
/**
The key for an `NSNumber` object that indicates the maximum number of
Mapbox-hosted tiles that may be downloaded and stored on the current device.
Call `-unsignedLongLongValue` on the object to receive the `uint64_t`-typed
tile limit.
This key is used in the `userInfo` dictionary of an
`MGLOfflinePackMaximumMapboxTilesReachedNotification` notification. Call
`-unsignedLongLongValue` on the object to receive the `uint64_t`-typed tile
limit.
*/
extern NSString * const MGLOfflinePackMaximumCountUserInfoKey;

View File

@@ -204,3 +204,17 @@ void MBGLOfflineRegionObserver::mapboxTileCountLimitExceeded(uint64_t limit) {
[pack.delegate offlinePack:pack didReceiveMaximumAllowedMapboxTiles:limit];
});
}
@implementation NSValue (MGLOfflinePackAdditions)
+ (NSValue *)valueWithMGLOfflinePackProgress:(MGLOfflinePackProgress)progress {
return [NSValue value:&progress withObjCType:@encode(MGLOfflinePackProgress)];
}
- (MGLOfflinePackProgress)MGLOfflinePackProgressValue {
MGLOfflinePackProgress progress;
[self getValue:&progress];
return progress;
}
@end

View File

@@ -15,6 +15,8 @@ NSString * const MGLOfflinePackProgressChangedNotification = @"MGLOfflinePackPro
NSString * const MGLOfflinePackErrorNotification = @"MGLOfflinePackError";
NSString * const MGLOfflinePackMaximumMapboxTilesReachedNotification = @"MGLOfflinePackMaximumMapboxTilesReached";
NSString * const MGLOfflinePackStateUserInfoKey = @"State";
NSString * const MGLOfflinePackProgressUserInfoKey = @"Progress";
NSString * const MGLOfflinePackErrorUserInfoKey = @"Error";
NSString * const MGLOfflinePackMaximumCountUserInfoKey = @"MaximumCount";
@@ -242,7 +244,10 @@ NSString * const MGLOfflinePackMaximumCountUserInfoKey = @"MaximumCount";
#pragma mark MGLOfflinePackDelegate methods
- (void)offlinePack:(MGLOfflinePack *)pack progressDidChange:(__unused MGLOfflinePackProgress)progress {
[[NSNotificationCenter defaultCenter] postNotificationName:MGLOfflinePackProgressChangedNotification object:pack];
[[NSNotificationCenter defaultCenter] postNotificationName:MGLOfflinePackProgressChangedNotification object:pack userInfo:@{
MGLOfflinePackStateUserInfoKey: @(pack.state),
MGLOfflinePackProgressUserInfoKey: [NSValue valueWithMGLOfflinePackProgress:progress],
}];
}
- (void)offlinePack:(MGLOfflinePack *)pack didReceiveError:(NSError *)error {

View File

@@ -22,4 +22,19 @@
XCTAssertThrowsSpecificNamed([invalidPack suspend], NSException, @"Invalid offline pack", @"Invalid offline pack should raise an exception when being suspended.");
}
- (void)testProgressBoxing {
MGLOfflinePackProgress progress = {
.countOfResourcesCompleted = 1,
.countOfResourcesExpected = 2,
.countOfBytesCompleted = 7,
.maximumResourcesExpected = UINT64_MAX,
};
MGLOfflinePackProgress roundTrippedProgress = [NSValue valueWithMGLOfflinePackProgress:progress].MGLOfflinePackProgressValue;
XCTAssertEqual(progress.countOfResourcesCompleted, roundTrippedProgress.countOfResourcesCompleted, @"Completed resources should round-trip.");
XCTAssertEqual(progress.countOfResourcesExpected, roundTrippedProgress.countOfResourcesExpected, @"Expected resources should round-trip.");
XCTAssertEqual(progress.countOfBytesCompleted, roundTrippedProgress.countOfBytesCompleted, @"Completed bytes should round-trip.");
XCTAssertEqual(progress.maximumResourcesExpected, roundTrippedProgress.maximumResourcesExpected, @"Maximum expected resources should round-trip.");
}
@end

View File

@@ -82,6 +82,18 @@
[self expectationForNotification:MGLOfflinePackProgressChangedNotification object:pack handler:^BOOL(NSNotification * _Nonnull notification) {
MGLOfflinePack *notificationPack = notification.object;
XCTAssert([notificationPack isKindOfClass:[MGLOfflinePack class]], @"Object of notification should be an MGLOfflinePack.");
NSDictionary *userInfo = notification.userInfo;
XCTAssertNotNil(userInfo, @"Progress change notification should have a userInfo dictionary.");
NSNumber *stateNumber = userInfo[MGLOfflinePackStateUserInfoKey];
XCTAssert([stateNumber isKindOfClass:[NSNumber class]], @"Progress change notification’s state should be an NSNumber.");
XCTAssertEqual(stateNumber.integerValue, pack.state, @"State in a progress change notification should match the pack’s state.");
NSValue *progressValue = userInfo[MGLOfflinePackProgressUserInfoKey];
XCTAssert([progressValue isKindOfClass:[NSValue class]], @"Progress change notification’s progress should be an NSValue.");
XCTAssertEqualObjects(progressValue, [NSValue valueWithMGLOfflinePackProgress:pack.progress], @"Progress change notification’s progress should match pack’s progress.");
return notificationPack == pack && pack.state == MGLOfflinePackStateInactive;
}];
[self waitForExpectationsWithTimeout:1 handler:nil];