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>
This commit is contained in:
parent
b4afba0c34
commit
21a6c86979
@ -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)
|
||||
|
@ -65,6 +65,7 @@ qt_internal_extend_target(QIOSIntegrationPlugin CONDITION NOT TVOS
|
||||
LIBRARIES
|
||||
${FWAssetsLibrary}
|
||||
${FWUniformTypeIdentifiers}
|
||||
${FWPhotos}
|
||||
)
|
||||
|
||||
add_subdirectory(optional)
|
||||
|
@ -39,6 +39,7 @@ private:
|
||||
|
||||
bool showImagePickerDialog(QWindow *parent);
|
||||
bool showNativeDocumentPickerDialog(QWindow *parent);
|
||||
void showImagePickerDialog_helper(QWindow *parent);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user