iOS: Forward [UIApplicationDelegate handleOpenURL:] to QDesktopServices

The user may use QDesktopServices::setUrlHandler() in combination with
the appropriate Info.plist keys (CFBundleURLTypes, CFBundleURLSchemes)
to react to URL requests from other applications.

This is among other things useful for handling OAuth authentication from
applications such as Dropbox. See:

  https://www.dropbox.com/developers/core/start/ios

We protect against recursive URL opening, but an application may still
redirect a request to open a URL by opening another URL, eg a website.

Task-number: QTBUG-35201
Change-Id: I9f1d246206c5594b1b65bb11fa98c6bcdefc443e
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@digia.com>
This commit is contained in:
Tor Arne Vestbø 2013-11-28 15:33:06 +01:00 committed by The Qt Project
parent bedc5a3ae2
commit c5b19f2521
3 changed files with 46 additions and 0 deletions

View File

@ -41,9 +41,14 @@
#include "qiosapplicationdelegate.h"
#include "qiosintegration.h"
#include "qiosservices.h"
#include "qiosviewcontroller.h"
#include "qioswindow.h"
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
#include <QtCore/QtCore>
@implementation QIOSApplicationDelegate
@ -82,6 +87,21 @@
return YES;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
Q_UNUSED(application);
Q_UNUSED(sourceApplication);
Q_UNUSED(annotation);
if (!QGuiApplication::instance())
return NO;
QIOSIntegration *iosIntegration = static_cast<QIOSIntegration *>(QGuiApplicationPrivate::platformIntegration());
QIOSServices *iosServices = static_cast<QIOSServices *>(iosIntegration->services());
return iosServices->handleUrl(QUrl::fromNSURL(url));
}
- (void)dealloc
{
[window release];

View File

@ -41,6 +41,8 @@
#ifndef QIOSSERVICES_H
#define QIOSSERVICES_H
#include <qurl.h>
#include <qpa/qplatformservices.h>
QT_BEGIN_NAMESPACE
@ -50,6 +52,11 @@ class QIOSServices : public QPlatformServices
public:
bool openUrl(const QUrl &url);
bool openDocument(const QUrl &url);
bool handleUrl(const QUrl &url);
private:
QUrl m_handlingUrl;
};
QT_END_NAMESPACE

View File

@ -42,6 +42,7 @@
#include "qiosservices.h"
#include <QtCore/qurl.h>
#include <QtGui/qdesktopservices.h>
#import <UIKit/UIApplication.h>
@ -49,6 +50,9 @@ QT_BEGIN_NAMESPACE
bool QIOSServices::openUrl(const QUrl &url)
{
if (url == m_handlingUrl)
return false;
if (url.scheme().isEmpty())
return openDocument(url);
@ -66,4 +70,19 @@ bool QIOSServices::openDocument(const QUrl &url)
return QPlatformServices::openDocument(url);
}
/* Callback from iOS that the application should handle a URL */
bool QIOSServices::handleUrl(const QUrl &url)
{
QUrl previouslyHandling = m_handlingUrl;
m_handlingUrl = url;
// FIXME: Add platform services callback from QDesktopServices::setUrlHandler
// so that we can warn the user if calling setUrlHandler without also setting
// up the matching keys in the Info.plist file (CFBundleURLTypes and friends).
bool couldHandle = QDesktopServices::openUrl(url);
m_handlingUrl = previouslyHandling;
return couldHandle;
}
QT_END_NAMESPACE