8#include <CoreLocation/CoreLocation.h>
11@property (nonatomic, retain) CLLocationManager *
manager;
26 qCDebug(lcLocationPermission) <<
"Warming up location services";
27 [[CLLocationManager new] release];
39 std::deque<PermissionRequest> m_requests;
44 if ((self = [super
init])) {
56- (
Qt::PermissionStatus)checkPermission:(
QPermission)permission
60 auto status = [
self authorizationStatus:locationPermission];
64 return [
self accuracyAuthorization:locationPermission];
69 NSString *bundleIdentifier = NSBundle.mainBundle.bundleIdentifier;
70 if (!bundleIdentifier || !bundleIdentifier.length) {
71 qCWarning(lcLocationPermission) <<
"Missing bundle identifier"
72 <<
"in Info.plist. Can not use location permissions.";
76 auto status = [
self authorizationStatus];
78 case kCLAuthorizationStatusRestricted:
79 case kCLAuthorizationStatusDenied:
81 case kCLAuthorizationStatusNotDetermined:
83 case kCLAuthorizationStatusAuthorizedAlways:
86 case kCLAuthorizationStatusAuthorizedWhenInUse:
93 qCWarning(lcPermissions) <<
"Unknown permission status" << status <<
"detected in" <<
self;
97- (CLAuthorizationStatus)authorizationStatus
100 if (@available(macOS 11,
iOS 14, *))
101 return self.manager.authorizationStatus;
109 auto status = CLAccuracyAuthorizationReducedAccuracy;
110 if (@available(macOS 11,
iOS 14, *))
111 status =
self.manager.accuracyAuthorization;
114 case CLAccuracyAuthorizationFullAccuracy:
116 case CLAccuracyAuthorizationReducedAccuracy:
123 qCWarning(lcPermissions) <<
"Unknown accuracy status" << status <<
"detected in" <<
self;
129#if defined(Q_OS_MACOS)
130 return {
"NSLocationUsageDescription" };
132 QStringList usageDescriptions = {
"NSLocationWhenInUseUsageDescription" };
135 usageDescriptions <<
"NSLocationAlwaysAndWhenInUseUsageDescription";
136 return usageDescriptions;
142 const bool requestAlreadyInFlight = !m_requests.empty();
144 m_requests.push_back({ permission, callback });
146 if (requestAlreadyInFlight) {
147 qCDebug(lcLocationPermission).nospace() <<
"Already processing "
148 << m_requests.front().permission <<
". Deferring request";
150 [
self requestQueuedPermission];
154- (
void)requestQueuedPermission
157 const auto permission = m_requests.front().permission;
159 qCDebug(lcLocationPermission) <<
"Requesting" << permission;
162 self.manager = [[CLLocationManager new] autorelease];
167 switch (locationPermission.availability()) {
171 switch ([self authorizationStatus]) {
172 case kCLAuthorizationStatusNotDetermined:
173 [
self.manager requestWhenInUseAuthorization];
176 [
self deliverResult];
183 switch ([self authorizationStatus]) {
184 case kCLAuthorizationStatusNotDetermined:
185 [
self.manager requestAlwaysAuthorization];
188 case kCLAuthorizationStatusAuthorizedWhenInUse:
194 qCWarning(lcLocationPermission) <<
"QLocationPermission::WhenInUse"
195 <<
"can not be upgraded to QLocationPermission::Always on iOS."
196 <<
"Please request QLocationPermission::Always directly.";
200 [
self deliverResult];
206- (
void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
208 qCDebug(lcLocationPermission) <<
"Processing authorization"
209 <<
"update with status" << status;
211 if (m_requests.empty()) {
212 qCDebug(lcLocationPermission) <<
"No requests in flight. Ignoring.";
216 if (status == kCLAuthorizationStatusNotDetermined) {
224 qCDebug(lcLocationPermission) <<
"Ignoring delegate callback"
225 <<
"with status kCLAuthorizationStatusNotDetermined";
229 [
self deliverResult];
234 auto request = m_requests.front();
235 m_requests.pop_front();
237 auto status = [
self checkPermission:request.permission];
238 qCDebug(lcLocationPermission) <<
"Result for"
239 <<
request.permission <<
"was" << status;
243 if (!m_requests.empty()) {
244 qCDebug(lcLocationPermission) <<
"Still have"
245 << m_requests.size() <<
"deferred request(s)";
246 [
self requestQueuedPermission];
252#include "moc_qdarwinpermissionplugin_p_p.cpp"
Access the user's location.
Q_CORE_EXPORT Accuracy accuracy() const
Returns the accuracy of the request.
\inmodule QtCore \inheaderfile QPermissions
std::optional< T > value() const
void requestPermission(const QPermission &permission, const PermissionCallback &callback)
std::function< void(Qt::PermissionStatus)> PermissionCallback
#define QT_IGNORE_DEPRECATIONS(statement)
Q_CONSTRUCTOR_FUNCTION(warmUpLocationServices)
void warmUpLocationServices()
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
QNetworkAccessManager manager
QNetworkRequest request(url)
PermissionCallback callback