diff --git a/cmake/QtFrameworkHelpers.cmake b/cmake/QtFrameworkHelpers.cmake index 1eed9df3797..e8db635963f 100644 --- a/cmake/QtFrameworkHelpers.cmake +++ b/cmake/QtFrameworkHelpers.cmake @@ -6,6 +6,7 @@ macro(qt_find_apple_system_frameworks) qt_internal_find_apple_system_framework(FWAppKit AppKit) qt_internal_find_apple_system_framework(FWCFNetwork CFNetwork) qt_internal_find_apple_system_framework(FWAssetsLibrary AssetsLibrary) + qt_internal_find_apple_system_framework(FWPhotos Photos) qt_internal_find_apple_system_framework(FWAudioToolbox AudioToolbox) qt_internal_find_apple_system_framework(FWApplicationServices ApplicationServices) qt_internal_find_apple_system_framework(FWCarbon Carbon) diff --git a/src/plugins/platforms/ios/CMakeLists.txt b/src/plugins/platforms/ios/CMakeLists.txt index e0473b3ce4b..37457832483 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 12a3af71816..f00c154c035 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 526c0403356..5dea3c6446e 100644 --- a/src/plugins/platforms/ios/qiosfiledialog.mm +++ b/src/plugins/platforms/ios/qiosfiledialog.mm @@ -3,6 +3,8 @@ #import +#import + #include #include #include @@ -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(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(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 winGuard(parent); + QPointer 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; }