From 844e0e4aec3285ec5cfde90422acd796bc4d7d39 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Wed, 27 Dec 2017 23:30:24 -0800 Subject: Apple platforms: properly guard API access when requesting location info requestAlwaysAuthorization and requestWhenInUseAuthorization are prohibited APIs on macOS, and the former is also prohibited API on tvOS. This means they are akin to private APIs and must not be called under any circumstances. The respondsToSelector calls are also removed as Qt no longer supports OS versions where thee methods are not available, and in any case such uses should be replaced with __builtin_available. Background location updates are also now made available on watchOS 4 and above. Change-Id: I817d69f4ec71b96f03dda42635d675499e8908c0 Reviewed-by: Gabriel de Dietrich --- src/plugins/position/corelocation/corelocation.pro | 2 +- .../corelocation/qgeopositioninfosource_cl.mm | 31 +++++++++++++--------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/plugins/position/corelocation/corelocation.pro b/src/plugins/position/corelocation/corelocation.pro index 947a1d0c..85a5aaed 100644 --- a/src/plugins/position/corelocation/corelocation.pro +++ b/src/plugins/position/corelocation/corelocation.pro @@ -1,6 +1,6 @@ TARGET = qtposition_cl -QT = core positioning +QT = core core-private positioning OBJECTIVE_SOURCES += \ qgeopositioninfosource_cl.mm \ diff --git a/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm b/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm index 3fac056e..94c5b807 100644 --- a/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm +++ b/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm @@ -40,6 +40,7 @@ #include #include #include +#include #include "qgeopositioninfosource_cl_p.h" @@ -141,15 +142,17 @@ bool QGeoPositionInfoSourceCL::enableLocationManager() if (!m_locationManager) { m_locationManager = [[CLLocationManager alloc] init]; -#ifdef Q_OS_IOS - NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary]; - if (id value = [infoDict objectForKey:@"UIBackgroundModes"]) { - if ([value isKindOfClass:[NSArray class]]) { - NSArray *modes = static_cast(value); - for (id mode in modes) { - if ([@"location" isEqualToString:mode]) { - m_locationManager.allowsBackgroundLocationUpdates = YES; - break; +#if defined(Q_OS_IOS) || defined(Q_OS_WATCHOS) + if (__builtin_available(watchOS 4.0, *)) { + NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary]; + if (id value = [infoDict objectForKey:@"UIBackgroundModes"]) { + if ([value isKindOfClass:[NSArray class]]) { + NSArray *modes = static_cast(value); + for (id mode in modes) { + if ([@"location" isEqualToString:mode]) { + m_locationManager.allowsBackgroundLocationUpdates = YES; + break; + } } } } @@ -162,10 +165,12 @@ bool QGeoPositionInfoSourceCL::enableLocationManager() // These two methods are new in iOS 8. They require NSLocationAlwaysUsageDescription // and NSLocationWhenInUseUsageDescription to be set in Info.plist to work (methods are // noop if there are no such entries in plist). - if ([m_locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) - [m_locationManager performSelector:@selector(requestAlwaysAuthorization)]; - if ([m_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) - [m_locationManager performSelector:@selector(requestWhenInUseAuthorization)]; +#ifndef Q_OS_MACOS +#ifndef Q_OS_TVOS + [m_locationManager requestAlwaysAuthorization]; +#endif + [m_locationManager requestWhenInUseAuthorization]; +#endif } return (m_locationManager != 0); -- cgit v1.2.1