summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/ios
diff options
context:
space:
mode:
authorTimur Pocheptsov <timur.pocheptsov@qt.io>2023-03-24 10:53:11 +0100
committerTimur Pocheptsov <timur.pocheptsov@qt.io>2023-03-28 18:37:36 +0200
commit21a6c86979064b70b11b14b97c8f828d08e29781 (patch)
treef542511c055ffb6baae2ab906893c1fe463736c7 /src/plugins/platforms/ios
parentb4afba0c3450fd0c14ec7bada098c4e82ca310e7 (diff)
iOS: request authorization before presenting image-picker
Right now, image picker view is shown first (it does not require access to photos, since it's essentially Photos app getting access to photos ...). Then, we use AssetsLibrary to get asset for an url (using ALAssetsLibrarie's -assetForURL method). This may trigger a permission-related alert, asking to: a. Select more photos or ... b. Allow access to all photos or ... c. Deny access. Showing this alert _after_ picker has selected an image makes little sense (and probably was never intended this way anyway). Instead, we now use Photos.framework to check the authorization and, if needed, we request an authorization (when the current status is 'Nondetermined'). If authorization is 'Granted' as a result, we show picker view and proceed as normal/before. Pick-to: 6.5 Task-number: QTBUG-109120 Change-Id: I0acfd7b0476346360d75a5e37f5845aaf2d6e3e0 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src/plugins/platforms/ios')
-rw-r--r--src/plugins/platforms/ios/CMakeLists.txt1
-rw-r--r--src/plugins/platforms/ios/qiosfiledialog.h1
-rw-r--r--src/plugins/platforms/ios/qiosfiledialog.mm44
3 files changed, 43 insertions, 3 deletions
diff --git a/src/plugins/platforms/ios/CMakeLists.txt b/src/plugins/platforms/ios/CMakeLists.txt
index e0473b3ce4..3745783248 100644
--- a/src/plugins/platforms/ios/CMakeLists.txt
+++ b/src/plugins/platforms/ios/CMakeLists.txt
@@ -65,6 +65,7 @@ qt_internal_extend_target(QIOSIntegrationPlugin CONDITION NOT TVOS
LIBRARIES
${FWAssetsLibrary}
${FWUniformTypeIdentifiers}
+ ${FWPhotos}
)
add_subdirectory(optional)
diff --git a/src/plugins/platforms/ios/qiosfiledialog.h b/src/plugins/platforms/ios/qiosfiledialog.h
index 12a3af7181..f00c154c03 100644
--- a/src/plugins/platforms/ios/qiosfiledialog.h
+++ b/src/plugins/platforms/ios/qiosfiledialog.h
@@ -39,6 +39,7 @@ private:
bool showImagePickerDialog(QWindow *parent);
bool showNativeDocumentPickerDialog(QWindow *parent);
+ void showImagePickerDialog_helper(QWindow *parent);
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosfiledialog.mm b/src/plugins/platforms/ios/qiosfiledialog.mm
index 526c040335..5dea3c6446 100644
--- a/src/plugins/platforms/ios/qiosfiledialog.mm
+++ b/src/plugins/platforms/ios/qiosfiledialog.mm
@@ -3,6 +3,8 @@
#import <UIKit/UIKit.h>
+#import <Photos/Photos.h>
+
#include <QtCore/qstandardpaths.h>
#include <QtGui/qwindow.h>
#include <QDebug>
@@ -53,6 +55,13 @@ bool QIOSFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality window
return false;
}
+void QIOSFileDialog::showImagePickerDialog_helper(QWindow *parent)
+{
+ UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window
+ : qt_apple_sharedApplication().keyWindow;
+ [window.rootViewController presentViewController:m_viewController animated:YES completion:nil];
+}
+
bool QIOSFileDialog::showImagePickerDialog(QWindow *parent)
{
if (!m_viewController) {
@@ -71,9 +80,38 @@ bool QIOSFileDialog::showImagePickerDialog(QWindow *parent)
return false;
}
- UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window
- : qt_apple_sharedApplication().keyWindow;
- [window.rootViewController presentViewController:m_viewController animated:YES completion:nil];
+ // "Old style" authorization (deprecated, but we have to work with AssetsLibrary anyway).
+ //
+ // From the documentation:
+ // "The authorizationStatus and requestAuthorization: methods aren’t compatible with the
+ // limited library and return PHAuthorizationStatusAuthorized when the user authorizes your
+ // app for limited access only."
+ //
+ // This is good enough for us.
+
+ const auto authStatus = [PHPhotoLibrary authorizationStatus];
+ if (authStatus == PHAuthorizationStatusAuthorized) {
+ showImagePickerDialog_helper(parent);
+ } else if (authStatus == PHAuthorizationStatusNotDetermined) {
+ QPointer<QWindow> winGuard(parent);
+ QPointer<QIOSFileDialog> thisGuard(this);
+ [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ if (status == PHAuthorizationStatusAuthorized) {
+ if (thisGuard && winGuard)
+ thisGuard->showImagePickerDialog_helper(winGuard);
+
+ } else if (thisGuard) {
+ emit thisGuard->reject();
+ }
+ });
+ }];
+ } else {
+ // Treat 'Limited' (we don't know how to deal with anyway) and 'Denied' as errors.
+ // FIXME: logging category?
+ qWarning() << "QIOSFileDialog: insufficient permission, cannot pick images";
+ return false;
+ }
return true;
}