forked from organicmaps/organicmaps
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapple_location_service.mm
112 lines (91 loc) · 2.89 KB
/
apple_location_service.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "platform/location_service.hpp"
#include "base/logging.hpp"
#include "base/macros.hpp"
#include "std/target_os.hpp"
#import <CoreLocation/CoreLocation.h>
class AppleLocationService;
@interface LocationManagerWrapper : NSObject <CLLocationManagerDelegate> {
@private
AppleLocationService * m_service;
}
- (id)initWithService:(AppleLocationService *) service;
@end
using namespace location;
#define ROUGH_ACCURACY kCLLocationAccuracyNearestTenMeters
class AppleLocationService : public LocationService
{
LocationManagerWrapper * m_objCppWrapper;
CLLocationManager * m_locationManager;
public:
AppleLocationService(LocationObserver & observer) : LocationService(observer)
{
m_objCppWrapper = [[LocationManagerWrapper alloc] initWithService:this];
m_locationManager = [[CLLocationManager alloc] init];
m_locationManager.delegate = m_objCppWrapper;
m_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
}
void OnLocationUpdate(GpsInfo const & info)
{
m_observer.OnLocationUpdated(info);
}
void OnDeniedError()
{
m_observer.OnLocationError(location::EDenied);
}
virtual void Start()
{
if (![CLLocationManager locationServicesEnabled])
{
// @TODO correctly handle situation in GUI when wifi is working and native is disabled
//m_observer.OnLocationStatusChanged(location::ENotSupported);
}
else
{
[m_locationManager startUpdatingLocation];
}
}
virtual void Stop()
{
[m_locationManager stopUpdatingLocation];
}
};
@implementation LocationManagerWrapper
- (id)initWithService:(AppleLocationService *) service
{
if ((self = [super init]))
m_service = service;
return self;
}
+ (void)location:(CLLocation *)location toGpsInfo:(GpsInfo &) info
{
info.m_horizontalAccuracy = location.horizontalAccuracy;
info.m_latitude = location.coordinate.latitude;
info.m_longitude = location.coordinate.longitude;
info.m_timestamp = [location.timestamp timeIntervalSince1970];
info.m_source = location::EAppleNative;
//info.m_verticalAccuracy = location.verticalAccuracy;
//info.m_altitude = location.altitude;
//info.m_course = location.course;
//info.m_speed = location.speed;
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray<CLLocation *> *)locations
{
UNUSED_VALUE(manager);
GpsInfo newInfo;
[LocationManagerWrapper location:locations.firstObject toGpsInfo:newInfo];
m_service->OnLocationUpdate(newInfo);
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
UNUSED_VALUE(manager);
LOG(LWARNING, ("locationManager failed with error", error.code, error.description.UTF8String));
if (error.code == kCLErrorDenied)
m_service->OnDeniedError();
}
@end
std::unique_ptr<location::LocationService> CreateAppleLocationService(LocationObserver & observer)
{
return std::make_unique<AppleLocationService>(observer);
}