From e35921e504a94cbe5f8cbc35b15943f1d2e8903f Mon Sep 17 00:00:00 2001 From: Jordan Kiley Date: Mon, 15 Oct 2018 10:18:50 +0800 Subject: [ios] Create a branch that supports iOS 8 (#13036) * [ios] switched deployment * [ios, macos] started to restore iOS 8 support * [ios] Started to restore iOS 8 support * [ios, macos] Switching storage types * [ios] update iosapp * [ios, macos] fixed a test, documented length is unavailable * [ios] remove safe area from integration test * [ios] Update Changelog, Installation guide, and README * [ios] Addressed Fabian's feedback --- platform/darwin/src/MGLAttributionInfo.mm | 6 +- platform/darwin/src/MGLAttributionInfo_Private.h | 6 +- platform/darwin/src/MGLCompassDirectionFormatter.m | 4 +- platform/darwin/src/MGLComputedShapeSource.h | 4 +- platform/darwin/src/MGLComputedShapeSource.mm | 4 +- .../darwin/src/MGLComputedShapeSource_Private.h | 2 +- platform/darwin/src/MGLFeature.h | 8 +- platform/darwin/src/MGLFeature.mm | 6 +- platform/darwin/src/MGLFeature_Private.h | 4 +- platform/darwin/src/MGLMultiPoint.mm | 2 +- platform/darwin/src/MGLOfflineStorage.h | 2 +- platform/darwin/src/MGLOfflineStorage.mm | 8 +- platform/darwin/src/MGLPolygon.h | 8 +- platform/darwin/src/MGLPolygon.mm | 8 +- platform/darwin/src/MGLPolygon_Private.h | 2 +- platform/darwin/src/MGLPolyline.h | 4 +- platform/darwin/src/MGLPolyline.mm | 8 +- platform/darwin/src/MGLPolyline_Private.h | 2 +- platform/darwin/src/MGLRasterTileSource.h | 2 +- platform/darwin/src/MGLRasterTileSource.mm | 2 +- platform/darwin/src/MGLShapeCollection.h | 4 +- platform/darwin/src/MGLShapeCollection.mm | 4 +- platform/darwin/src/MGLShapeSource.h | 10 +- platform/darwin/src/MGLShapeSource.mm | 12 +- platform/darwin/src/MGLShapeSource_Private.h | 2 +- platform/darwin/src/MGLStyle.h | 6 +- platform/darwin/src/MGLStyle.mm | 22 +-- platform/darwin/src/MGLStyle_Private.h | 10 +- platform/darwin/src/MGLTileSource.h | 2 +- platform/darwin/src/MGLTileSource.mm | 6 +- platform/darwin/src/MGLTileSource_Private.h | 4 +- platform/darwin/src/MGLTypes.h | 21 +++ platform/darwin/src/MGLVectorTileSource.h | 4 +- platform/darwin/src/MGLVectorTileSource.mm | 8 +- platform/darwin/src/MGLVectorTileSource_Private.h | 2 +- platform/darwin/src/NSBundle+MGLAdditions.h | 2 +- platform/darwin/src/NSBundle+MGLAdditions.m | 2 +- platform/darwin/src/NSExpression+MGLAdditions.h | 2 + platform/darwin/src/NSExpression+MGLAdditions.mm | 38 +++--- platform/darwin/src/NSString+MGLAdditions.h | 3 + platform/darwin/src/NSString+MGLAdditions.m | 26 ++-- platform/darwin/test/MGLCoordinateFormatterTests.m | 24 +++- platform/darwin/test/MGLExpressionTests.mm | 149 ++++++++++++--------- platform/darwin/test/MGLNSStringAdditionsTests.m | 48 +++---- platform/ios/CHANGELOG.md | 5 +- platform/ios/INSTALL.md | 2 +- .../Base.lproj/LaunchScreen.storyboard | 16 ++- .../ios/Mapbox-iOS-SDK-nightly-dynamic.podspec | 2 +- platform/ios/Mapbox-iOS-SDK-static-part.podspec | 2 +- platform/ios/Mapbox-iOS-SDK-symbols.podspec | 2 +- platform/ios/Mapbox-iOS-SDK.podspec | 2 +- platform/ios/README.md | 2 + .../ios/app/MBXOfflinePacksTableViewController.m | 6 +- platform/ios/app/MBXViewController.m | 9 +- platform/ios/app/Main.storyboard | 62 +++++---- platform/ios/benchmark/MBXBenchViewController.mm | 6 +- platform/ios/config.cmake | 2 +- platform/ios/ios.xcodeproj/project.pbxproj | 10 +- platform/ios/src/MGLMapAccessibilityElement.mm | 8 +- platform/ios/src/MGLMapView.mm | 8 +- platform/ios/src/MGLScaleBar.mm | 6 +- .../ios/test/MGLMapAccessibilityElementTests.m | 7 +- platform/ios/test/MGLNSOrthographyAdditionsTests.m | 8 +- 63 files changed, 397 insertions(+), 271 deletions(-) diff --git a/platform/darwin/src/MGLAttributionInfo.mm b/platform/darwin/src/MGLAttributionInfo.mm index e8d6a203d0..07d10e852b 100644 --- a/platform/darwin/src/MGLAttributionInfo.mm +++ b/platform/darwin/src/MGLAttributionInfo.mm @@ -16,7 +16,7 @@ @implementation MGLAttributionInfo -+ (NSArray *)attributionInfosFromHTMLString:(nullable NSString *)htmlString fontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor { ++ (NS_ARRAY_OF(MGLAttributionInfo *) *)attributionInfosFromHTMLString:(nullable NSString *)htmlString fontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor { if (!htmlString) { return @[]; } @@ -112,7 +112,7 @@ return infos; } -+ (NSAttributedString *)attributedStringForAttributionInfos:(NSArray *)attributionInfos { ++ (NSAttributedString *)attributedStringForAttributionInfos:(NS_ARRAY_OF(MGLAttributionInfo *) *)attributionInfos { NSMutableArray *titles = [NSMutableArray arrayWithCapacity:attributionInfos.count]; for (MGLAttributionInfo *info in attributionInfos) { NSMutableAttributedString *title = info.title.mutableCopy; @@ -259,7 +259,7 @@ } } -- (void)growArrayByAddingAttributionInfosFromArray:(NSArray *)infos { +- (void)growArrayByAddingAttributionInfosFromArray:(NS_ARRAY_OF(MGLAttributionInfo *) *)infos { for (MGLAttributionInfo *info in infos) { [self growArrayByAddingAttributionInfo:info]; } diff --git a/platform/darwin/src/MGLAttributionInfo_Private.h b/platform/darwin/src/MGLAttributionInfo_Private.h index 85c9ed796f..c639752ac3 100644 --- a/platform/darwin/src/MGLAttributionInfo_Private.h +++ b/platform/darwin/src/MGLAttributionInfo_Private.h @@ -16,9 +16,9 @@ NS_ASSUME_NONNULL_BEGIN @param fontSize The default text size in points. @param linkColor The default link color. */ -+ (NSArray *)attributionInfosFromHTMLString:(nullable NSString *)htmlString fontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor; ++ (NS_ARRAY_OF(MGLAttributionInfo *) *)attributionInfosFromHTMLString:(nullable NSString *)htmlString fontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor; -+ (NSAttributedString *)attributedStringForAttributionInfos:(NSArray *)attributionInfos; ++ (NSAttributedString *)attributedStringForAttributionInfos:(NS_ARRAY_OF(MGLAttributionInfo *) *)attributionInfos; /** Returns a copy of the `URL` property modified to account for the given style @@ -58,7 +58,7 @@ NS_ASSUME_NONNULL_BEGIN @param infos An array of info objects to add to the receiver. */ -- (void)growArrayByAddingAttributionInfosFromArray:(NSArray *)infos; +- (void)growArrayByAddingAttributionInfosFromArray:(NS_ARRAY_OF(MGLAttributionInfo *) *)infos; @end diff --git a/platform/darwin/src/MGLCompassDirectionFormatter.m b/platform/darwin/src/MGLCompassDirectionFormatter.m index 1ac6a82162..5f0cfae6f7 100644 --- a/platform/darwin/src/MGLCompassDirectionFormatter.m +++ b/platform/darwin/src/MGLCompassDirectionFormatter.m @@ -15,8 +15,8 @@ } - (NSString *)stringFromDirection:(CLLocationDirection)direction { - static NSArray *shortStrings; - static NSArray *longStrings; + static NS_ARRAY_OF(NSString *) *shortStrings; + static NS_ARRAY_OF(NSString *) *longStrings; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ shortStrings = @[ diff --git a/platform/darwin/src/MGLComputedShapeSource.h b/platform/darwin/src/MGLComputedShapeSource.h index 84dc4801a7..de48a197cb 100644 --- a/platform/darwin/src/MGLComputedShapeSource.h +++ b/platform/darwin/src/MGLComputedShapeSource.h @@ -103,7 +103,7 @@ MGL_EXPORT @param identifier A string that uniquely identifies the source. @param options An `NSDictionary` of options for this source. */ -- (instancetype)initWithIdentifier:(NSString *)identifier options:(nullable NSDictionary *)options NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithIdentifier:(NSString *)identifier options:(nullable NS_DICTIONARY_OF(MGLShapeSourceOption, id) *)options NS_DESIGNATED_INITIALIZER; /** Returns a custom shape data source initialized with an identifier, data source, and a @@ -122,7 +122,7 @@ MGL_EXPORT @param identifier A string that uniquely identifies the source. @param options An `NSDictionary` of options for this source. */ -- (instancetype)initWithIdentifier:(NSString *)identifier dataSource:(id)dataSource options:(nullable NSDictionary *)options; +- (instancetype)initWithIdentifier:(NSString *)identifier dataSource:(id)dataSource options:(nullable NS_DICTIONARY_OF(MGLShapeSourceOption, id) *)options; /** Invalidates all the features and properties intersecting with or contained in diff --git a/platform/darwin/src/MGLComputedShapeSource.mm b/platform/darwin/src/MGLComputedShapeSource.mm index 0493131922..858df46595 100644 --- a/platform/darwin/src/MGLComputedShapeSource.mm +++ b/platform/darwin/src/MGLComputedShapeSource.mm @@ -16,7 +16,7 @@ const MGLExceptionName MGLInvalidDatasourceException = @"MGLInvalidDatasourceExc const MGLShapeSourceOption MGLShapeSourceOptionWrapsCoordinates = @"MGLShapeSourceOptionWrapsCoordinates"; const MGLShapeSourceOption MGLShapeSourceOptionClipsCoordinates = @"MGLShapeSourceOptionClipsCoordinates"; -mbgl::style::CustomGeometrySource::Options MBGLCustomGeometrySourceOptionsFromDictionary(NSDictionary *options) { +mbgl::style::CustomGeometrySource::Options MBGLCustomGeometrySourceOptionsFromDictionary(NS_DICTIONARY_OF(MGLShapeSourceOption, id) *options) { mbgl::style::CustomGeometrySource::Options sourceOptions; if (NSNumber *value = options[MGLShapeSourceOptionMinimumZoomLevel]) { @@ -159,7 +159,7 @@ mbgl::style::CustomGeometrySource::Options MBGLCustomGeometrySourceOptionsFromDi @implementation MGLComputedShapeSource -- (instancetype)initWithIdentifier:(NSString *)identifier options:(NSDictionary *)options { +- (instancetype)initWithIdentifier:(NSString *)identifier options:(NS_DICTIONARY_OF(MGLShapeSourceOption, id) *)options { NSOperationQueue *requestQueue = [[NSOperationQueue alloc] init]; requestQueue.name = [NSString stringWithFormat:@"mgl.MGLComputedShapeSource.%@", identifier]; requestQueue.qualityOfService = NSQualityOfServiceUtility; diff --git a/platform/darwin/src/MGLComputedShapeSource_Private.h b/platform/darwin/src/MGLComputedShapeSource_Private.h index ec075e4bd7..e1887caf8d 100644 --- a/platform/darwin/src/MGLComputedShapeSource_Private.h +++ b/platform/darwin/src/MGLComputedShapeSource_Private.h @@ -7,6 +7,6 @@ NS_ASSUME_NONNULL_BEGIN MGL_EXPORT -mbgl::style::CustomGeometrySource::Options MBGLCustomGeometrySourceOptionsFromDictionary(NSDictionary *options); +mbgl::style::CustomGeometrySource::Options MBGLCustomGeometrySourceOptionsFromDictionary(NS_DICTIONARY_OF(MGLShapeSourceOption, id) *options); NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLFeature.h b/platform/darwin/src/MGLFeature.h index 62471abb16..d0c9e26062 100644 --- a/platform/darwin/src/MGLFeature.h +++ b/platform/darwin/src/MGLFeature.h @@ -148,7 +148,7 @@ NS_ASSUME_NONNULL_BEGIN when the feature instance is used to initialize an `MGLShapeSource` and that source is added to the map and styled. */ -@property (nonatomic, copy) NSDictionary *attributes; +@property (nonatomic, copy) NS_DICTIONARY_OF(NSString *, id) *attributes; /** Returns the feature attribute for the given attribute name. @@ -167,7 +167,7 @@ NS_ASSUME_NONNULL_BEGIN `attributes` property, and an `id` key corresponding to the receiver’s `identifier` property. */ -- (NSDictionary *)geoJSONDictionary; +- (NS_DICTIONARY_OF(NSString *, id) *)geoJSONDictionary; @end @@ -252,9 +252,9 @@ MGL_EXPORT MGL_EXPORT @interface MGLShapeCollectionFeature : MGLShapeCollection -@property (nonatomic, copy, readonly) NSArray *> *shapes; +@property (nonatomic, copy, readonly) NS_ARRAY_OF(MGLShape *) *shapes; -+ (instancetype)shapeCollectionWithShapes:(NSArray *> *)shapes; ++ (instancetype)shapeCollectionWithShapes:(NS_ARRAY_OF(MGLShape *) *)shapes; @end diff --git a/platform/darwin/src/MGLFeature.mm b/platform/darwin/src/MGLFeature.mm index 02f67dca6e..ee2c71be21 100644 --- a/platform/darwin/src/MGLFeature.mm +++ b/platform/darwin/src/MGLFeature.mm @@ -233,7 +233,7 @@ MGL_DEFINE_FEATURE_IS_EQUAL(); @dynamic shapes; -+ (instancetype)shapeCollectionWithShapes:(NSArray *> *)shapes { ++ (instancetype)shapeCollectionWithShapes:(NS_ARRAY_OF(MGLShape *) *)shapes { return [super shapeCollectionWithShapes:shapes]; } @@ -373,7 +373,7 @@ public: } }; -NSArray *> *MGLFeaturesFromMBGLFeatures(const std::vector &features) { +NS_ARRAY_OF(MGLShape *) *MGLFeaturesFromMBGLFeatures(const std::vector &features) { NSMutableArray *shapes = [NSMutableArray arrayWithCapacity:features.size()]; for (const auto &feature : features) { [shapes addObject:MGLFeatureFromMBGLFeature(feature)]; @@ -414,7 +414,7 @@ mbgl::Feature mbglFeature(mbgl::Feature feature, id identifier, NSDictionary *at return feature; } -NSDictionary *NSDictionaryFeatureForGeometry(NSDictionary *geometry, NSDictionary *attributes, id identifier) { +NS_DICTIONARY_OF(NSString *, id) *NSDictionaryFeatureForGeometry(NSDictionary *geometry, NSDictionary *attributes, id identifier) { NSMutableDictionary *feature = [@{@"type": @"Feature", @"properties": (attributes) ?: [NSNull null], @"geometry": geometry} mutableCopy]; diff --git a/platform/darwin/src/MGLFeature_Private.h b/platform/darwin/src/MGLFeature_Private.h index d4074b53ed..4137200b98 100644 --- a/platform/darwin/src/MGLFeature_Private.h +++ b/platform/darwin/src/MGLFeature_Private.h @@ -13,7 +13,7 @@ NS_ASSUME_NONNULL_BEGIN vector tile features. */ MGL_EXPORT -NSArray *> *MGLFeaturesFromMBGLFeatures(const std::vector &features); +NS_ARRAY_OF(MGLShape *) *MGLFeaturesFromMBGLFeatures(const std::vector &features); /** Returns an `MGLFeature` object converted from the given mbgl::Feature @@ -36,7 +36,7 @@ mbgl::Feature mbglFeature(mbgl::Feature feature, id identifier, NSDictionary *at /** Returns an `NSDictionary` representation of an `MGLFeature`. */ -NSDictionary *NSDictionaryFeatureForGeometry(NSDictionary *geometry, NSDictionary *attributes, id identifier); +NS_DICTIONARY_OF(NSString *, id) *NSDictionaryFeatureForGeometry(NSDictionary *geometry, NSDictionary *attributes, id identifier); NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLMultiPoint.mm b/platform/darwin/src/MGLMultiPoint.mm index d4518e3d8f..75638fec97 100644 --- a/platform/darwin/src/MGLMultiPoint.mm +++ b/platform/darwin/src/MGLMultiPoint.mm @@ -70,7 +70,7 @@ return _coordinates.size(); } -+ (NSSet *)keyPathsForValuesAffectingPointCount ++ (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingPointCount { return [NSSet setWithObjects:@"coordinates", nil]; } diff --git a/platform/darwin/src/MGLOfflineStorage.h b/platform/darwin/src/MGLOfflineStorage.h index d512c60845..9260dda1c0 100644 --- a/platform/darwin/src/MGLOfflineStorage.h +++ b/platform/darwin/src/MGLOfflineStorage.h @@ -249,7 +249,7 @@ MGL_EXPORT `packs` property, observe KVO change notifications on the `packs` key path. The initial load results in an `NSKeyValueChangeSetting` change. */ -@property (nonatomic, strong, readonly, nullable) NSArray *packs; +@property (nonatomic, strong, readonly, nullable) NS_ARRAY_OF(MGLOfflinePack *) *packs; /** Creates and registers an offline pack that downloads the resources needed to diff --git a/platform/darwin/src/MGLOfflineStorage.mm b/platform/darwin/src/MGLOfflineStorage.mm index fd6dd2f998..608be18db9 100644 --- a/platform/darwin/src/MGLOfflineStorage.mm +++ b/platform/darwin/src/MGLOfflineStorage.mm @@ -34,7 +34,7 @@ const MGLExceptionName MGLUnsupportedRegionTypeException = @"MGLUnsupportedRegio @interface MGLOfflineStorage () -@property (nonatomic, strong, readwrite) NSMutableArray *packs; +@property (nonatomic, strong, readwrite) NS_MUTABLE_ARRAY_OF(MGLOfflinePack *) *packs; @property (nonatomic) mbgl::DefaultFileSource *mbglFileSource; @property (nonatomic, getter=isPaused) BOOL paused; @@ -245,7 +245,7 @@ const MGLExceptionName MGLUnsupportedRegionTypeException = @"MGLUnsupportedRegio _mbglFileSource = nullptr; } -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NS_DICTIONARY_OF(NSString *, id) *)change context:(void *)context { // Synchronize the file source’s access token with the global one in MGLAccountManager. if ([keyPath isEqualToString:@"accessToken"] && object == [MGLAccountManager sharedManager]) { NSString *accessToken = change[NSKeyValueChangeNewKey]; @@ -421,7 +421,7 @@ const MGLExceptionName MGLUnsupportedRegionTypeException = @"MGLUnsupportedRegio } - (void)reloadPacks { - [self getPacksWithCompletionHandler:^(NSArray *packs, __unused NSError * _Nullable error) { + [self getPacksWithCompletionHandler:^(NS_ARRAY_OF(MGLOfflinePack *) *packs, __unused NSError * _Nullable error) { for (MGLOfflinePack *pack in self.packs) { [pack invalidate]; } @@ -429,7 +429,7 @@ const MGLExceptionName MGLUnsupportedRegionTypeException = @"MGLUnsupportedRegio }]; } -- (void)getPacksWithCompletionHandler:(void (^)(NSArray *packs, NSError * _Nullable error))completion { +- (void)getPacksWithCompletionHandler:(void (^)(NS_ARRAY_OF(MGLOfflinePack *) *packs, NSError * _Nullable error))completion { self.mbglFileSource->listOfflineRegions([&, completion](mbgl::expected result) { NSError *error; NSMutableArray *packs; diff --git a/platform/darwin/src/MGLPolygon.h b/platform/darwin/src/MGLPolygon.h index 810a8b78ae..190b6df9c5 100644 --- a/platform/darwin/src/MGLPolygon.h +++ b/platform/darwin/src/MGLPolygon.h @@ -57,7 +57,7 @@ MGL_EXPORT If there are no interior polygons, the value of this property is `nil`. */ -@property (nonatomic, nullable, readonly) NSArray *interiorPolygons; +@property (nonatomic, nullable, readonly) NS_ARRAY_OF(MGLPolygon *) *interiorPolygons; /** Creates and returns an `MGLPolygon` object from the specified set of @@ -82,7 +82,7 @@ MGL_EXPORT is considered to have no interior polygons. @return A new polygon object. */ -+ (instancetype)polygonWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count interiorPolygons:(nullable NSArray *)interiorPolygons; ++ (instancetype)polygonWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count interiorPolygons:(nullable NS_ARRAY_OF(MGLPolygon *) *)interiorPolygons; @end @@ -109,7 +109,7 @@ MGL_EXPORT /** An array of polygons forming the multipolygon. */ -@property (nonatomic, copy, readonly) NSArray *polygons; +@property (nonatomic, copy, readonly) NS_ARRAY_OF(MGLPolygon *) *polygons; /** Creates and returns a multipolygon object consisting of the given polygons. @@ -117,7 +117,7 @@ MGL_EXPORT @param polygons The array of polygons defining the shape. @return A new multipolygon object. */ -+ (instancetype)multiPolygonWithPolygons:(NSArray *)polygons; ++ (instancetype)multiPolygonWithPolygons:(NS_ARRAY_OF(MGLPolygon *) *)polygons; @end diff --git a/platform/darwin/src/MGLPolygon.mm b/platform/darwin/src/MGLPolygon.mm index b80504707b..2af768d514 100644 --- a/platform/darwin/src/MGLPolygon.mm +++ b/platform/darwin/src/MGLPolygon.mm @@ -102,7 +102,7 @@ @"coordinates": self.mgl_coordinates}; } -- (NSArray *)mgl_coordinates { +- (NS_ARRAY_OF(id) *)mgl_coordinates { NSMutableArray *coordinates = [NSMutableArray array]; NSMutableArray *exteriorRing = [NSMutableArray array]; @@ -128,7 +128,7 @@ @interface MGLMultiPolygon () -@property (nonatomic, copy, readwrite) NSArray *polygons; +@property (nonatomic, copy, readwrite) NS_ARRAY_OF(MGLPolygon *) *polygons; @end @@ -138,11 +138,11 @@ @synthesize overlayBounds = _overlayBounds; -+ (instancetype)multiPolygonWithPolygons:(NSArray *)polygons { ++ (instancetype)multiPolygonWithPolygons:(NS_ARRAY_OF(MGLPolygon *) *)polygons { return [[self alloc] initWithPolygons:polygons]; } -- (instancetype)initWithPolygons:(NSArray *)polygons { +- (instancetype)initWithPolygons:(NS_ARRAY_OF(MGLPolygon *) *)polygons { if (self = [super init]) { _polygons = polygons; diff --git a/platform/darwin/src/MGLPolygon_Private.h b/platform/darwin/src/MGLPolygon_Private.h index b006f2d77f..75afcd61f6 100644 --- a/platform/darwin/src/MGLPolygon_Private.h +++ b/platform/darwin/src/MGLPolygon_Private.h @@ -4,7 +4,7 @@ NS_ASSUME_NONNULL_BEGIN @interface MGLPolygon (Private) -- (NSArray *)mgl_coordinates; +- (NS_ARRAY_OF(id) *)mgl_coordinates; @end diff --git a/platform/darwin/src/MGLPolyline.h b/platform/darwin/src/MGLPolyline.h index 8e9007686b..b1fca5bf28 100644 --- a/platform/darwin/src/MGLPolyline.h +++ b/platform/darwin/src/MGLPolyline.h @@ -92,7 +92,7 @@ MGL_EXPORT /** An array of polygons forming the multipolyline. */ -@property (nonatomic, copy, readonly) NSArray *polylines; +@property (nonatomic, copy, readonly) NS_ARRAY_OF(MGLPolyline *) *polylines; /** Creates and returns a multipolyline object consisting of the given polylines. @@ -100,7 +100,7 @@ MGL_EXPORT @param polylines The array of polylines defining the shape. @return A new multipolyline object. */ -+ (instancetype)multiPolylineWithPolylines:(NSArray *)polylines; ++ (instancetype)multiPolylineWithPolylines:(NS_ARRAY_OF(MGLPolyline *) *)polylines; @end diff --git a/platform/darwin/src/MGLPolyline.mm b/platform/darwin/src/MGLPolyline.mm index a028db8176..26e3518cd8 100644 --- a/platform/darwin/src/MGLPolyline.mm +++ b/platform/darwin/src/MGLPolyline.mm @@ -49,7 +49,7 @@ @"coordinates": self.mgl_coordinates}; } -- (NSArray *)mgl_coordinates { +- (NS_ARRAY_OF(id) *)mgl_coordinates { NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:self.pointCount]; for (NSUInteger index = 0; index < self.pointCount; index++) { CLLocationCoordinate2D coordinate = self.coordinates[index]; @@ -123,7 +123,7 @@ @interface MGLMultiPolyline () -@property (nonatomic, copy, readwrite) NSArray *polylines; +@property (nonatomic, copy, readwrite) NS_ARRAY_OF(MGLPolyline *) *polylines; @end @@ -133,11 +133,11 @@ @synthesize overlayBounds = _overlayBounds; -+ (instancetype)multiPolylineWithPolylines:(NSArray *)polylines { ++ (instancetype)multiPolylineWithPolylines:(NS_ARRAY_OF(MGLPolyline *) *)polylines { return [[self alloc] initWithPolylines:polylines]; } -- (instancetype)initWithPolylines:(NSArray *)polylines { +- (instancetype)initWithPolylines:(NS_ARRAY_OF(MGLPolyline *) *)polylines { if (self = [super init]) { _polylines = polylines; diff --git a/platform/darwin/src/MGLPolyline_Private.h b/platform/darwin/src/MGLPolyline_Private.h index ff4fabaa78..405a0c5bc9 100644 --- a/platform/darwin/src/MGLPolyline_Private.h +++ b/platform/darwin/src/MGLPolyline_Private.h @@ -4,7 +4,7 @@ NS_ASSUME_NONNULL_BEGIN @interface MGLPolyline (Private) -- (NSArray *)mgl_coordinates; +- (NS_ARRAY_OF(id) *)mgl_coordinates; @end diff --git a/platform/darwin/src/MGLRasterTileSource.h b/platform/darwin/src/MGLRasterTileSource.h index 8f00be0ea4..a72417142a 100644 --- a/platform/darwin/src/MGLRasterTileSource.h +++ b/platform/darwin/src/MGLRasterTileSource.h @@ -127,7 +127,7 @@ MGL_EXPORT the default values. @return An initialized tile source. */ -- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NSArray *)tileURLTemplates options:(nullable NSDictionary *)options NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NS_ARRAY_OF(NSString *) *)tileURLTemplates options:(nullable NS_DICTIONARY_OF(MGLTileSourceOption, id) *)options NS_DESIGNATED_INITIALIZER; @end diff --git a/platform/darwin/src/MGLRasterTileSource.mm b/platform/darwin/src/MGLRasterTileSource.mm index 61e9ef97fd..02cfef4ae8 100644 --- a/platform/darwin/src/MGLRasterTileSource.mm +++ b/platform/darwin/src/MGLRasterTileSource.mm @@ -44,7 +44,7 @@ static const CGFloat MGLRasterTileSourceRetinaTileSize = 512; uint16_t(round(tileSize))); } -- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NSArray *)tileURLTemplates options:(nullable NSDictionary *)options { +- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NS_ARRAY_OF(NSString *) *)tileURLTemplates options:(nullable NS_DICTIONARY_OF(MGLTileSourceOption, id) *)options { mbgl::Tileset tileSet = MGLTileSetFromTileURLTemplates(tileURLTemplates, options); uint16_t tileSize = MGLRasterTileSourceRetinaTileSize; diff --git a/platform/darwin/src/MGLShapeCollection.h b/platform/darwin/src/MGLShapeCollection.h index 08f3276496..bec482ca61 100644 --- a/platform/darwin/src/MGLShapeCollection.h +++ b/platform/darwin/src/MGLShapeCollection.h @@ -40,7 +40,7 @@ MGL_EXPORT /** An array of shapes forming the shape collection. */ -@property (nonatomic, copy, readonly) NSArray *shapes; +@property (nonatomic, copy, readonly) NS_ARRAY_OF(MGLShape *) *shapes; /** Creates and returns a shape collection consisting of the given shapes. @@ -49,7 +49,7 @@ MGL_EXPORT this array is copied to the new object. @return A new shape collection object. */ -+ (instancetype)shapeCollectionWithShapes:(NSArray *)shapes; ++ (instancetype)shapeCollectionWithShapes:(NS_ARRAY_OF(MGLShape *) *)shapes; @end diff --git a/platform/darwin/src/MGLShapeCollection.mm b/platform/darwin/src/MGLShapeCollection.mm index 5db1ee335c..454b0d47f1 100644 --- a/platform/darwin/src/MGLShapeCollection.mm +++ b/platform/darwin/src/MGLShapeCollection.mm @@ -7,11 +7,11 @@ @implementation MGLShapeCollection -+ (instancetype)shapeCollectionWithShapes:(NSArray *)shapes { ++ (instancetype)shapeCollectionWithShapes:(NS_ARRAY_OF(MGLShape *) *)shapes { return [[self alloc] initWithShapes:shapes]; } -- (instancetype)initWithShapes:(NSArray *)shapes { +- (instancetype)initWithShapes:(NS_ARRAY_OF(MGLShape *) *)shapes { if (self = [super init]) { _shapes = shapes.copy; } diff --git a/platform/darwin/src/MGLShapeSource.h b/platform/darwin/src/MGLShapeSource.h index c80c329cbc..f6c892a2a6 100644 --- a/platform/darwin/src/MGLShapeSource.h +++ b/platform/darwin/src/MGLShapeSource.h @@ -166,7 +166,7 @@ MGL_EXPORT @param options An `NSDictionary` of options for this source. @return An initialized shape source. */ -- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url options:(nullable NSDictionary *)options NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url options:(nullable NS_DICTIONARY_OF(MGLShapeSourceOption, id) *)options NS_DESIGNATED_INITIALIZER; /** Returns a shape source with an identifier, a shape, and dictionary of options @@ -195,7 +195,7 @@ MGL_EXPORT @param options An `NSDictionary` of options for this source. @return An initialized shape source. */ -- (instancetype)initWithIdentifier:(NSString *)identifier shape:(nullable MGLShape *)shape options:(nullable NSDictionary *)options NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithIdentifier:(NSString *)identifier shape:(nullable MGLShape *)shape options:(nullable NS_DICTIONARY_OF(MGLShapeSourceOption, id) *)options NS_DESIGNATED_INITIALIZER; /** Returns a shape source with an identifier, an array of features, and a dictionary @@ -222,7 +222,7 @@ MGL_EXPORT @param options An `NSDictionary` of options for this source. @return An initialized shape source. */ -- (instancetype)initWithIdentifier:(NSString *)identifier features:(NSArray *> *)features options:(nullable NSDictionary *)options; +- (instancetype)initWithIdentifier:(NSString *)identifier features:(NS_ARRAY_OF(MGLShape *) *)features options:(nullable NS_DICTIONARY_OF(MGLShapeSourceOption, id) *)options; /** Returns a shape source with an identifier, an array of shapes, and a dictionary of @@ -250,7 +250,7 @@ MGL_EXPORT @param options An `NSDictionary` of options for this source. @return An initialized shape source. */ -- (instancetype)initWithIdentifier:(NSString *)identifier shapes:(NSArray *)shapes options:(nullable NSDictionary *)options; +- (instancetype)initWithIdentifier:(NSString *)identifier shapes:(NS_ARRAY_OF(MGLShape *) *)shapes options:(nullable NS_DICTIONARY_OF(MGLShapeSourceOption, id) *)options; #pragma mark Accessing a Source’s Content @@ -303,7 +303,7 @@ MGL_EXPORT @return An array of objects conforming to the `MGLFeature` protocol that represent features in the source that match the predicate. */ -- (NSArray> *)featuresMatchingPredicate:(nullable NSPredicate *)predicate; +- (NS_ARRAY_OF(id ) *)featuresMatchingPredicate:(nullable NSPredicate *)predicate; @end diff --git a/platform/darwin/src/MGLShapeSource.mm b/platform/darwin/src/MGLShapeSource.mm index c960f2a4a7..29f80d1f24 100644 --- a/platform/darwin/src/MGLShapeSource.mm +++ b/platform/darwin/src/MGLShapeSource.mm @@ -22,7 +22,7 @@ const MGLShapeSourceOption MGLShapeSourceOptionMinimumZoomLevel = @"MGLShapeSour const MGLShapeSourceOption MGLShapeSourceOptionSimplificationTolerance = @"MGLShapeSourceOptionSimplificationTolerance"; const MGLShapeSourceOption MGLShapeSourceOptionLineDistanceMetrics = @"MGLShapeSourceOptionLineDistanceMetrics"; -mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary *options) { +mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NS_DICTIONARY_OF(MGLShapeSourceOption, id) *options) { auto geoJSONOptions = mbgl::style::GeoJSONOptions(); if (NSNumber *value = options[MGLShapeSourceOptionMinimumZoomLevel]) { @@ -101,7 +101,7 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary *)options { +- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url options:(NS_DICTIONARY_OF(NSString *, id) *)options { auto geoJSONOptions = MGLGeoJSONOptionsFromDictionary(options); auto source = std::make_unique(identifier.UTF8String, geoJSONOptions); if (self = [super initWithPendingSource:std::move(source)]) { @@ -110,7 +110,7 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary *)options { +- (instancetype)initWithIdentifier:(NSString *)identifier shape:(nullable MGLShape *)shape options:(NS_DICTIONARY_OF(MGLShapeSourceOption, id) *)options { auto geoJSONOptions = MGLGeoJSONOptionsFromDictionary(options); auto source = std::make_unique(identifier.UTF8String, geoJSONOptions); if (self = [super initWithPendingSource:std::move(source)]) { @@ -127,7 +127,7 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary *> *)features options:(nullable NSDictionary *)options { +- (instancetype)initWithIdentifier:(NSString *)identifier features:(NS_ARRAY_OF(MGLShape *) *)features options:(nullable NS_DICTIONARY_OF(MGLShapeSourceOption, id) *)options { for (id feature in features) { if (![feature conformsToProtocol:@protocol(MGLFeature)]) { [NSException raise:NSInvalidArgumentException format:@"The object %@ included in the features argument does not conform to the MGLFeature protocol.", feature]; @@ -137,7 +137,7 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary *)shapes options:(nullable NSDictionary *)options { +- (instancetype)initWithIdentifier:(NSString *)identifier shapes:(NS_ARRAY_OF(MGLShape *) *)shapes options:(nullable NS_DICTIONARY_OF(MGLShapeSourceOption, id) *)options { MGLShapeCollection *shapeCollection = [MGLShapeCollection shapeCollectionWithShapes:shapes]; return [self initWithIdentifier:identifier shape:shapeCollection options:options]; } @@ -170,7 +170,7 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary> *)featuresMatchingPredicate:(nullable NSPredicate *)predicate { +- (NS_ARRAY_OF(id ) *)featuresMatchingPredicate:(nullable NSPredicate *)predicate { mbgl::optional optionalFilter; if (predicate) { diff --git a/platform/darwin/src/MGLShapeSource_Private.h b/platform/darwin/src/MGLShapeSource_Private.h index 83872afcbc..0720074d1d 100644 --- a/platform/darwin/src/MGLShapeSource_Private.h +++ b/platform/darwin/src/MGLShapeSource_Private.h @@ -10,6 +10,6 @@ namespace mbgl { } MGL_EXPORT -mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary *options); +mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NS_DICTIONARY_OF(MGLShapeSourceOption, id) *options); NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLStyle.h b/platform/darwin/src/MGLStyle.h index 7b62432d36..60535b5a15 100644 --- a/platform/darwin/src/MGLStyle.h +++ b/platform/darwin/src/MGLStyle.h @@ -247,7 +247,7 @@ MGL_EXPORT /** A set containing the style’s sources. */ -@property (nonatomic, strong) NSSet<__kindof MGLSource *> *sources; +@property (nonatomic, strong) NS_SET_OF(__kindof MGLSource *) *sources; /** Values describing animated transitions to changes on a style's individual @@ -309,7 +309,7 @@ MGL_EXPORT The layers included in the style, arranged according to their back-to-front ordering on the screen. */ -@property (nonatomic, strong) NSArray<__kindof MGLStyleLayer *> *layers; +@property (nonatomic, strong) NS_ARRAY_OF(__kindof MGLStyleLayer *) *layers; /** Returns a style layer with the given identifier in the current style. @@ -423,7 +423,7 @@ MGL_EXPORT #pragma mark Managing Style Classes -@property (nonatomic) NSArray *styleClasses __attribute__((unavailable("Support for style classes has been removed."))); +@property (nonatomic) NS_ARRAY_OF(NSString *) *styleClasses __attribute__((unavailable("Support for style classes has been removed."))); - (BOOL)hasStyleClass:(NSString *)styleClass __attribute__((unavailable("Support for style classes has been removed."))); diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm index 88499cf9bb..5915280f04 100644 --- a/platform/darwin/src/MGLStyle.mm +++ b/platform/darwin/src/MGLStyle.mm @@ -88,8 +88,8 @@ const MGLExceptionName MGLRedundantSourceIdentifierException = @"MGLRedundantSou @property (nonatomic, readonly, weak) MGLMapView *mapView; @property (nonatomic, readonly) mbgl::style::Style *rawStyle; @property (readonly, copy, nullable) NSURL *URL; -@property (nonatomic, readwrite, strong) NSMutableDictionary *openGLLayers; -@property (nonatomic) NSMutableDictionary *> *localizedLayersByIdentifier; +@property (nonatomic, readwrite, strong) NS_MUTABLE_DICTIONARY_OF(NSString *, MGLOpenGLStyleLayer *) *openGLLayers; +@property (nonatomic) NS_MUTABLE_DICTIONARY_OF(NSString *, NS_DICTIONARY_OF(NSObject *, MGLTextLanguage *) *) *localizedLayersByIdentifier; @end @@ -148,9 +148,9 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, #pragma mark Sources -- (NSSet<__kindof MGLSource *> *)sources { +- (NS_SET_OF(__kindof MGLSource *) *)sources { auto rawSources = self.rawStyle->getSources(); - NSMutableSet<__kindof MGLSource *> *sources = [NSMutableSet setWithCapacity:rawSources.size()]; + NS_MUTABLE_SET_OF(__kindof MGLSource *) *sources = [NSMutableSet setWithCapacity:rawSources.size()]; for (auto rawSource = rawSources.begin(); rawSource != rawSources.end(); ++rawSource) { MGLSource *source = [self sourceFromMBGLSource:*rawSource]; [sources addObject:source]; @@ -158,7 +158,7 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, return sources; } -- (void)setSources:(NSSet<__kindof MGLSource *> *)sources { +- (void)setSources:(NS_SET_OF(__kindof MGLSource *) *)sources { for (MGLSource *source in self.sources) { [self removeSource:source]; } @@ -251,10 +251,10 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, #pragma mark Style layers -- (NSArray<__kindof MGLStyleLayer *> *)layers +- (NS_ARRAY_OF(__kindof MGLStyleLayer *) *)layers { auto layers = self.rawStyle->getLayers(); - NSMutableArray<__kindof MGLStyleLayer *> *styleLayers = [NSMutableArray arrayWithCapacity:layers.size()]; + NS_MUTABLE_ARRAY_OF(__kindof MGLStyleLayer *) *styleLayers = [NSMutableArray arrayWithCapacity:layers.size()]; for (auto layer : layers) { MGLStyleLayer *styleLayer = [self layerFromMBGLLayer:layer]; [styleLayers addObject:styleLayer]; @@ -262,7 +262,7 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, return styleLayers; } -- (void)setLayers:(NSArray<__kindof MGLStyleLayer *> *)layers { +- (void)setLayers:(NS_ARRAY_OF(__kindof MGLStyleLayer *) *)layers { for (MGLStyleLayer *layer in self.layers) { [self removeLayer:layer]; } @@ -600,13 +600,13 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, } } -- (NSSet *)mapboxStreetsSources { +- (NS_SET_OF(MGLVectorTileSource *) *)mapboxStreetsSources { return [self.sources objectsPassingTest:^BOOL (__kindof MGLVectorTileSource * _Nonnull source, BOOL * _Nonnull stop) { return [source isKindOfClass:[MGLVectorTileSource class]] && source.mapboxStreets; }]; } -- (NSArray *)placeStyleLayers { +- (NS_ARRAY_OF(MGLStyleLayer *) *)placeStyleLayers { NSSet *streetsSourceIdentifiers = [self.mapboxStreetsSources valueForKey:@"identifier"]; NSSet *placeSourceLayerIdentifiers = [NSSet setWithObjects:@"marine_label", @"country_label", @"state_label", @"place_label", @"water_label", @"poi_label", @"rail_station_label", @"mountain_peak_label", nil]; @@ -616,7 +616,7 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, return [self.layers filteredArrayUsingPredicate:isPlacePredicate]; } -- (NSArray *)roadStyleLayers { +- (NS_ARRAY_OF(MGLStyleLayer *) *)roadStyleLayers { NSSet *streetsSourceIdentifiers = [self.mapboxStreetsSources valueForKey:@"identifier"]; NSPredicate *isPlacePredicate = [NSPredicate predicateWithBlock:^BOOL (MGLVectorStyleLayer * _Nullable layer, NSDictionary * _Nullable bindings) { diff --git a/platform/darwin/src/MGLStyle_Private.h b/platform/darwin/src/MGLStyle_Private.h index 1294b9ad1c..24466b8018 100644 --- a/platform/darwin/src/MGLStyle_Private.h +++ b/platform/darwin/src/MGLStyle_Private.h @@ -24,16 +24,16 @@ namespace mbgl { @property (nonatomic, readonly, weak) MGLMapView *mapView; @property (nonatomic, readonly) mbgl::style::Style *rawStyle; -- (nullable NSArray *)attributionInfosWithFontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor; -@property (nonatomic, readonly, strong) NSMutableDictionary *openGLLayers; -- (void)setStyleClasses:(NSArray *)appliedClasses transitionDuration:(NSTimeInterval)transitionDuration; +- (nullable NS_ARRAY_OF(MGLAttributionInfo *) *)attributionInfosWithFontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor; +@property (nonatomic, readonly, strong) NS_MUTABLE_DICTIONARY_OF(NSString *, MGLOpenGLStyleLayer *) *openGLLayers; +- (void)setStyleClasses:(NS_ARRAY_OF(NSString *) *)appliedClasses transitionDuration:(NSTimeInterval)transitionDuration; @end @interface MGLStyle (MGLStreetsAdditions) -@property (nonatomic, readonly, copy) NSArray *placeStyleLayers; -@property (nonatomic, readonly, copy) NSArray *roadStyleLayers; +@property (nonatomic, readonly, copy) NS_ARRAY_OF(MGLVectorStyleLayer *) *placeStyleLayers; +@property (nonatomic, readonly, copy) NS_ARRAY_OF(MGLVectorStyleLayer *) *roadStyleLayers; @end diff --git a/platform/darwin/src/MGLTileSource.h b/platform/darwin/src/MGLTileSource.h index 0d8b118ec6..501b077653 100644 --- a/platform/darwin/src/MGLTileSource.h +++ b/platform/darwin/src/MGLTileSource.h @@ -199,7 +199,7 @@ MGL_EXPORT configuration URL, this array is also empty until the configuration JSON file is loaded. */ -@property (nonatomic, copy, readonly) NSArray *attributionInfos; +@property (nonatomic, copy, readonly) NS_ARRAY_OF(MGLAttributionInfo *) *attributionInfos; @end diff --git a/platform/darwin/src/MGLTileSource.mm b/platform/darwin/src/MGLTileSource.mm index eef3b33430..ab803857df 100644 --- a/platform/darwin/src/MGLTileSource.mm +++ b/platform/darwin/src/MGLTileSource.mm @@ -30,11 +30,11 @@ const MGLTileSourceOption MGLTileSourceOptionDEMEncoding = @"MGLTileSourceOption return nil; } -- (NSArray *)attributionInfos { +- (NS_ARRAY_OF(MGLAttributionInfo *) *)attributionInfos { return [self attributionInfosWithFontSize:0 linkColor:nil]; } -- (NSArray *)attributionInfosWithFontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor { +- (NS_ARRAY_OF(MGLAttributionInfo *) *)attributionInfosWithFontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor { return [MGLAttributionInfo attributionInfosFromHTMLString:self.attributionHTMLString fontSize:fontSize linkColor:linkColor]; @@ -48,7 +48,7 @@ const MGLTileSourceOption MGLTileSourceOptionDEMEncoding = @"MGLTileSourceOption @end -mbgl::Tileset MGLTileSetFromTileURLTemplates(NSArray *tileURLTemplates, NSDictionary * _Nullable options) { +mbgl::Tileset MGLTileSetFromTileURLTemplates(NS_ARRAY_OF(NSString *) *tileURLTemplates, NS_DICTIONARY_OF(MGLTileSourceOption, id) * _Nullable options) { mbgl::Tileset tileSet; for (NSString *tileURLTemplate in tileURLTemplates) { diff --git a/platform/darwin/src/MGLTileSource_Private.h b/platform/darwin/src/MGLTileSource_Private.h index 1b260ca86a..0d9876d412 100644 --- a/platform/darwin/src/MGLTileSource_Private.h +++ b/platform/darwin/src/MGLTileSource_Private.h @@ -28,11 +28,11 @@ namespace mbgl { @param fontSize The default text size in points, or 0 to use the default. @param linkColor The default link color, or `nil` to use the default. */ -- (NSArray *)attributionInfosWithFontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor; +- (NS_ARRAY_OF(MGLAttributionInfo *) *)attributionInfosWithFontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor; @end MGL_EXPORT -mbgl::Tileset MGLTileSetFromTileURLTemplates(NSArray *tileURLTemplates, NSDictionary * _Nullable options); +mbgl::Tileset MGLTileSetFromTileURLTemplates(NS_ARRAY_OF(NSString *) *tileURLTemplates, NS_DICTIONARY_OF(MGLTileSourceOption, id) * _Nullable options); NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLTypes.h b/platform/darwin/src/MGLTypes.h index 035c6f6593..a98b521759 100644 --- a/platform/darwin/src/MGLTypes.h +++ b/platform/darwin/src/MGLTypes.h @@ -112,3 +112,24 @@ NS_INLINE MGLTransition MGLTransitionMake(NSTimeInterval duration, NSTimeInterva } NS_ASSUME_NONNULL_END + +#ifndef NS_ARRAY_OF + +// Foundation collection classes adopted lightweight generics in iOS 9.0 and OS X 10.11 SDKs. +#if __has_feature(objc_generics) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101100) +/** Inserts a type specifier for a pointer to a lightweight generic with the given collection and object classes. Use a `*` for any non-`id` object classes but no `*` for the collection class. */ +#define NS_ARRAY_OF(ObjectClass...) NSArray +#define NS_MUTABLE_ARRAY_OF(ObjectClass...) NSMutableArray +#define NS_SET_OF(ObjectClass...) NSSet +#define NS_MUTABLE_SET_OF(ObjectClass...) NSMutableSet +#define NS_DICTIONARY_OF(ObjectClass...) NSDictionary +#define NS_MUTABLE_DICTIONARY_OF(ObjectClass...) NSMutableDictionary +#else +#define NS_ARRAY_OF(ObjectClass...) NSArray +#define NS_MUTABLE_ARRAY_OF(ObjectClass...) NSMutableArray +#define NS_SET_OF(ObjectClass...) NSSet +#define NS_MUTABLE_SET_OF(ObjectClass...) NSMutableSet +#define NS_DICTIONARY_OF(ObjectClass...) NSDictionary +#define NS_MUTABLE_DICTIONARY_OF(ObjectClass...) NSMutableDictionary +#endif +#endif diff --git a/platform/darwin/src/MGLVectorTileSource.h b/platform/darwin/src/MGLVectorTileSource.h index 70d2f6e8ec..790c9d4d42 100644 --- a/platform/darwin/src/MGLVectorTileSource.h +++ b/platform/darwin/src/MGLVectorTileSource.h @@ -99,7 +99,7 @@ MGL_EXPORT the default values. @return An initialized tile source. */ -- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NSArray *)tileURLTemplates options:(nullable NSDictionary *)options NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NS_ARRAY_OF(NSString *) *)tileURLTemplates options:(nullable NS_DICTIONARY_OF(MGLTileSourceOption, id) *)options NS_DESIGNATED_INITIALIZER; #pragma mark Accessing a Source’s Content @@ -138,7 +138,7 @@ MGL_EXPORT @return An array of objects conforming to the `MGLFeature` protocol that represent features loaded by the source that match the predicate. */ -- (NSArray> *)featuresInSourceLayersWithIdentifiers:(NSSet *)sourceLayerIdentifiers predicate:(nullable NSPredicate *)predicate NS_SWIFT_NAME(features(sourceLayerIdentifiers:predicate:)); +- (NS_ARRAY_OF(id ) *)featuresInSourceLayersWithIdentifiers:(NS_SET_OF(NSString *) *)sourceLayerIdentifiers predicate:(nullable NSPredicate *)predicate NS_SWIFT_NAME(features(sourceLayerIdentifiers:predicate:)); @end diff --git a/platform/darwin/src/MGLVectorTileSource.mm b/platform/darwin/src/MGLVectorTileSource.mm index a3241d3bce..c751d1e313 100644 --- a/platform/darwin/src/MGLVectorTileSource.mm +++ b/platform/darwin/src/MGLVectorTileSource.mm @@ -27,7 +27,7 @@ return self = [super initWithPendingSource:std::move(source)]; } -- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NSArray *)tileURLTemplates options:(nullable NSDictionary *)options { +- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NS_ARRAY_OF(NSString *) *)tileURLTemplates options:(nullable NS_DICTIONARY_OF(MGLTileSourceOption, id) *)options { mbgl::Tileset tileSet = MGLTileSetFromTileURLTemplates(tileURLTemplates, options); auto source = std::make_unique(identifier.UTF8String, tileSet); return self = [super initWithPendingSource:std::move(source)]; @@ -47,7 +47,7 @@ return attribution ? @(attribution->c_str()) : nil; } -- (NSArray> *)featuresInSourceLayersWithIdentifiers:(NSSet *)sourceLayerIdentifiers predicate:(nullable NSPredicate *)predicate { +- (NS_ARRAY_OF(id ) *)featuresInSourceLayersWithIdentifiers:(NS_SET_OF(NSString *) *)sourceLayerIdentifiers predicate:(nullable NSPredicate *)predicate { mbgl::optional> optionalSourceLayerIDs; if (sourceLayerIdentifiers) { @@ -95,9 +95,9 @@ static NSArray * const MGLMapboxStreetsAlternativeLanguages = @[ @"zh-Hans", ]; -+ (NSSet *)mapboxStreetsLanguages { ++ (NS_SET_OF(NSString *) *)mapboxStreetsLanguages { static dispatch_once_t onceToken; - static NSSet *mapboxStreetsLanguages; + static NS_SET_OF(NSString *) *mapboxStreetsLanguages; dispatch_once(&onceToken, ^{ mapboxStreetsLanguages = [NSSet setWithArray:MGLMapboxStreetsLanguages]; }); diff --git a/platform/darwin/src/MGLVectorTileSource_Private.h b/platform/darwin/src/MGLVectorTileSource_Private.h index 8d287ae4c4..109f66a432 100644 --- a/platform/darwin/src/MGLVectorTileSource_Private.h +++ b/platform/darwin/src/MGLVectorTileSource_Private.h @@ -6,7 +6,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly, getter=isMapboxStreets) BOOL mapboxStreets; -+ (NSSet *)mapboxStreetsLanguages; ++ (NS_SET_OF(NSString *) *)mapboxStreetsLanguages; + (nullable NSString *)preferredMapboxStreetsLanguage; + (nullable NSString *)preferredMapboxStreetsLanguageForPreferences:(NSArray *)preferencesArray; diff --git a/platform/darwin/src/NSBundle+MGLAdditions.h b/platform/darwin/src/NSBundle+MGLAdditions.h index dcafefedec..ba4e33564f 100644 --- a/platform/darwin/src/NSBundle+MGLAdditions.h +++ b/platform/darwin/src/NSBundle+MGLAdditions.h @@ -36,7 +36,7 @@ FOUNDATION_EXTERN MGL_EXPORT MGLExceptionName const MGLBundleNotFoundException; + (nullable NSString *)mgl_frameworkBundleIdentifier; -+ (nullable NSDictionary *)mgl_frameworkInfoDictionary; ++ (nullable NS_DICTIONARY_OF(NSString *, id) *)mgl_frameworkInfoDictionary; + (nullable NSString *)mgl_applicationBundleIdentifier; diff --git a/platform/darwin/src/NSBundle+MGLAdditions.m b/platform/darwin/src/NSBundle+MGLAdditions.m index d472e40b1f..f6e97a1780 100644 --- a/platform/darwin/src/NSBundle+MGLAdditions.m +++ b/platform/darwin/src/NSBundle+MGLAdditions.m @@ -28,7 +28,7 @@ const MGLExceptionName MGLBundleNotFoundException = @"MGLBundleNotFoundException return self.mgl_frameworkInfoDictionary[@"CFBundleIdentifier"]; } -+ (nullable NSDictionary *)mgl_frameworkInfoDictionary { ++ (nullable NS_DICTIONARY_OF(NSString *, id) *)mgl_frameworkInfoDictionary { NSBundle *bundle = self.mgl_frameworkBundle; return bundle.infoDictionary; } diff --git a/platform/darwin/src/NSExpression+MGLAdditions.h b/platform/darwin/src/NSExpression+MGLAdditions.h index d13f0227b4..358b004e78 100644 --- a/platform/darwin/src/NSExpression+MGLAdditions.h +++ b/platform/darwin/src/NSExpression+MGLAdditions.h @@ -175,6 +175,8 @@ FOUNDATION_EXTERN MGL_EXPORT const MGLExpressionInterpolationMode MGLExpressionI You can use `NSJSONSerialization` to serialize the Foundation object as data to write to a file. + +@note Note that the `length` argument is not currently supported with iOS 8. */ @property (nonatomic, readonly) id mgl_jsonExpressionObject; diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm index 58f5816416..3146872a27 100644 --- a/platform/darwin/src/NSExpression+MGLAdditions.mm +++ b/platform/darwin/src/NSExpression+MGLAdditions.mm @@ -559,7 +559,11 @@ const MGLExpressionInterpolationMode MGLExpressionInterpolationModeCubicBezier = } + (instancetype)mgl_expressionForConditional:(nonnull NSPredicate *)conditionPredicate trueExpression:(nonnull NSExpression *)trueExpression falseExpresssion:(nonnull NSExpression *)falseExpression { - return [NSExpression expressionForConditional:conditionPredicate trueExpression:trueExpression falseExpression:falseExpression]; + if (@available(iOS 9.0, *)) { + return [NSExpression expressionForConditional:conditionPredicate trueExpression:trueExpression falseExpression:falseExpression]; + } else { + return [NSExpression expressionForFunction:@"MGL_IF" arguments:@[[NSExpression expressionWithFormat:@"%@", conditionPredicate], trueExpression, falseExpression]]; + } } + (instancetype)mgl_expressionForSteppingExpression:(nonnull NSExpression *)steppingExpression fromExpression:(nonnull NSExpression *)minimumExpression stops:(nonnull NSExpression *)stops { @@ -834,11 +838,13 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) { [arguments addObject:[NSExpression expressionWithMGLJSONObject:argumentObjects[index]]]; } } - - if (arguments.count == 3) { - NSPredicate *conditional = [arguments.firstObject constantValue]; - return [NSExpression expressionForConditional:conditional trueExpression:arguments[1] falseExpression:arguments[2]]; + if (@available(iOS 9.0, *)) { + if (arguments.count == 3) { + NSPredicate *conditional = [arguments.firstObject constantValue]; + return [NSExpression expressionForConditional:conditional trueExpression:arguments[1] falseExpression:arguments[2]]; + } } + return [NSExpression expressionForFunction:@"MGL_IF" arguments:arguments]; } else if ([op isEqualToString:@"match"]) { NSMutableArray *optionsArray = [NSMutableArray array]; @@ -1341,7 +1347,7 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) { If no localization takes place, this method returns the original collection. */ -NSArray *MGLLocalizedCollection(NSArray *collection, NSLocale * _Nullable locale) { +NS_ARRAY_OF(NSExpression *) *MGLLocalizedCollection(NS_ARRAY_OF(NSExpression *) *collection, NSLocale * _Nullable locale) { __block NSMutableArray *localizedCollection; [collection enumerateObjectsUsingBlock:^(NSExpression * _Nonnull item, NSUInteger idx, BOOL * _Nonnull stop) { NSExpression *localizedItem = [item mgl_expressionLocalizedIntoLocale:locale]; @@ -1361,7 +1367,7 @@ NSArray *MGLLocalizedCollection(NSArray *collect If no localization takes place, this method returns the original stop dictionary. */ -NSDictionary *MGLLocalizedStopDictionary(NSDictionary *stops, NSLocale * _Nullable locale) { +NS_DICTIONARY_OF(NSNumber *, NSExpression *) *MGLLocalizedStopDictionary(NS_DICTIONARY_OF(NSNumber *, NSExpression *) *stops, NSLocale * _Nullable locale) { __block NSMutableDictionary *localizedStops; [stops enumerateKeysAndObjectsUsingBlock:^(id _Nonnull zoomLevel, NSExpression * _Nonnull value, BOOL * _Nonnull stop) { if (![value isKindOfClass:[NSExpression class]]) { @@ -1444,14 +1450,16 @@ NSDictionary *MGLLocalizedStopDictionary(NSDictionar } case NSConditionalExpressionType: { - NSExpression *trueExpression = self.trueExpression; - NSExpression *localizedTrueExpression = [trueExpression mgl_expressionLocalizedIntoLocale:locale]; - NSExpression *falseExpression = self.falseExpression; - NSExpression *localizedFalseExpression = [falseExpression mgl_expressionLocalizedIntoLocale:locale]; - if (localizedTrueExpression != trueExpression || localizedFalseExpression != falseExpression) { - return [NSExpression expressionForConditional:self.predicate - trueExpression:localizedTrueExpression - falseExpression:localizedFalseExpression]; + if (@available(iOS 9.0, *)) { + NSExpression *trueExpression = self.trueExpression; + NSExpression *localizedTrueExpression = [trueExpression mgl_expressionLocalizedIntoLocale:locale]; + NSExpression *falseExpression = self.falseExpression; + NSExpression *localizedFalseExpression = [falseExpression mgl_expressionLocalizedIntoLocale:locale]; + if (localizedTrueExpression != trueExpression || localizedFalseExpression != falseExpression) { + return [NSExpression expressionForConditional:self.predicate + trueExpression:localizedTrueExpression + falseExpression:localizedFalseExpression]; + } } return self; } diff --git a/platform/darwin/src/NSString+MGLAdditions.h b/platform/darwin/src/NSString+MGLAdditions.h index 4888c7a00f..98f870c598 100644 --- a/platform/darwin/src/NSString+MGLAdditions.h +++ b/platform/darwin/src/NSString+MGLAdditions.h @@ -26,6 +26,9 @@ NS_ASSUME_NONNULL_BEGIN Only supports scripts for languages used by Mapbox Streets. + @note On iOS 8 or older, this will method will always return the untransliterated + receiver. + @param script The four-letter code representing the name of the script, as specified by ISO 15924. */ diff --git a/platform/darwin/src/NSString+MGLAdditions.m b/platform/darwin/src/NSString+MGLAdditions.m index d645490eb3..f4d4738728 100644 --- a/platform/darwin/src/NSString+MGLAdditions.m +++ b/platform/darwin/src/NSString+MGLAdditions.m @@ -41,18 +41,22 @@ } - (NSString *)mgl_stringByTransliteratingIntoScript:(NSString *)script { - NSMutableString *string = self.mutableCopy; - NSStringTransform transform; - if ([script isEqualToString:@"Latn"]) { - transform = NSStringTransformToLatin; - } else if ([script isEqualToString:@"Hans"]) { - // No transform available. - } else if ([script isEqualToString:@"Cyrl"]) { - transform = @"Any-Latin; Latin-Cyrillic"; - } else if ([script isEqualToString:@"Arab"]) { - transform = @"Any-Latin; Latin-Arabic"; + if (@available(iOS 9.0, *)) { + NSMutableString *string = self.mutableCopy; + NSStringTransform transform; + if ([script isEqualToString:@"Latn"]) { + transform = NSStringTransformToLatin; + } else if ([script isEqualToString:@"Hans"]) { + // No transform available. + } else if ([script isEqualToString:@"Cyrl"]) { + transform = @"Any-Latin; Latin-Cyrillic"; + } else if ([script isEqualToString:@"Arab"]) { + transform = @"Any-Latin; Latin-Arabic"; + } + return transform ? [string stringByApplyingTransform:transform reverse:NO] : string; + } else { + return self; } - return transform ? [string stringByApplyingTransform:transform reverse:NO] : string; } @end diff --git a/platform/darwin/test/MGLCoordinateFormatterTests.m b/platform/darwin/test/MGLCoordinateFormatterTests.m index ac083fa103..07923b7e67 100644 --- a/platform/darwin/test/MGLCoordinateFormatterTests.m +++ b/platform/darwin/test/MGLCoordinateFormatterTests.m @@ -24,7 +24,12 @@ coordinate = CLLocationCoordinate2DMake(38.9131982, -77.0325453144239); XCTAssertEqualObjects([shortFormatter stringFromCoordinate:coordinate], @"38°54′48″N, 77°1′57″W"); XCTAssertEqualObjects([mediumFormatter stringFromCoordinate:coordinate], @"38°54′48″ north, 77°1′57″ west"); - XCTAssertEqualObjects([longFormatter stringFromCoordinate:coordinate], @"38 degrees, 54 minutes, and 48 seconds north by 77 degrees, 1 minute, and 57 seconds west"); + if (@available(iOS 9.0, *)) { + XCTAssertEqualObjects([longFormatter stringFromCoordinate:coordinate], @"38 degrees, 54 minutes, and 48 seconds north by 77 degrees, 1 minute, and 57 seconds west"); + } else { + // Foundation in iOS 8 does not know how to pluralize coordinates. + XCTAssertEqualObjects([longFormatter stringFromCoordinate:coordinate], @"38 degree(s), 54 minute(s), and 48 second(s) north by 77 degree(s), 1 minute(s), and 57 second(s) west"); + } shortFormatter.allowsSeconds = NO; mediumFormatter.allowsSeconds = NO; @@ -33,8 +38,14 @@ coordinate = CLLocationCoordinate2DMake(38.9131982, -77.0325453144239); XCTAssertEqualObjects([shortFormatter stringFromCoordinate:coordinate], @"38°55′N, 77°2′W"); XCTAssertEqualObjects([mediumFormatter stringFromCoordinate:coordinate], @"38°55′ north, 77°2′ west"); - XCTAssertEqualObjects([longFormatter stringFromCoordinate:coordinate], @"38 degrees and 55 minutes north by 77 degrees and 2 minutes west"); - + + if (@available(iOS 9.0, *)) { + XCTAssertEqualObjects([longFormatter stringFromCoordinate:coordinate], @"38 degrees and 55 minutes north by 77 degrees and 2 minutes west"); + } else { + // Foundation in iOS 8 does not know how to pluralize coordinates. + XCTAssertEqualObjects([longFormatter stringFromCoordinate:coordinate], @"38 degree(s) and 55 minute(s) north by 77 degree(s) and 2 minute(s) west"); + } + shortFormatter.allowsMinutes = NO; mediumFormatter.allowsMinutes = NO; longFormatter.allowsMinutes = NO; @@ -42,7 +53,12 @@ coordinate = CLLocationCoordinate2DMake(38.9131982, -77.0325453144239); XCTAssertEqualObjects([shortFormatter stringFromCoordinate:coordinate], @"39°N, 77°W"); XCTAssertEqualObjects([mediumFormatter stringFromCoordinate:coordinate], @"39° north, 77° west"); - XCTAssertEqualObjects([longFormatter stringFromCoordinate:coordinate], @"39 degrees north by 77 degrees west"); + if (@available(iOS 9.0, *)) { + XCTAssertEqualObjects([longFormatter stringFromCoordinate:coordinate], @"39 degrees north by 77 degrees west"); + } else { + // Foundation in iOS 8 does not know how to pluralize coordinates. + XCTAssertEqualObjects([longFormatter stringFromCoordinate:coordinate], @"39 degree(s) north by 77 degree(s) west"); + } } @end diff --git a/platform/darwin/test/MGLExpressionTests.mm b/platform/darwin/test/MGLExpressionTests.mm index 6cb7bfdc3d..7e091a7f05 100644 --- a/platform/darwin/test/MGLExpressionTests.mm +++ b/platform/darwin/test/MGLExpressionTests.mm @@ -620,10 +620,12 @@ using namespace std::string_literals; XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { - NSExpression *expression = [NSExpression expressionForFunction:@"length:" arguments:arguments]; - NSArray *jsonExpression = @[@"length", @"MacDonald"]; - XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + if (@available(iOS 9.0, *)) { + NSExpression *expression = [NSExpression expressionForFunction:@"length:" arguments:arguments]; + NSArray *jsonExpression = @[@"length", @"MacDonald"]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } } } @@ -824,66 +826,70 @@ using namespace std::string_literals; } - (void)testConditionalExpressionObject { - { - NSPredicate *conditional = [NSPredicate predicateWithFormat:@"1 = 2"]; - NSExpression *trueExpression = [NSExpression expressionForConstantValue:@YES]; - NSExpression *falseExpression = [NSExpression expressionForConstantValue:@NO]; - NSExpression *expression = [NSExpression expressionForConditional:conditional trueExpression:trueExpression falseExpression:falseExpression]; - NSArray *jsonExpression = @[@"case", @[@"==", @1, @2], @YES, @NO]; - XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression expressionWithFormat:@"TERNARY(1 = 2, TRUE, FALSE)"].mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @NO); - XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); - } - { - NSExpression *expression = [NSExpression expressionWithFormat:@"TERNARY(0 = 1, TRUE, TERNARY(1 = 2, TRUE, FALSE))"]; - NSArray *jsonExpression = @[@"case", @[@"==", @0, @1], @YES, @[@"==", @1, @2], @YES, @NO]; - XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @NO); - expression = [NSExpression expressionWithFormat:@"MGL_IF(%@, TRUE, %@, TRUE, FALSE)", - MGLConstantExpression([NSPredicate predicateWithFormat:@"0 = 1"]), - MGLConstantExpression([NSPredicate predicateWithFormat:@"1 = 2"])]; - XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); - } - { - NSExpression *expression = [NSExpression expressionWithFormat:@"MGL_IF(%@, %@, %@)", - [NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 2"]], - MGLConstantExpression(@YES), - MGLConstantExpression(@NO)]; - NSExpression *compatibilityExpression = [NSExpression expressionWithFormat:@"FUNCTION(%@, 'mgl_if:', %@)", [NSPredicate predicateWithFormat:@"1 = 2"], @[MGLConstantExpression(@YES), MGLConstantExpression(@NO)]]; - NSArray *jsonExpression = @[@"case", @[@"==", @1, @2], @YES, @NO]; - XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects(compatibilityExpression.mgl_jsonExpressionObject, jsonExpression); - expression = [NSExpression expressionWithFormat:@"TERNARY(1 = 2, YES, NO)"]; - XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); - XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @NO); - } - { - NSExpression *expression = [NSExpression expressionWithFormat:@"MGL_IF(%@, %@, %@, %@, %@)", - [NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 2"]], - MGLConstantExpression(@YES), - [NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 1"]], - MGLConstantExpression(@YES), - MGLConstantExpression(@NO)]; - NSArray *jsonExpression = @[@"case", @[@"==", @1, @2], @YES, @[@"==", @1, @1], @YES, @NO]; - XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); - XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @YES); - } - { - NSArray *jsonExpression = @[ - @"case", - @[ - @"<", - @[@"get", @"area"], - @80000 - ], - @[@"get", @"abbr"], - @[@"get", @"name_en"] - ]; - NSExpression *expression = [NSExpression expressionWithFormat:@"TERNARY(area < 80000, abbr, name_en)"]; - XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); - XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + // This test crashes on iOS 8, which doesn't have `+[NSExpression expressionForConditional:trueExpression:falseExpression:]`. + // https://github.com/mapbox/mapbox-gl-native/issues/11007 + if (@available(iOS 9.0, *)) { + { + NSPredicate *conditional = [NSPredicate predicateWithFormat:@"1 = 2"]; + NSExpression *trueExpression = [NSExpression expressionForConstantValue:@YES]; + NSExpression *falseExpression = [NSExpression expressionForConstantValue:@NO]; + NSExpression *expression = [NSExpression expressionForConditional:conditional trueExpression:trueExpression falseExpression:falseExpression]; + NSArray *jsonExpression = @[@"case", @[@"==", @1, @2], @YES, @NO]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithFormat:@"TERNARY(1 = 2, TRUE, FALSE)"].mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @NO); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionWithFormat:@"TERNARY(0 = 1, TRUE, TERNARY(1 = 2, TRUE, FALSE))"]; + NSArray *jsonExpression = @[@"case", @[@"==", @0, @1], @YES, @[@"==", @1, @2], @YES, @NO]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @NO); + expression = [NSExpression expressionWithFormat:@"MGL_IF(%@, TRUE, %@, TRUE, FALSE)", + MGLConstantExpression([NSPredicate predicateWithFormat:@"0 = 1"]), + MGLConstantExpression([NSPredicate predicateWithFormat:@"1 = 2"])]; + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionWithFormat:@"MGL_IF(%@, %@, %@)", + [NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 2"]], + MGLConstantExpression(@YES), + MGLConstantExpression(@NO)]; + NSExpression *compatibilityExpression = [NSExpression expressionWithFormat:@"FUNCTION(%@, 'mgl_if:', %@)", [NSPredicate predicateWithFormat:@"1 = 2"], @[MGLConstantExpression(@YES), MGLConstantExpression(@NO)]]; + NSArray *jsonExpression = @[@"case", @[@"==", @1, @2], @YES, @NO]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects(compatibilityExpression.mgl_jsonExpressionObject, jsonExpression); + expression = [NSExpression expressionWithFormat:@"TERNARY(1 = 2, YES, NO)"]; + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @NO); + } + { + NSExpression *expression = [NSExpression expressionWithFormat:@"MGL_IF(%@, %@, %@, %@, %@)", + [NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 2"]], + MGLConstantExpression(@YES), + [NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 1"]], + MGLConstantExpression(@YES), + MGLConstantExpression(@NO)]; + NSArray *jsonExpression = @[@"case", @[@"==", @1, @2], @YES, @[@"==", @1, @1], @YES, @NO]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @YES); + } + { + NSArray *jsonExpression = @[ + @"case", + @[ + @"<", + @[@"get", @"area"], + @80000 + ], + @[@"get", @"abbr"], + @[@"get", @"name_en"] + ]; + NSExpression *expression = [NSExpression expressionWithFormat:@"TERNARY(area < 80000, abbr, name_en)"]; + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + } } } @@ -963,7 +969,12 @@ using namespace std::string_literals; } { NSExpression *expression; - expression = [NSExpression expressionWithFormat:@"TERNARY(key != nil, 1, 0)"]; + if (@available(iOS 9.0, *)) { + expression = [NSExpression expressionWithFormat:@"TERNARY(key != nil, 1, 0)"]; + } else { + expression = [NSExpression expressionWithFormat:@"MGL_IF(%@, 1, 0)", + MGLConstantExpression([NSPredicate predicateWithFormat:@"key != nil"])]; + } NSArray *jsonExpression = @[@"case", @[@"!=", @[@"get", @"key"], [NSNull null]], @1, @0]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); @@ -973,7 +984,13 @@ using namespace std::string_literals; { NSDictionary *dictionary = @{@"key": @"🔑"}; NSExpression *expression; - expression = [NSExpression expressionWithFormat:@"TERNARY(%@.key != nil, 1, 0)", dictionary]; + if (@available(iOS 9.0, *)) { + expression = [NSExpression expressionWithFormat:@"TERNARY(%@.key != nil, 1, 0)", dictionary]; + } else { + NSPredicate *conditional = [NSPredicate predicateWithFormat:@"%@.key != nil", dictionary]; + expression = [NSExpression expressionWithFormat:@"MGL_IF(%@, 1, 0)", + MGLConstantExpression(conditional)]; + } NSArray *jsonExpression = @[@"case", @[@"!=", @[@"get", @"key", @[@"literal", dictionary]], [NSNull null]], @1, @0]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); // The dictionary isn’t equal enough. diff --git a/platform/darwin/test/MGLNSStringAdditionsTests.m b/platform/darwin/test/MGLNSStringAdditionsTests.m index a3ee7e3433..1fd0117b87 100644 --- a/platform/darwin/test/MGLNSStringAdditionsTests.m +++ b/platform/darwin/test/MGLNSStringAdditionsTests.m @@ -40,29 +40,31 @@ } - (void)testTransliteratedString { - XCTAssertEqualObjects([@"Portland" mgl_stringByTransliteratingIntoScript:@"Latn"], @"Portland"); - XCTAssertEqualObjects([@"Portland" mgl_stringByTransliteratingIntoScript:@"Hans"], @"Portland"); - XCTAssertEqualObjects([@"Portland" mgl_stringByTransliteratingIntoScript:@"Cyrl"], @"Портланд"); - XCTAssertEqualObjects([@"Portland" mgl_stringByTransliteratingIntoScript:@"Arab"], @"پُرتلَند"); - XCTAssertEqualObjects([@"Portland" mgl_stringByTransliteratingIntoScript:@"Fake"], @"Portland"); - - XCTAssertEqualObjects([@"北京" mgl_stringByTransliteratingIntoScript:@"Latn"], @"běi jīng"); - XCTAssertEqualObjects([@"北京" mgl_stringByTransliteratingIntoScript:@"Hans"], @"北京"); - XCTAssertEqualObjects([@"北京" mgl_stringByTransliteratingIntoScript:@"Cyrl"], @"бе̌и йӣнг"); - XCTAssertEqualObjects([@"北京" mgl_stringByTransliteratingIntoScript:@"Arab"], @"بِِ̌ جِينگ"); - XCTAssertEqualObjects([@"北京" mgl_stringByTransliteratingIntoScript:@"Fake"], @"北京"); - - XCTAssertEqualObjects([@"Mосква" mgl_stringByTransliteratingIntoScript:@"Latn"], @"Moskva"); - XCTAssertEqualObjects([@"Mосква" mgl_stringByTransliteratingIntoScript:@"Hans"], @"Mосква"); - XCTAssertEqualObjects([@"Mосква" mgl_stringByTransliteratingIntoScript:@"Cyrl"], @"Москва"); - XCTAssertEqualObjects([@"Mосква" mgl_stringByTransliteratingIntoScript:@"Arab"], @"مُسكڤَ"); - XCTAssertEqualObjects([@"Mосква" mgl_stringByTransliteratingIntoScript:@"Fake"], @"Mосква"); - - XCTAssertEqualObjects([@"ロンドン" mgl_stringByTransliteratingIntoScript:@"Latn"], @"rondon"); - XCTAssertEqualObjects([@"ロンドン" mgl_stringByTransliteratingIntoScript:@"Hans"], @"ロンドン"); - XCTAssertEqualObjects([@"ロンドン" mgl_stringByTransliteratingIntoScript:@"Cyrl"], @"рондон"); - XCTAssertEqualObjects([@"ロンドン" mgl_stringByTransliteratingIntoScript:@"Arab"], @"رُندُن"); - XCTAssertEqualObjects([@"ロンドン" mgl_stringByTransliteratingIntoScript:@"Fake"], @"ロンドン"); + if (@available(iOS 9.0, *)) { + XCTAssertEqualObjects([@"Portland" mgl_stringByTransliteratingIntoScript:@"Latn"], @"Portland"); + XCTAssertEqualObjects([@"Portland" mgl_stringByTransliteratingIntoScript:@"Hans"], @"Portland"); + XCTAssertEqualObjects([@"Portland" mgl_stringByTransliteratingIntoScript:@"Cyrl"], @"Портланд"); + XCTAssertEqualObjects([@"Portland" mgl_stringByTransliteratingIntoScript:@"Arab"], @"پُرتلَند"); + XCTAssertEqualObjects([@"Portland" mgl_stringByTransliteratingIntoScript:@"Fake"], @"Portland"); + + XCTAssertEqualObjects([@"北京" mgl_stringByTransliteratingIntoScript:@"Latn"], @"běi jīng"); + XCTAssertEqualObjects([@"北京" mgl_stringByTransliteratingIntoScript:@"Hans"], @"北京"); + XCTAssertEqualObjects([@"北京" mgl_stringByTransliteratingIntoScript:@"Cyrl"], @"бе̌и йӣнг"); + XCTAssertEqualObjects([@"北京" mgl_stringByTransliteratingIntoScript:@"Arab"], @"بِِ̌ جِينگ"); + XCTAssertEqualObjects([@"北京" mgl_stringByTransliteratingIntoScript:@"Fake"], @"北京"); + + XCTAssertEqualObjects([@"Mосква" mgl_stringByTransliteratingIntoScript:@"Latn"], @"Moskva"); + XCTAssertEqualObjects([@"Mосква" mgl_stringByTransliteratingIntoScript:@"Hans"], @"Mосква"); + XCTAssertEqualObjects([@"Mосква" mgl_stringByTransliteratingIntoScript:@"Cyrl"], @"Москва"); + XCTAssertEqualObjects([@"Mосква" mgl_stringByTransliteratingIntoScript:@"Arab"], @"مُسكڤَ"); + XCTAssertEqualObjects([@"Mосква" mgl_stringByTransliteratingIntoScript:@"Fake"], @"Mосква"); + + XCTAssertEqualObjects([@"ロンドン" mgl_stringByTransliteratingIntoScript:@"Latn"], @"rondon"); + XCTAssertEqualObjects([@"ロンドン" mgl_stringByTransliteratingIntoScript:@"Hans"], @"ロンドン"); + XCTAssertEqualObjects([@"ロンドン" mgl_stringByTransliteratingIntoScript:@"Cyrl"], @"рондон"); + XCTAssertEqualObjects([@"ロンドン" mgl_stringByTransliteratingIntoScript:@"Arab"], @"رُندُن"); + XCTAssertEqualObjects([@"ロンドン" mgl_stringByTransliteratingIntoScript:@"Fake"], @"ロンドン"); + } } @end diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 6a53a367f7..e37fddc859 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -1,6 +1,9 @@ # Changelog for Mapbox Maps SDK for iOS Mapbox welcomes participation and contributions from everyone. Please read [CONTRIBUTING.md](../../CONTRIBUTING.md) to get started. +## ios8-release-gazpacho + +* Restored iOS 8 support for the Mapbox Maps SDK for iOS. ([#13036](https://github.com/mapbox/mapbox-gl-native/pull/13036)) ## 4.5.0 - October 10, 2018 @@ -23,7 +26,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Added `-[MGLOfflineStorage addContentsOfFile:withCompletionHandler:]` and `-[MGLOfflineStorage addContentsOfURL:withCompletionHandler:]` methods to add pregenerated offline packs to offline storage. ([#12791](https://github.com/mapbox/mapbox-gl-native/pull/12791)) * Fixed an issue where some tiles weren't rendered correctly when no internet connectivity was available ([#12931](https://github.com/mapbox/mapbox-gl-native/pull/12931)) -### Other changes +### Other changes * Added `MGLAltitudeForZoomLevel` and `MGLZoomLevelForAltitude` to public API for conversion between zoom levels and altitudes. ([#12986](https://github.com/mapbox/mapbox-gl-native/pull/12986)) * Deprecated the `+[MGLMapCamera cameraLookingAtCenterCoordinate:fromDistance:pitch:heading:]` method in favor of `+[MGLMapCamera cameraLookingAtCenterCoordinate:altitude:pitch:heading:]` and `+[MGLMapCamera cameraLookingAtCenterCoordinate:acrossDistance:pitch:heading:]`. ([#12966](https://github.com/mapbox/mapbox-gl-native/pull/12966)) diff --git a/platform/ios/INSTALL.md b/platform/ios/INSTALL.md index 25dbc53bdc..c2fdc36fbe 100644 --- a/platform/ios/INSTALL.md +++ b/platform/ios/INSTALL.md @@ -4,7 +4,7 @@ This document explains how to build a development version of Mapbox Maps SDK for ### Requirements -The Mapbox Maps SDK for iOS is intended to run on iOS 9.0 and above on the following devices: +The Mapbox Maps SDK for iOS is intended to run on iOS 8.0 and above on the following devices: * iPhone 4s and above (5, 5c, 5s, 6, 6 Plus, 7, 7 Plus, 8, 8 Plus, X) * iPad 2 and above (3, 4, Mini, Air, Mini 2, Air 2, Pro) diff --git a/platform/ios/Integration Test Harness/Base.lproj/LaunchScreen.storyboard b/platform/ios/Integration Test Harness/Base.lproj/LaunchScreen.storyboard index f83f6fd581..820306196c 100644 --- a/platform/ios/Integration Test Harness/Base.lproj/LaunchScreen.storyboard +++ b/platform/ios/Integration Test Harness/Base.lproj/LaunchScreen.storyboard @@ -1,8 +1,11 @@ - - + + + + + - - + + @@ -10,11 +13,14 @@ + + + + - diff --git a/platform/ios/Mapbox-iOS-SDK-nightly-dynamic.podspec b/platform/ios/Mapbox-iOS-SDK-nightly-dynamic.podspec index 3d0c38ffae..16318e1462 100644 --- a/platform/ios/Mapbox-iOS-SDK-nightly-dynamic.podspec +++ b/platform/ios/Mapbox-iOS-SDK-nightly-dynamic.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |m| } m.platform = :ios - m.ios.deployment_target = '9.0' + m.ios.deployment_target = '8.0' m.requires_arc = true diff --git a/platform/ios/Mapbox-iOS-SDK-static-part.podspec b/platform/ios/Mapbox-iOS-SDK-static-part.podspec index b82c2bb24f..072d82364a 100644 --- a/platform/ios/Mapbox-iOS-SDK-static-part.podspec +++ b/platform/ios/Mapbox-iOS-SDK-static-part.podspec @@ -1,4 +1,4 @@ - m.ios.deployment_target = '9.0' + m.ios.deployment_target = '8.0' m.requires_arc = true diff --git a/platform/ios/Mapbox-iOS-SDK-symbols.podspec b/platform/ios/Mapbox-iOS-SDK-symbols.podspec index 91087cc8a5..75e0f3ffee 100644 --- a/platform/ios/Mapbox-iOS-SDK-symbols.podspec +++ b/platform/ios/Mapbox-iOS-SDK-symbols.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |m| } m.platform = :ios - m.ios.deployment_target = '9.0' + m.ios.deployment_target = '8.0' m.requires_arc = true diff --git a/platform/ios/Mapbox-iOS-SDK.podspec b/platform/ios/Mapbox-iOS-SDK.podspec index 237d4bd360..fd7dca1d2e 100644 --- a/platform/ios/Mapbox-iOS-SDK.podspec +++ b/platform/ios/Mapbox-iOS-SDK.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |m| } m.platform = :ios - m.ios.deployment_target = '9.0' + m.ios.deployment_target = '8.0' m.requires_arc = true diff --git a/platform/ios/README.md b/platform/ios/README.md index 27c8ad4cc8..ad7d522456 100644 --- a/platform/ios/README.md +++ b/platform/ios/README.md @@ -2,6 +2,8 @@ [![Circle CI build status](https://circleci.com/gh/mapbox/mapbox-gl-native.svg?style=shield)](https://circleci.com/gh/mapbox/workflows/mapbox-gl-native/tree/master) +**Please note:** This is branch restores iOS 8 support to iOS SDK v4.5.0. There will be minimal maintenance for this branch. If iOS 8 support is not needed, please use the [latest release](https://github.com/mapbox/mapbox-gl-native/releases) of the Maps SDK for iOS. There are no plans to restore iOS 8 support to `master`. + A library based on [Mapbox GL Native](../../README.md) for embedding interactive map views with scalable, customizable vector maps into Cocoa Touch applications on iOS using Objective-C, Swift, or Interface Builder. This repository is for day-to-day development of the SDK. Building the SDK yourself requires [a number of dependencies and steps](../../INSTALL.md) that are unnecessary for developing production applications. For production applications, please consider installing an official, prebuilt release instead; see the [Mapbox iOS SDK website](https://www.mapbox.com/ios-sdk/) for installation instructions. diff --git a/platform/ios/app/MBXOfflinePacksTableViewController.m b/platform/ios/app/MBXOfflinePacksTableViewController.m index 959ae57548..46a032dae7 100644 --- a/platform/ios/app/MBXOfflinePacksTableViewController.m +++ b/platform/ios/app/MBXOfflinePacksTableViewController.m @@ -119,8 +119,10 @@ static NSString * const MBXOfflinePacksTableViewActiveCellReuseIdentifier = @"Ac }]; }]; [alertController addAction:downloadAction]; - alertController.preferredAction = downloadAction; - + if ([UIAlertController respondsToSelector:@selector(preferredAction)]) { + alertController.preferredAction = downloadAction; + } + [self presentViewController:alertController animated:YES completion:nil]; } diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m index 7642cf1bc0..42bfd01d42 100644 --- a/platform/ios/app/MBXViewController.m +++ b/platform/ios/app/MBXViewController.m @@ -237,7 +237,9 @@ CLLocationCoordinate2D randomWorldCoordinate() { self.debugLoggingEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"MGLMapboxMetricsDebugLoggingEnabled"]; self.mapView.showsScale = YES; self.mapView.showsUserHeadingIndicator = YES; - self.hudLabel.titleLabel.font = [UIFont monospacedDigitSystemFontOfSize:10 weight:UIFontWeightRegular]; + if ([UIFont respondsToSelector:@selector(monospacedDigitSystemFontOfSize:weight:)]) { + self.hudLabel.titleLabel.font = [UIFont monospacedDigitSystemFontOfSize:10 weight:UIFontWeightRegular]; + } if ([MGLAccountManager accessToken].length) { @@ -267,7 +269,10 @@ CLLocationCoordinate2D randomWorldCoordinate() { [self.mapView reloadStyle:self]; }]; [alertController addAction:OKAction]; - alertController.preferredAction = OKAction; + if ([UIAlertController respondsToSelector:@selector(preferredAction)]) { + alertController.preferredAction = OKAction; + } + [self presentViewController:alertController animated:YES completion:nil]; } diff --git a/platform/ios/app/Main.storyboard b/platform/ios/app/Main.storyboard index 3e8a0ad02a..50d312e18a 100644 --- a/platform/ios/app/Main.storyboard +++ b/platform/ios/app/Main.storyboard @@ -1,15 +1,15 @@ - + - + + - @@ -17,6 +17,10 @@ + + + + @@ -63,7 +67,6 @@ - @@ -220,6 +223,10 @@ + + + + @@ -279,7 +286,7 @@ @@ -365,6 +371,10 @@ + + + + @@ -392,33 +402,32 @@ - - - - - + + + + + - - + + - + - + - + - @@ -437,11 +446,14 @@ + + + + - diff --git a/platform/ios/benchmark/MBXBenchViewController.mm b/platform/ios/benchmark/MBXBenchViewController.mm index 84c2790d50..23a22f3af1 100644 --- a/platform/ios/benchmark/MBXBenchViewController.mm +++ b/platform/ios/benchmark/MBXBenchViewController.mm @@ -76,8 +76,10 @@ [self startBenchmarkIteration]; }]; [alertController addAction:OKAction]; - alertController.preferredAction = OKAction; - + if ([UIAlertController respondsToSelector:@selector(preferredAction)]) { + alertController.preferredAction = OKAction; + } + [self presentViewController:alertController animated:YES completion:nil]; } } diff --git a/platform/ios/config.cmake b/platform/ios/config.cmake index 471c1183a5..8707fb8d12 100644 --- a/platform/ios/config.cmake +++ b/platform/ios/config.cmake @@ -1,7 +1,7 @@ set(USE_GLES2 ON) macro(initialize_ios_target target) - set_xcode_property(${target} IPHONEOS_DEPLOYMENT_TARGET "9.0") + set_xcode_property(${target} IPHONEOS_DEPLOYMENT_TARGET "8.0") set_xcode_property(${target} ENABLE_BITCODE "YES") set_xcode_property(${target} BITCODE_GENERATION_MODE bitcode) set_xcode_property(${target} ONLY_ACTIVE_ARCH $<$:YES>) diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index 0eaf4fc0a6..76f09e0948 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -3537,7 +3537,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -3592,7 +3592,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; @@ -3608,6 +3608,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "$(SRCROOT)/app/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.MapboxGL; PRODUCT_NAME = "Mapbox GL"; @@ -3621,6 +3622,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "$(SRCROOT)/app/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.MapboxGL; PRODUCT_NAME = "Mapbox GL"; @@ -3699,6 +3701,7 @@ ); INFOPLIST_FILE = framework/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; OTHER_CFLAGS = "-fvisibility=hidden"; OTHER_CPLUSPLUSFLAGS = ( @@ -3741,6 +3744,7 @@ ); INFOPLIST_FILE = framework/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LLVM_LTO = YES; OTHER_CFLAGS = "-fvisibility=hidden"; @@ -3858,6 +3862,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = "$(SRCROOT)/benchmark/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.bench; PRODUCT_NAME = "Bench GL"; @@ -3869,6 +3874,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = "$(SRCROOT)/benchmark/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.bench; PRODUCT_NAME = "Bench GL"; diff --git a/platform/ios/src/MGLMapAccessibilityElement.mm b/platform/ios/src/MGLMapAccessibilityElement.mm index c1cc5304d7..1426a28a2e 100644 --- a/platform/ios/src/MGLMapAccessibilityElement.mm +++ b/platform/ios/src/MGLMapAccessibilityElement.mm @@ -56,9 +56,11 @@ // may be in the local language, which may be written in another script. // Attempt to transform to the script of the preferred language, keeping // the original string if no transform exists or if transformation fails. - NSString *dominantScript = [NSOrthography mgl_dominantScriptForMapboxStreetsLanguage:languageCode]; - name = [name mgl_stringByTransliteratingIntoScript:dominantScript]; - + if (@available(iOS 9.0, *)) { + NSString *dominantScript = [NSOrthography mgl_dominantScriptForMapboxStreetsLanguage:languageCode]; + name = [name mgl_stringByTransliteratingIntoScript:dominantScript]; + } + self.accessibilityLabel = name; } return self; diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 7096c55a8c..a65ece1c6b 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -636,9 +636,11 @@ public: _glView.contentScaleFactor = [UIScreen instancesRespondToSelector:@selector(nativeScale)] ? [[UIScreen mainScreen] nativeScale] : [[UIScreen mainScreen] scale]; _glView.layer.opaque = _opaque; _glView.delegate = self; - - CAEAGLLayer *eaglLayer = MGL_OBJC_DYNAMIC_CAST(_glView.layer, CAEAGLLayer); - eaglLayer.presentsWithTransaction = YES; + + if (@available(iOS 9.0, *)) { + CAEAGLLayer *eaglLayer = MGL_OBJC_DYNAMIC_CAST(_glView.layer, CAEAGLLayer); + eaglLayer.presentsWithTransaction = YES; + } [_glView bindDrawable]; [self insertSubview:_glView atIndex:0]; diff --git a/platform/ios/src/MGLScaleBar.mm b/platform/ios/src/MGLScaleBar.mm index d69fb3e852..a180280adc 100644 --- a/platform/ios/src/MGLScaleBar.mm +++ b/platform/ios/src/MGLScaleBar.mm @@ -205,7 +205,11 @@ static const CGFloat MGLFeetPerMeter = 3.28084; #pragma mark - Convenience methods - (BOOL)usesRightToLeftLayout { - return [UIView userInterfaceLayoutDirectionForSemanticContentAttribute:self.superview.semanticContentAttribute] == UIUserInterfaceLayoutDirectionRightToLeft; + if ([self.superview respondsToSelector:@selector(semanticContentAttribute)]) { + return [UIView userInterfaceLayoutDirectionForSemanticContentAttribute:self.superview.semanticContentAttribute] == UIUserInterfaceLayoutDirectionRightToLeft; + } else { + return UIApplication.sharedApplication.userInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft; + } } - (BOOL)usesMetricSystem { diff --git a/platform/ios/test/MGLMapAccessibilityElementTests.m b/platform/ios/test/MGLMapAccessibilityElementTests.m index 916461e708..65a68c90f6 100644 --- a/platform/ios/test/MGLMapAccessibilityElementTests.m +++ b/platform/ios/test/MGLMapAccessibilityElementTests.m @@ -25,7 +25,12 @@ @"name_en": @"Цинциннати", }; element = [[MGLFeatureAccessibilityElement alloc] initWithAccessibilityContainer:self feature:feature]; - XCTAssertEqualObjects(element.accessibilityLabel, @"Cincinnati", @"Accessibility label should be romanized."); + + if (@available(iOS 9.0, *)) { + XCTAssertEqualObjects(element.accessibilityLabel, @"Cincinnati", @"Accessibility label should be romanized."); + } else { + XCTAssertEqualObjects(element.accessibilityLabel, @"Цинциннати", @"Accessibility label should not be romanized."); + } } - (void)testPlaceFeatureValues { diff --git a/platform/ios/test/MGLNSOrthographyAdditionsTests.m b/platform/ios/test/MGLNSOrthographyAdditionsTests.m index f30553e8f6..b53cdcc918 100644 --- a/platform/ios/test/MGLNSOrthographyAdditionsTests.m +++ b/platform/ios/test/MGLNSOrthographyAdditionsTests.m @@ -10,9 +10,11 @@ @implementation MGLNSOrthographyAdditionsTests - (void)testStreetsLanguages { - for (NSString *language in [MGLVectorTileSource mapboxStreetsLanguages]) { - NSString *dominantScript = [NSOrthography mgl_dominantScriptForMapboxStreetsLanguage:language]; - XCTAssertNotEqualObjects(dominantScript, @"Zyyy", @"Mapbox Streets languages should have dominant script"); + if (@available(iOS 11.0, *)) { + for (NSString *language in [MGLVectorTileSource mapboxStreetsLanguages]) { + NSString *dominantScript = [NSOrthography mgl_dominantScriptForMapboxStreetsLanguage:language]; + XCTAssertNotEqualObjects(dominantScript, @"Zyyy", @"Mapbox Streets languages should have dominant script"); + } } } -- cgit v1.2.1