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#if defined(Q_OS_VISIONOS)
81 auto status = [
self authorizationStatus];
83 case kCLAuthorizationStatusRestricted:
84 case kCLAuthorizationStatusDenied:
86 case kCLAuthorizationStatusNotDetermined:
88#if !defined(Q_OS_VISIONOS)
89 case kCLAuthorizationStatusAuthorizedAlways:
92#if defined(Q_OS_IOS) || defined(Q_OS_VISIONOS)
93 case kCLAuthorizationStatusAuthorizedWhenInUse:
100 qCWarning(lcPermissions) <<
"Unknown permission status" << status <<
"detected in" <<
self;
104- (CLAuthorizationStatus)authorizationStatus
107 if (@available(macOS 11,
iOS 14, *))
108 return self.manager.authorizationStatus;
116 auto status = CLAccuracyAuthorizationReducedAccuracy;
117 if (@available(macOS 11,
iOS 14, *))
118 status =
self.manager.accuracyAuthorization;
121 case CLAccuracyAuthorizationFullAccuracy:
123 case CLAccuracyAuthorizationReducedAccuracy:
130 qCWarning(lcPermissions) <<
"Unknown accuracy status" << status <<
"detected in" <<
self;
136#if defined(Q_OS_MACOS)
137 return {
"NSLocationUsageDescription" };
139 QStringList usageDescriptions = {
"NSLocationWhenInUseUsageDescription" };
142 usageDescriptions <<
"NSLocationAlwaysAndWhenInUseUsageDescription";
143 return usageDescriptions;
149 const bool requestAlreadyInFlight = !m_requests.empty();
151 m_requests.push_back({ permission, callback });
153 if (requestAlreadyInFlight) {
154 qCDebug(lcLocationPermission).nospace() <<
"Already processing "
155 << m_requests.front().permission <<
". Deferring request";
157 [
self requestQueuedPermission];
161- (
void)requestQueuedPermission
164 const auto permission = m_requests.front().permission;
166 qCDebug(lcLocationPermission) <<
"Requesting" << permission;
169 self.manager = [[CLLocationManager new] autorelease];
174 switch (locationPermission.availability()) {
178 switch ([self authorizationStatus]) {
179 case kCLAuthorizationStatusNotDetermined:
180 [
self.manager requestWhenInUseAuthorization];
183 [
self deliverResult];
187#if defined(Q_OS_VISIONOS)
188 [
self deliverResult];
193 switch ([self authorizationStatus]) {
194 case kCLAuthorizationStatusNotDetermined:
195 [
self.manager requestAlwaysAuthorization];
198 case kCLAuthorizationStatusAuthorizedWhenInUse:
204 qCWarning(lcLocationPermission) <<
"QLocationPermission::WhenInUse"
205 <<
"can not be upgraded to QLocationPermission::Always on iOS."
206 <<
"Please request QLocationPermission::Always directly.";
210 [
self deliverResult];
217- (
void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
219 qCDebug(lcLocationPermission) <<
"Processing authorization"
220 <<
"update with status" << status;
222 if (m_requests.empty()) {
223 qCDebug(lcLocationPermission) <<
"No requests in flight. Ignoring.";
227 if (status == kCLAuthorizationStatusNotDetermined) {
235 qCDebug(lcLocationPermission) <<
"Ignoring delegate callback"
236 <<
"with status kCLAuthorizationStatusNotDetermined";
240 [
self deliverResult];
245 auto request = m_requests.front();
246 m_requests.pop_front();
248 auto status = [
self checkPermission:request.permission];
249 qCDebug(lcLocationPermission) <<
"Result for"
250 <<
request.permission <<
"was" << status;
254 if (!m_requests.empty()) {
255 qCDebug(lcLocationPermission) <<
"Still have"
256 << m_requests.size() <<
"deferred request(s)";
257 [
self requestQueuedPermission];
263#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