Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Make features and annotations conform to NSSecureCoding #6559

Merged
merged 1 commit into from
Dec 22, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions platform/darwin/src/MGLFeature.mm
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
#import "MGLPolyline+MGLAdditions.h"
#import "MGLPolygon+MGLAdditions.h"
#import "NSDictionary+MGLAdditions.h"
#import "NSArray+MGLAdditions.h"

#import "NSExpression+MGLAdditions.h"

@@ -25,6 +26,10 @@ @implementation MGLPointFeature
@synthesize identifier;
@synthesize attributes;

MGL_DEFINE_FEATURE_INIT_WITH_CODER();
MGL_DEFINE_FEATURE_ENCODE();
MGL_DEFINE_FEATURE_IS_EQUAL();

- (id)attributeForKey:(NSString *)key {
return self.attributes[key];
}
@@ -47,6 +52,10 @@ @implementation MGLPolylineFeature
@synthesize identifier;
@synthesize attributes;

MGL_DEFINE_FEATURE_INIT_WITH_CODER();
MGL_DEFINE_FEATURE_ENCODE();
MGL_DEFINE_FEATURE_IS_EQUAL();

- (id)attributeForKey:(NSString *)key {
return self.attributes[key];
}
@@ -69,6 +78,10 @@ @implementation MGLPolygonFeature
@synthesize identifier;
@synthesize attributes;

MGL_DEFINE_FEATURE_INIT_WITH_CODER();
MGL_DEFINE_FEATURE_ENCODE();
MGL_DEFINE_FEATURE_IS_EQUAL();

- (id)attributeForKey:(NSString *)key {
return self.attributes[key];
}
@@ -91,6 +104,10 @@ @implementation MGLPointCollectionFeature
@synthesize identifier;
@synthesize attributes;

MGL_DEFINE_FEATURE_INIT_WITH_CODER();
MGL_DEFINE_FEATURE_ENCODE();
MGL_DEFINE_FEATURE_IS_EQUAL();

- (id)attributeForKey:(NSString *)key {
return self.attributes[key];
}
@@ -113,6 +130,10 @@ @implementation MGLMultiPolylineFeature
@synthesize identifier;
@synthesize attributes;

MGL_DEFINE_FEATURE_INIT_WITH_CODER();
MGL_DEFINE_FEATURE_ENCODE();
MGL_DEFINE_FEATURE_IS_EQUAL();

- (id)attributeForKey:(NSString *)key {
return self.attributes[key];
}
@@ -135,6 +156,10 @@ @implementation MGLMultiPolygonFeature
@synthesize identifier;
@synthesize attributes;

MGL_DEFINE_FEATURE_INIT_WITH_CODER();
MGL_DEFINE_FEATURE_ENCODE();
MGL_DEFINE_FEATURE_IS_EQUAL();

- (id)attributeForKey:(NSString *)key {
return self.attributes[key];
}
@@ -163,6 +188,10 @@ + (instancetype)shapeCollectionWithShapes:(NSArray *)shapes {
return [super shapeCollectionWithShapes:shapes];
}

MGL_DEFINE_FEATURE_INIT_WITH_CODER();
MGL_DEFINE_FEATURE_ENCODE();
MGL_DEFINE_FEATURE_IS_EQUAL();

