Skip to content

Commit

Permalink
Cherry pick changes from mapbox-gl-native-ios. resolves #29
Browse files Browse the repository at this point in the history
  • Loading branch information
petr-pokorny-1 committed Feb 22, 2021
1 parent 62c6178 commit 80e98fd
Show file tree
Hide file tree
Showing 24 changed files with 999 additions and 54 deletions.
41 changes: 41 additions & 0 deletions platform/ios/platform/darwin/src/MGLEvent.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#import "MGLFoundation.h"

NS_ASSUME_NONNULL_BEGIN

/**
Type of event used when subscribing to and unsubscribing from an `MGLObservable`.
*/
typedef NSString *MGLEventType NS_TYPED_EXTENSIBLE_ENUM;

// TODO: Doc
FOUNDATION_EXPORT MGL_EXPORT MGLEventType const MGLEventTypeResourceRequest;


/**
Generic Event used when notifying an `MGLObserver`. This is not intended nor
expected to be created by the application developer. It will be provided as
part of an `MGLObservable` notification.
*/
MGL_EXPORT
@interface MGLEvent: NSObject

/// Type of an event. Matches an original event type used for a subscription.
@property (nonatomic, readonly, copy) MGLEventType type;

/// Timestamp taken at the time of an event creation, relative to the Unix epoch.
@property (nonatomic, readonly) NSTimeInterval begin;

/// Timestamp taken at the time of an event completion. For a non-interval
/// (single-shot) events, migth be equal to an event's `begin` timestamp.
/// Relative to the Unix epoch.
@property (nonatomic, readonly) NSTimeInterval end;

/// Generic property for the event's data. Supported types are: `NSNumber` (int64,
/// uint64, bool, double), `NSString`, `NSArray`, `NSDictionary`.
@property (nonatomic, readonly, copy) id data;

/// Test for equality. Note this compares all properties except `data`.
- (BOOL)isEqualToEvent:(MGLEvent *)otherEvent;
@end

NS_ASSUME_NONNULL_END
80 changes: 80 additions & 0 deletions platform/ios/platform/darwin/src/MGLEvent.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#import "MGLEvent_Private.h"
#import "MGLStyleValue_Private.h"

const MGLEventType MGLEventTypeResourceRequest = @"resource-request";

#pragma mark - Event

@implementation MGLEvent

- (instancetype)init {
[self doesNotRecognizeSelector:_cmd];
return nil;
}

- (instancetype)initWithEvent:(const mbgl::ObservableEvent&)event {
self = [super init];

if (!self)
return nil;

// mbgl::ObservableEvent timestamps do not use the system_clock, i.e. they
// are not relative to the Unix epoch, so we'll need to offset appropriately
auto systemClockNow = std::chrono::system_clock::now();
auto steadyClockNow = std::chrono::steady_clock::now();
auto begin = std::chrono::time_point_cast<std::chrono::system_clock::duration>(systemClockNow +
(event.begin - steadyClockNow));
auto end = std::chrono::time_point_cast<std::chrono::system_clock::duration>(systemClockNow +
(event.end - steadyClockNow));

auto beginTime = std::chrono::duration<double, std::ratio<1>>(begin.time_since_epoch()).count();
auto endTime = std::chrono::duration<double, std::ratio<1>>(end.time_since_epoch()).count();

_type = (MGLEventType)[NSString stringWithUTF8String:event.type.c_str()];
_begin = beginTime;
_end = endTime;

// From value.md
// Supported types are `int`, `uint`, `bool`, `double`, `array`, `object` and `string`.
_data = MGLJSONObjectFromMBGLValue(event.data);

return self;
}

- (NSString *)description {
return [NSString stringWithFormat:@"<%@: %p; type = %@, begin = %f, end = %f, data = %@>",
NSStringFromClass([self class]), (void *)self,
self.type,
self.begin,
self.end,
self.data];
}

#pragma mark - Equality

- (NSUInteger)hash {
return self.type.hash ^ @(self.begin).hash ^ @(self.end).hash;
}

- (BOOL)isEqualToEvent:(MGLEvent *)other {
if (self == other)
return YES;

// Ignore the value at this moment.
return ((self.type == other.type) &&
(self.begin == other.begin) &&
(self.end == other.end));
}

- (BOOL)isEqual:(id)other {
if (self == other)
return YES;

if (![other isKindOfClass:[MGLEvent class]]) {
return NO;
}

return [self isEqualToEvent:(MGLEvent*)other];
}

@end
11 changes: 11 additions & 0 deletions platform/ios/platform/darwin/src/MGLEvent_Private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#import <Foundation/Foundation.h>
#import "MGLEvent.h"
#include <mbgl/util/observable.hpp>

NS_ASSUME_NONNULL_BEGIN

@interface MGLEvent ()
- (instancetype)initWithEvent:(const mbgl::ObservableEvent&)event;
@end

