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
Show file tree
Hide file tree
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
Expand Up @@ -10,6 +10,7 @@
#import "MGLPolyline+MGLAdditions.h"
#import "MGLPolygon+MGLAdditions.h"
#import "NSDictionary+MGLAdditions.h"
#import "NSArray+MGLAdditions.h"

#import "NSExpression+MGLAdditions.h"

Expand All @@ -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];
}
Expand All @@ -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];
}
Expand All @@ -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];
}
Expand All @@ -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];
}
Expand All @@ -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];
}
Expand All @@ -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];
}
Expand Down Expand Up @@ -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];
}
Expand Down
28 changes: 28 additions & 0 deletions platform/darwin/src/MGLFeature_Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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");
Expand Down
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>

Expand All @@ -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>",
Expand Down
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>
Expand All @@ -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];
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
55 changes: 55 additions & 0 deletions platform/darwin/src/MGLPolygon.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down
Loading