- (id)attributeForKey:(NSString *)key {
return self.attributes[key];
}
28 changes: 28 additions & 0 deletions platform/darwin/src/MGLFeature_Private.h
Original file line number Diff line number Diff line change
@@ -37,3 +37,31 @@ mbgl::Feature mbglFeature(mbgl::Feature feature, id identifier, NSDictionary *at
NS_DICTIONARY_OF(NSString *, id) *NSDictionaryFeatureForGeometry(NSDictionary *geometry, NSDictionary *attributes, id identifier);

NS_ASSUME_NONNULL_END

#define MGL_DEFINE_FEATURE_INIT_WITH_CODER() \
- (instancetype)initWithCoder:(NSCoder *)decoder { \
if (self = [super initWithCoder:decoder]) { \
NSSet<Class> *identifierClasses = [NSSet setWithArray:@[[NSString class], [NSNumber class]]]; \
identifier = [decoder decodeObjectOfClasses:identifierClasses forKey:@"identifier"]; \
attributes = [decoder decodeObjectOfClass:[NSDictionary class] forKey:@"attributes"]; \
} \
return self; \
}

#define MGL_DEFINE_FEATURE_ENCODE() \
- (void)encodeWithCoder:(NSCoder *)coder { \
[super encodeWithCoder:coder]; \
[coder encodeObject:identifier forKey:@"identifier"]; \
[coder encodeObject:attributes forKey:@"attributes"]; \
}

#define MGL_DEFINE_FEATURE_IS_EQUAL() \
- (BOOL)isEqual:(id)other { \
if (other == self) return YES; \
if (![other isKindOfClass:[self class]]) return NO; \
__typeof(self) otherFeature = other; \
return [super isEqual:other] && [self geoJSONObject] == [otherFeature geoJSONObject]; \
} \
- (NSUInteger)hash { \
return [super hash] + [[self geoJSONDictionary] hash]; \
}
38 changes: 35 additions & 3 deletions platform/darwin/src/MGLMultiPoint.mm
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
#import "MGLMultiPoint_Private.h"
#import "MGLGeometry_Private.h"
#import "MGLShape_Private.h"
#import "NSCoder+MGLAdditions.h"
#import "MGLTypes.h"

#include <mbgl/util/geo.hpp>
#include <mbgl/util/optional.hpp>

@implementation MGLMultiPoint
{
mbgl::optional<mbgl::LatLngBounds> _bounds;
@@ -27,6 +26,39 @@ - (instancetype)initWithCoordinates:(const CLLocationCoordinate2D *)coords count
return self;
}

- (instancetype)initWithCoder:(NSCoder *)decoder
{
if (self = [super initWithCoder:decoder]) {
_coordinates = [decoder mgl_decodeLocationCoordinates2DForKey:@"coordinates"];
}
return self;
}

- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
[coder mgl_encodeLocationCoordinates2D:_coordinates forKey:@"coordinates"];
}

- (BOOL)isEqual:(id)other
{
if (self == other) return YES;
if (![other isKindOfClass:[MGLMultiPoint class]]) return NO;

MGLMultiPoint *otherMultipoint = other;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if other is an instance of some other class that implements coordinates as an NSSet?

return ([super isEqual:otherMultipoint]
&& _coordinates == otherMultipoint->_coordinates);
}

- (NSUInteger)hash
{
NSUInteger hash = [super hash];
for (auto coord : _coordinates) {
hash += @(coord.latitude+coord.longitude).hash;
}
return hash;
}

- (CLLocationCoordinate2D)coordinate
{
NSAssert([self pointCount] > 0, @"A multipoint must have coordinates");
36 changes: 36 additions & 0 deletions platform/darwin/src/MGLPointAnnotation.mm
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#import "MGLPointAnnotation.h"

#import "MGLShape_Private.h"
#import "NSCoder+MGLAdditions.h"

#import <mbgl/util/geometry.hpp>

@@ -9,6 +10,41 @@ @implementation MGLPointAnnotation

@synthesize coordinate;

+ (BOOL)supportsSecureCoding
{
return YES;
}

- (instancetype)initWithCoder:(NSCoder *)coder
{
if (self = [super initWithCoder:coder]) {
self.coordinate = [coder decodeMGLCoordinateForKey:@"coordinate"];
}
return self;
}

- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
[coder encodeMGLCoordinate:coordinate forKey:@"coordinate"];
}

- (BOOL)isEqual:(id)other
{
if (other == self) return YES;
if (![other isKindOfClass:[MGLPointAnnotation class]]) return NO;

MGLPointAnnotation *otherAnnotation = other;
return ([super isEqual:other]
&& self.coordinate.latitude == otherAnnotation.coordinate.latitude
&& self.coordinate.longitude == otherAnnotation.coordinate.longitude);
}

- (NSUInteger)hash
{
return [super hash] + @(self.coordinate.latitude).hash + @(self.coordinate.longitude).hash;
}

- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p; title = %@; subtitle = %@; coordinate = %f, %f>",
42 changes: 34 additions & 8 deletions platform/darwin/src/MGLPointCollection.mm
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#import "MGLPointCollection_Private.h"
#import "MGLGeometry_Private.h"
#import "NSArray+MGLAdditions.h"

#import <mbgl/util/geojson.hpp>
#import <mbgl/util/geometry.hpp>
@@ -8,12 +9,10 @@

@implementation MGLPointCollection
{
MGLCoordinateBounds _overlayBounds;
mbgl::optional<mbgl::LatLngBounds> _bounds;
std::vector<CLLocationCoordinate2D> _coordinates;
}

@synthesize overlayBounds = _overlayBounds;

+ (instancetype)pointCollectionWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count
{
return [[self alloc] initWithCoordinates:coords count:count];
@@ -25,14 +24,41 @@ - (instancetype)initWithCoordinates:(const CLLocationCoordinate2D *)coords count
if (self)
{
_coordinates = { coords, coords + count };
}
return self;
}