NS_ASSUME_NONNULL_END
31 changes: 31 additions & 0 deletions platform/ios/platform/darwin/src/MGLLocationManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)setDesiredAccuracy:(CLLocationAccuracy)desiredAccuracy;

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
/**
Specifies the level of location accuracy the Maps SDK has permission to use.
@note If the value of this property is `CLAccuracyAuthorizationFullAccuracy`, you can set the
`MGLLocationManager.desiredAccuracy` property to any value. If the value is `CLAccuracyAuthorizationReducedAccuracy`,
setting `MGLLocationManager.desiredAccuracy` to a value other than` kCLLocationAccuracyReduced` has no effect on
the location information.
*/
- (CLAccuracyAuthorization)accuracyAuthorization API_AVAILABLE(ios(14));
#endif

/**
Specifies the type of user activity associated with the location updates.
Expand All @@ -78,6 +90,17 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)setActivityType:(CLActivityType)activityType;

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
/**
Requests the user's permission to temporarily use location update services
with full accuracy.
@note If the user turned off location accuracy you may use this method to
request full accuracy for a session.
*/
- (void)requestTemporaryFullAccuracyAuthorizationWithPurposeKey:(NSString *)purposeKey API_AVAILABLE(ios(14));
#endif

@required

/**
Expand Down Expand Up @@ -195,6 +218,14 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)locationManager:(id<MGLLocationManager>)manager
didFailWithError:(nonnull NSError *)error;
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
/**
Notifies the delegate that the location authorization status has changed.
@param manager The location manager reporting the change.
*/
- (void)locationManagerDidChangeAuthorization:(id<MGLLocationManager>)manager;
#endif

@optional

Expand Down
31 changes: 31 additions & 0 deletions platform/ios/platform/darwin/src/MGLLocationManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,16 @@ - (CLLocationAccuracy)desiredAccuracy {
}

- (CLAuthorizationStatus)authorizationStatus {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
if (@available(iOS 14.0, *)) {
return self.locationManager.authorizationStatus;
} else {
return kCLAuthorizationStatusNotDetermined;
}
#else
return [CLLocationManager authorizationStatus];
return [CLLocationManager authorizationStatus];
#endif
}

- (void)setActivityType:(CLActivityType)activityType {
Expand All @@ -49,6 +58,23 @@ - (CLActivityType)activityType {
return self.locationManager.activityType;
}

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
- (CLAccuracyAuthorization)accuracyAuthorization {
if (@available(iOS 14.0, *)) {
return self.locationManager.accuracyAuthorization;
} else {
return CLAccuracyAuthorizationFullAccuracy;
}
}

- (void)requestTemporaryFullAccuracyAuthorizationWithPurposeKey:(NSString *)purposeKey {
if (@available(iOS 14.0, *)) {
[self.locationManager requestTemporaryFullAccuracyAuthorizationWithPurposeKey:purposeKey];
}
}
#endif


- (void)dismissHeadingCalibrationDisplay {
[self.locationManager dismissHeadingCalibrationDisplay];
}
Expand Down Expand Up @@ -113,4 +139,9 @@ - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *
}
}

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
- (void)locationManagerDidChangeAuthorization:(CLLocationManager *)manager {
[self.delegate locationManagerDidChangeAuthorization:self];
}
#endif
@end
65 changes: 65 additions & 0 deletions platform/ios/platform/darwin/src/MGLObserver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#import "MGLFoundation.h"
#import "MGLEvent.h"

NS_ASSUME_NONNULL_BEGIN

#pragma mark -

/**
Base class for observers used to receive notifications from an `MGLObservable`.
Subclasses should only override `-[MGLObserver notifyWithEvent:]`.
*/
MGL_EXPORT
@interface MGLObserver: NSObject

/// A unique identifier that can be used to identify an observer.
@property (nonatomic, readonly) NSUInteger identifier;

/// Primary notification method.
- (void)notifyWithEvent:(MGLEvent*)event;

// TODO: document
- (BOOL)isEqualToObserver:(MGLObserver *)other;
@end


#pragma mark -

/**
Protocol that yypes that wish to support subscriptions for events should conform
to.
*/
MGL_EXPORT
@protocol MGLObservable

/**
Subscribes an `MGLObserver` to a provided set of event types.
`MGLObservable` will hold a strong reference to an `MGLObserver` instance,
therefore, in order to stop receiving notifications (and to avoid memory leaks),
the caller must call unsubscribe with the `MGLObserver` instance used for
the initial subscription.
@param observer an MGLObserver
@param events a set of event types to subscribe to.
*/
- (void)subscribeForObserver:(nonnull MGLObserver *)observer
events:(nonnull NSSet<MGLEventType> *)events;

/**
Unsubscribes an `MGLObserver` from a provided set of event types.
@param observer an MGLObserver
@param events a set of event types to unsubscribe from.
*/
- (void)unsubscribeForObserver:(nonnull MGLObserver *)observer
events:(nonnull NSSet<MGLEventType> *)events;
/**
Unsubscribes an `MGLObserver` from all events (and release the strong reference).
@param observer an MGLObserver
*/
- (void)unsubscribeForObserver:(nonnull MGLObserver *)observer;

@end

NS_ASSUME_NONNULL_END
Loading

0 comments on commit 80e98fd

Please sign in to comment.