- (nullable instancetype)initWithCoder:(NSCoder *)decoder {
if (self = [super initWithCoder:decoder]) {
NSArray *coordinates = [decoder decodeObjectOfClass:[NSArray class] forKey:@"coordinates"];
_coordinates = [coordinates mgl_coordinates];
}
return self;
}

- (void)encodeWithCoder:(NSCoder *)coder {
[super encodeWithCoder:coder];
[coder encodeObject:[NSArray mgl_coordinatesFromCoordinates:_coordinates] forKey:@"coordinates"];
}

- (BOOL)isEqual:(id)other {
if (self == other) return YES;
if (![other isKindOfClass:[MGLPointCollection class]]) return NO;

MGLPointCollection *otherCollection = (MGLPointCollection *)other;
return ([super isEqual:other]
&& ((![self geoJSONDictionary] && ![otherCollection geoJSONDictionary]) || [[self geoJSONDictionary] isEqualToDictionary:[otherCollection geoJSONDictionary]]));
}

- (MGLCoordinateBounds)overlayBounds {
if (!_bounds) {
mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty();
for (auto coordinate : _coordinates)
{
for (auto coordinate : _coordinates) {
bounds.extend(mbgl::LatLng(coordinate.latitude, coordinate.longitude));
}
_overlayBounds = MGLCoordinateBoundsFromLatLngBounds(bounds);
_bounds = bounds;
}
return self;
return MGLCoordinateBoundsFromLatLngBounds(*_bounds);
}

- (NSUInteger)pointCount
@@ -65,7 +91,7 @@ - (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range

- (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds
{
return MGLCoordinateBoundsIntersectsCoordinateBounds(_overlayBounds, overlayBounds);
return MGLCoordinateBoundsIntersectsCoordinateBounds(self.overlayBounds, overlayBounds);
}

- (mbgl::Geometry<double>)geometryObject
55 changes: 55 additions & 0 deletions platform/darwin/src/MGLPolygon.mm
Original file line number Diff line number Diff line change
@@ -28,6 +28,32 @@ - (instancetype)initWithCoordinates:(const CLLocationCoordinate2D *)coords count
return self;
}

- (instancetype)initWithCoder:(NSCoder *)decoder {
self = [super initWithCoder:decoder];
if (self) {
_interiorPolygons = [decoder decodeObjectOfClass:[NSArray class] forKey:@"interiorPolygons"];
}
return self;
}

- (void)encodeWithCoder:(NSCoder *)coder {
[super encodeWithCoder:coder];
[coder encodeObject:self.interiorPolygons forKey:@"interiorPolygons"];
}

- (BOOL)isEqual:(id)other {
if (self == other) return YES;
if (![other isKindOfClass:[MGLPolygon class]]) return NO;

MGLPolygon *otherPolygon = (MGLPolygon *)other;
return ([super isEqual:otherPolygon] &&
[[self geoJSONDictionary] isEqualToDictionary:[otherPolygon geoJSONDictionary]]);
}

- (NSUInteger)hash {
return [super hash] + [[self geoJSONDictionary] hash];
}

- (mbgl::LinearRing<double>)ring {
NSUInteger count = self.pointCount;
CLLocationCoordinate2D *coordinates = self.coordinates;
@@ -100,6 +126,35 @@ - (instancetype)initWithPolygons:(NS_ARRAY_OF(MGLPolygon *) *)polygons {
return self;
}

- (instancetype)initWithCoder:(NSCoder *)decoder {
if (self = [super initWithCoder:decoder]) {
_polygons = [decoder decodeObjectOfClass:[NSArray class] forKey:@"polygons"];
}
return self;
}

- (void)encodeWithCoder:(NSCoder *)coder {
[super encodeWithCoder:coder];
[coder encodeObject:_polygons forKey:@"polygons"];
}

- (BOOL)isEqual:(id)other {
if (self == other) return YES;
if (![other isKindOfClass:[MGLMultiPolygon class]]) return NO;

MGLMultiPolygon *otherMultiPolygon = other;
return [super isEqual:other]
&& [self.polygons isEqualToArray:otherMultiPolygon.polygons];
}

- (NSUInteger)hash {
NSUInteger hash = [super hash];
for (MGLPolygon *polygon in self.polygons) {
hash += [polygon hash];
}
return hash;
}

- (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds {
return MGLCoordinateBoundsIntersectsCoordinateBounds(_overlayBounds, overlayBounds);
}
Loading