Implement sharing on IOS
This commit is contained in:
parent
cc855bd329
commit
38ad92207e
20 changed files with 425 additions and 21 deletions
|
@ -1,3 +1,9 @@
|
||||||
# Digital Rock ranking
|
# Digital Rock ranking
|
||||||
|
|
||||||
App to view ranking and calendar data from https://www.digitalrock.de/
|
App to view ranking and calendar data from https://www.digitalrock.de/
|
||||||
|
|
||||||
|
# Init
|
||||||
|
´´´
|
||||||
|
git submodule init
|
||||||
|
git submodule update
|
||||||
|
´´´
|
||||||
|
|
49
blueROCK.pro
49
blueROCK.pro
|
@ -1,4 +1,4 @@
|
||||||
QT += quick qml quickcontrols2 purchasing printsupport
|
QT += quick qml quickcontrols2 purchasing
|
||||||
CONFIG += c++11
|
CONFIG += c++11
|
||||||
|
|
||||||
VERSION = 0.5.0
|
VERSION = 0.5.0
|
||||||
|
@ -15,7 +15,7 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
||||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
INCLUDEPATH *= $$PWD/headers
|
INCLUDEPATH += $$PWD/headers
|
||||||
|
|
||||||
# Add version to define
|
# Add version to define
|
||||||
DEFINES += APP_VERSION=\"\\\"$${VERSION}\\\"\"
|
DEFINES += APP_VERSION=\"\\\"$${VERSION}\\\"\"
|
||||||
|
@ -35,8 +35,6 @@ HEADERS += \
|
||||||
|
|
||||||
RESOURCES += resources/qml/qml.qrc \
|
RESOURCES += resources/qml/qml.qrc \
|
||||||
resources/shared/shared.qrc \
|
resources/shared/shared.qrc \
|
||||||
#resources/shared/icons/bluerock/index.theme \
|
|
||||||
\ #$$files(resources/shared/icons/*.png, true)
|
|
||||||
resources/translations/translations.qrc
|
resources/translations/translations.qrc
|
||||||
|
|
||||||
TRANSLATIONS += resources/translations/en.ts \
|
TRANSLATIONS += resources/translations/en.ts \
|
||||||
|
@ -54,7 +52,8 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
!isEmpty(target.path): INSTALLS += target
|
!isEmpty(target.path): INSTALLS += target
|
||||||
|
|
||||||
DISTFILES += \
|
DISTFILES += \
|
||||||
CHANGELOG.md
|
CHANGELOG.md \
|
||||||
|
README.md
|
||||||
|
|
||||||
android {
|
android {
|
||||||
QT += androidextras
|
QT += androidextras
|
||||||
|
@ -97,14 +96,54 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
ios {
|
ios {
|
||||||
|
OBJECTIVE_SOURCES += sources/shareUtils/ios/iosshareutils.mm \
|
||||||
|
sources/iospermissionutils.mm \
|
||||||
|
sources/shareUtils/ios/docviewcontroller.mm
|
||||||
|
|
||||||
|
HEADERS += headers/shareUtils/ios/iosshareutils.h \
|
||||||
|
headers/iospermissionutils.h \
|
||||||
|
headers/shareUtils/ios/docviewcontroller.h
|
||||||
|
|
||||||
|
OTHER_FILES += ios/Info.plist \
|
||||||
|
ios/blueROCK.entitlements
|
||||||
|
|
||||||
|
QMAKE_INFO_PLIST = ios/Info.plist
|
||||||
|
|
||||||
|
|
||||||
|
#QMAKE_IOS_DEPLOYMENT_TARGET = 12.0
|
||||||
|
|
||||||
|
#disable_warning.name = GCC_WARN_64_TO_32_BIT_CONVERSION
|
||||||
|
#disable_warning.value = NO
|
||||||
|
#QMAKE_MAC_XCODE_SETTINGS += disable_warning
|
||||||
|
|
||||||
|
# see https://bugreports.qt.io/browse/QTCREATORBUG-16968
|
||||||
|
# ios_signature.pri not part of project repo because of private signature details
|
||||||
|
# contains:
|
||||||
|
# QMAKE_XCODE_CODE_SIGN_IDENTITY = "iPhone Developer"
|
||||||
|
# MY_DEVELOPMENT_TEAM.name = DEVELOPMENT_TEAM
|
||||||
|
# MY_DEVELOPMENT_TEAM.value = your team Id from Apple Developer Account
|
||||||
|
# QMAKE_MAC_XCODE_SETTINGS += MY_DEVELOPMENT_TEAM
|
||||||
|
|
||||||
|
#include(ios_signature.pri)
|
||||||
|
|
||||||
QMAKE_ASSET_CATALOGS += resources/shared/Assets.xcassets
|
QMAKE_ASSET_CATALOGS += resources/shared/Assets.xcassets
|
||||||
|
|
||||||
|
MY_ENTITLEMENTS.name = CODE_SIGN_ENTITLEMENTS
|
||||||
|
MY_ENTITLEMENTS.value = $$PWD/ios/blueROCK.entitlements
|
||||||
|
QMAKE_MAC_XCODE_SETTINGS += MY_ENTITLEMENTS
|
||||||
|
|
||||||
|
MY_BUNDLE_ID.name = PRODUCT_BUNDLE_IDENTIFIER
|
||||||
|
MY_BUNDLE_ID.value = de.itsblue.bluerock
|
||||||
|
QMAKE_MAC_XCODE_SETTINGS += MY_BUNDLE_ID
|
||||||
xcode_product_bundle_identifier_setting.value = "de.itsblue.bluerock"
|
xcode_product_bundle_identifier_setting.value = "de.itsblue.bluerock"
|
||||||
|
PRODUCT_IDENTIFIER = de.itsblue.bluerock
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG += enable_decoder_qr_code \
|
CONFIG += enable_decoder_qr_code \
|
||||||
enable_encoder_qr_code \
|
enable_encoder_qr_code \
|
||||||
qzxing_multimedia \
|
qzxing_multimedia \
|
||||||
qzxing_qml
|
qzxing_qml
|
||||||
|
|
||||||
include(qzxing/src/QZXing-components.pri)
|
include(qzxing/src/QZXing-components.pri)
|
||||||
|
|
||||||
# this has to be the last line!
|
# this has to be the last line!
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPrinter>
|
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
#include <QBrush>
|
#include <QBrush>
|
||||||
#include <QTextCharFormat>
|
#include <QTextCharFormat>
|
||||||
|
@ -37,6 +36,8 @@
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
#include <QtAndroidExtras>
|
#include <QtAndroidExtras>
|
||||||
|
#elif defined Q_OS_IOS
|
||||||
|
#include "iospermissionutils.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "shareUtils/shareutils.h"
|
#include "shareUtils/shareutils.h"
|
||||||
|
@ -51,6 +52,7 @@ private:
|
||||||
QVariantMap _senddata(QUrl serviceUrl, QUrlQuery pdata = QUrlQuery());
|
QVariantMap _senddata(QUrl serviceUrl, QUrlQuery pdata = QUrlQuery());
|
||||||
|
|
||||||
ShareUtils* _shareUtils;
|
ShareUtils* _shareUtils;
|
||||||
|
IosPermissionUtils* _iosPermissionUtils;
|
||||||
const QStringList _validBaseDomains = {"digitalrock.de", "bluerock.dev"};
|
const QStringList _validBaseDomains = {"digitalrock.de", "bluerock.dev"};
|
||||||
bool _pendingIntentsChecked;
|
bool _pendingIntentsChecked;
|
||||||
signals:
|
signals:
|
||||||
|
|
22
headers/iospermissionutils.h
Normal file
22
headers/iospermissionutils.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef IOSPERMISSIONUTILS_H
|
||||||
|
#define IOSPERMISSIONUTILS_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QEventLoop>
|
||||||
|
|
||||||
|
class IosPermissionUtils : QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
IosPermissionUtils();
|
||||||
|
bool isCameraPermissionGranted();
|
||||||
|
bool requestCameraPermission();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QEventLoop* _responseWaitLoop;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void permissionRequestFinished(bool result);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IOSPERMISSIONUTILS_H
|
|
@ -18,7 +18,7 @@ public:
|
||||||
bool checkMimeTypeView(const QString &mimeType) override;
|
bool checkMimeTypeView(const QString &mimeType) override;
|
||||||
bool checkMimeTypeEdit(const QString &mimeType) override;
|
bool checkMimeTypeEdit(const QString &mimeType) override;
|
||||||
virtual QString getTemporaryFileLocationPath() override;
|
virtual QString getTemporaryFileLocationPath() override;
|
||||||
void shareText(const QString &text) override;
|
void shareText(const QString &text, const QUrl &url) override;
|
||||||
void sendFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId) override;
|
void sendFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId) override;
|
||||||
void viewFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId) override;
|
void viewFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId) override;
|
||||||
void editFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId) override;
|
void editFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId) override;
|
||||||
|
|
21
headers/shareUtils/ios/docviewcontroller.h
Normal file
21
headers/shareUtils/ios/docviewcontroller.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// (c) 2017 Ekkehard Gentz (ekke) @ekkescorner
|
||||||
|
// my blog about Qt for mobile: http://j.mp/qt-x
|
||||||
|
// see also /COPYRIGHT and /LICENSE
|
||||||
|
|
||||||
|
#ifndef DOCVIEWCONTROLLER_HPP
|
||||||
|
#define DOCVIEWCONTROLLER_HPP
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import "iosshareutils.h"
|
||||||
|
|
||||||
|
@interface DocViewController : UIViewController <UIDocumentInteractionControllerDelegate>
|
||||||
|
|
||||||
|
@property int requestId;
|
||||||
|
|
||||||
|
@property IosShareUtils *mIosShareUtils;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // DOCVIEWCONTROLLER_HPP
|
31
headers/shareUtils/ios/iosshareutils.h
Executable file
31
headers/shareUtils/ios/iosshareutils.h
Executable file
|
@ -0,0 +1,31 @@
|
||||||
|
// (c) 2017 Ekkehard Gentz (ekke) @ekkescorner
|
||||||
|
// my blog about Qt for mobile: http://j.mp/qt-x
|
||||||
|
// see also /COPYRIGHT and /LICENSE
|
||||||
|
|
||||||
|
#ifndef __IOSSHAREUTILS_H__
|
||||||
|
#define __IOSSHAREUTILS_H__
|
||||||
|
|
||||||
|
#include "headers/shareUtils/platformshareutils.h"
|
||||||
|
|
||||||
|
class IosShareUtils : public PlatformShareUtils
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit IosShareUtils(QObject *parent = 0);
|
||||||
|
bool checkMimeTypeView(const QString &mimeType) override;
|
||||||
|
bool checkMimeTypeEdit(const QString &mimeType) override;
|
||||||
|
void shareText(const QString &text, const QUrl &url) override;
|
||||||
|
void sendFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId) override;
|
||||||
|
void viewFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId) override;
|
||||||
|
void editFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId) override;
|
||||||
|
|
||||||
|
void handleDocumentPreviewDone(const int &requestId);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void handleFileUrlReceived(const QUrl &url);
|
||||||
|
void handleHttpsUrlReceived(const QUrl &url);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -40,7 +40,7 @@ public:
|
||||||
virtual bool checkMimeTypeView(const QString &mimeType);
|
virtual bool checkMimeTypeView(const QString &mimeType);
|
||||||
virtual bool checkMimeTypeEdit(const QString &mimeType);
|
virtual bool checkMimeTypeEdit(const QString &mimeType);
|
||||||
virtual QString getTemporaryFileLocationPath();
|
virtual QString getTemporaryFileLocationPath();
|
||||||
virtual void shareText(const QString &text);
|
virtual void shareText(const QString &text, const QUrl &url);
|
||||||
virtual void sendFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId);
|
virtual void sendFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId);
|
||||||
virtual void viewFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId);
|
virtual void viewFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId);
|
||||||
virtual void editFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId);
|
virtual void editFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId);
|
||||||
|
|
|
@ -49,7 +49,7 @@ public:
|
||||||
Q_INVOKABLE bool checkMimeTypeView(const QString &mimeType);
|
Q_INVOKABLE bool checkMimeTypeView(const QString &mimeType);
|
||||||
Q_INVOKABLE bool checkMimeTypeEdit(const QString &mimeType);
|
Q_INVOKABLE bool checkMimeTypeEdit(const QString &mimeType);
|
||||||
Q_INVOKABLE QString getTemporaryFileLocationPath();
|
Q_INVOKABLE QString getTemporaryFileLocationPath();
|
||||||
Q_INVOKABLE void shareText(const QString &text);
|
Q_INVOKABLE void shareText(const QString &text, const QUrl &url);
|
||||||
Q_INVOKABLE void sendFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId);
|
Q_INVOKABLE void sendFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId);
|
||||||
Q_INVOKABLE void viewFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId);
|
Q_INVOKABLE void viewFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId);
|
||||||
Q_INVOKABLE void editFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId);
|
Q_INVOKABLE void editFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId);
|
||||||
|
|
45
ios/Info.plist
Normal file
45
ios/Info.plist
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDisplayName</key>
|
||||||
|
<string>${PRODUCT_NAME}</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>${EXECUTABLE_NAME}</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>${ASSETCATALOG_COMPILER_APPICON_NAME}</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>${PRODUCT_NAME}</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>${QMAKE_SHORT_VERSION}</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>${QMAKE_PKGINFO_TYPEINFO}</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>${QMAKE_FULL_VERSION}</string>
|
||||||
|
<key>LSApplicationQueriesSchemes</key>
|
||||||
|
<array>
|
||||||
|
<string>https</string>
|
||||||
|
</array>
|
||||||
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
<true/>
|
||||||
|
<key>MinimumOSVersion</key>
|
||||||
|
<string>${IPHONEOS_DEPLOYMENT_TARGET}</string>
|
||||||
|
<key>NOTE</key>
|
||||||
|
<string>This file was generated by Qt/QMake.</string>
|
||||||
|
<key>NSCameraUsageDescription</key>
|
||||||
|
<string>blueROCK would like to access the camera.</string>
|
||||||
|
<key>UILaunchStoryboardName</key>
|
||||||
|
<string>LaunchScreen</string>
|
||||||
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
|
<array>
|
||||||
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
11
ios/blueROCK.entitlements
Normal file
11
ios/blueROCK.entitlements
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.developer.associated-domains</key>
|
||||||
|
<array>
|
||||||
|
<string>applinks:l.bluerock.dev</string>
|
||||||
|
<string>applinks:app.bluerock.dev</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -8,8 +8,8 @@ Rectangle {
|
||||||
property var flowchartData: ({})
|
property var flowchartData: ({})
|
||||||
|
|
||||||
// always unlock in debug mode
|
// always unlock in debug mode
|
||||||
property bool unlocked: QT_DEBUG || appSettings.read("speedBackendPurchase") === "1"
|
//property bool unlocked: QT_DEBUG || appSettings.read("speedBackendPurchase") === "1"
|
||||||
//property bool unlocked: appSettings.read("speedBackendPurchase") === "1"
|
property bool unlocked: appSettings.read("speedBackendPurchase") === "1"
|
||||||
|
|
||||||
|
|
||||||
state: "hidden"
|
state: "hidden"
|
||||||
|
|
|
@ -25,6 +25,8 @@ BlueRockBackend::BlueRockBackend(QObject *parent) : QObject(parent), _pendingInt
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID)
|
#if defined(Q_OS_ANDROID)
|
||||||
connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(onApplicationStateChanged(Qt::ApplicationState)));
|
connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(onApplicationStateChanged(Qt::ApplicationState)));
|
||||||
|
#elif defined Q_OS_IOS
|
||||||
|
this->_iosPermissionUtils = new IosPermissionUtils();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +98,7 @@ QVariantMap BlueRockBackend::getParamsFromUrl(QString stringUrl) {
|
||||||
|
|
||||||
void BlueRockBackend::shareResultsAsUrl(QString url, QString compName) {
|
void BlueRockBackend::shareResultsAsUrl(QString url, QString compName) {
|
||||||
//% "Check out the results of %1 over here:"
|
//% "Check out the results of %1 over here:"
|
||||||
this->_shareUtils->shareText(qtTrId("#shareResultsLinkText").arg(compName) + "\n" + url);
|
this->_shareUtils->shareText(qtTrId("#shareResultsLinkText").arg(compName) + " \n", url);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlueRockBackend::shareResultsAsPoster(QString url, QString compName) {
|
void BlueRockBackend::shareResultsAsPoster(QString url, QString compName) {
|
||||||
|
@ -146,6 +148,8 @@ bool BlueRockBackend::isCameraPermissionGranted() {
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
QtAndroid::PermissionResult cameraAccess = QtAndroid::checkPermission("android.permission.CAMERA");
|
QtAndroid::PermissionResult cameraAccess = QtAndroid::checkPermission("android.permission.CAMERA");
|
||||||
return cameraAccess == QtAndroid::PermissionResult::Granted;
|
return cameraAccess == QtAndroid::PermissionResult::Granted;
|
||||||
|
#elif defined Q_OS_IOS
|
||||||
|
return this->_iosPermissionUtils->isCameraPermissionGranted();
|
||||||
#else
|
#else
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
@ -203,6 +207,8 @@ bool BlueRockBackend::requestCameraPermission() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
#elif defined Q_OS_IOS
|
||||||
|
return this->_iosPermissionUtils->requestCameraPermission();
|
||||||
#else
|
#else
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
34
sources/iospermissionutils.mm
Normal file
34
sources/iospermissionutils.mm
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#import "../headers/iospermissionutils.h"
|
||||||
|
#import <AVFoundation/AVFoundation.h>
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
IosPermissionUtils::IosPermissionUtils() : QObject(nullptr)
|
||||||
|
{
|
||||||
|
this->_responseWaitLoop = new QEventLoop(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IosPermissionUtils::isCameraPermissionGranted() {
|
||||||
|
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
|
||||||
|
return status == AVAuthorizationStatusAuthorized;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IosPermissionUtils::requestCameraPermission() {
|
||||||
|
if(this->isCameraPermissionGranted())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ([AVCaptureDevice respondsToSelector:@selector(requestAccessForMediaType: completionHandler:)]) {
|
||||||
|
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
|
||||||
|
// Will get here on both iOS 7 & 8 even though camera permissions weren't required
|
||||||
|
// until iOS 8. So for iOS 7 permission will always be granted.
|
||||||
|
this->_responseWaitLoop->exit(granted);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!this->_responseWaitLoop->exec()) {
|
||||||
|
// permission was not granted -> open settings
|
||||||
|
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -20,7 +20,6 @@
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QtQml/QQmlContext>
|
#include <QtQml/QQmlContext>
|
||||||
#include <QQmlApplicationEngine>
|
#include <QQmlApplicationEngine>
|
||||||
#include <QStyleFactory>
|
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include "QZXing.h"
|
#include "QZXing.h"
|
||||||
|
|
||||||
|
|
|
@ -58,9 +58,9 @@ QString AndroidShareUtils::getTemporaryFileLocationPath() {
|
||||||
return QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).value(0) + "/temporaryFiles";
|
return QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).value(0) + "/temporaryFiles";
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidShareUtils::shareText(const QString &text)
|
void AndroidShareUtils::shareText(const QString &text, const QUrl &url)
|
||||||
{
|
{
|
||||||
QAndroidJniObject jsText = QAndroidJniObject::fromString(text);
|
QAndroidJniObject jsText = QAndroidJniObject::fromString(text + url.toString());
|
||||||
jboolean ok = QAndroidJniObject::callStaticMethod<jboolean>("org/ekkescorner/utils/QShareUtils",
|
jboolean ok = QAndroidJniObject::callStaticMethod<jboolean>("org/ekkescorner/utils/QShareUtils",
|
||||||
"shareText",
|
"shareText",
|
||||||
"(Ljava/lang/String;)Z",
|
"(Ljava/lang/String;)Z",
|
||||||
|
|
32
sources/shareUtils/ios/docviewcontroller.mm
Normal file
32
sources/shareUtils/ios/docviewcontroller.mm
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// (c) 2017 Ekkehard Gentz (ekke) @ekkescorner
|
||||||
|
// my blog about Qt for mobile: http://j.mp/qt-x
|
||||||
|
// see also /COPYRIGHT and /LICENSE
|
||||||
|
|
||||||
|
#import "headers/shareUtils/ios/docviewcontroller.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
@interface DocViewController ()
|
||||||
|
@end
|
||||||
|
@implementation DocViewController
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark View Life Cycle
|
||||||
|
- (void)viewDidLoad {
|
||||||
|
[super viewDidLoad];
|
||||||
|
}
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark Document Interaction Controller Delegate Methods
|
||||||
|
- (UIViewController *) documentInteractionControllerViewControllerForPreview: (UIDocumentInteractionController *) controller {
|
||||||
|
#pragma unused (controller)
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
- (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController *)controller
|
||||||
|
{
|
||||||
|
#pragma unused (controller)
|
||||||
|
qDebug() << "end preview";
|
||||||
|
|
||||||
|
self.mIosShareUtils->handleDocumentPreviewDone(self.requestId);
|
||||||
|
|
||||||
|
[self removeFromParentViewController];
|
||||||
|
}
|
||||||
|
@end
|
156
sources/shareUtils/ios/iosshareutils.mm
Executable file
156
sources/shareUtils/ios/iosshareutils.mm
Executable file
|
@ -0,0 +1,156 @@
|
||||||
|
// (c) 2017 Ekkehard Gentz (ekke) @ekkescorner
|
||||||
|
// my blog about Qt for mobile: http://j.mp/qt-x
|
||||||
|
// see also /COPYRIGHT and /LICENSE
|
||||||
|
|
||||||
|
#import "headers/shareUtils/ios/iosshareutils.h"
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <QGuiApplication>
|
||||||
|
#import <QQuickWindow>
|
||||||
|
#import <QDesktopServices>
|
||||||
|
#import <QUrl>
|
||||||
|
#import <QFileInfo>
|
||||||
|
|
||||||
|
#import <UIKit/UIDocumentInteractionController.h>
|
||||||
|
|
||||||
|
#import "headers/shareUtils/ios/docviewcontroller.h"
|
||||||
|
|
||||||
|
IosShareUtils::IosShareUtils(QObject *parent) : PlatformShareUtils(parent)
|
||||||
|
{
|
||||||
|
// Sharing Files from other iOS Apps I got the ideas and some code contribution from:
|
||||||
|
// Thomas K. Fischer (@taskfabric) - http://taskfabric.com - thx
|
||||||
|
QDesktopServices::setUrlHandler("file", this, "handleFileUrlReceived");
|
||||||
|
QDesktopServices::setUrlHandler("https", this, "handleHttpsUrlReceived");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IosShareUtils::checkMimeTypeView(const QString &mimeType) {
|
||||||
|
#pragma unused (mimeType)
|
||||||
|
// dummi implementation on iOS
|
||||||
|
// MimeType not used yet
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IosShareUtils::checkMimeTypeEdit(const QString &mimeType) {
|
||||||
|
#pragma unused (mimeType)
|
||||||
|
// dummi implementation on iOS
|
||||||
|
// MimeType not used yet
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IosShareUtils::shareText(const QString &text, const QUrl &url) {
|
||||||
|
|
||||||
|
NSMutableArray *sharingItems = [NSMutableArray new];
|
||||||
|
|
||||||
|
if (!text.isEmpty()) {
|
||||||
|
[sharingItems addObject:text.toNSString()];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url.isValid()) {
|
||||||
|
[sharingItems addObject:url.toNSURL()];
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the main window rootViewController
|
||||||
|
UIViewController *qtUIViewController = [[UIApplication sharedApplication].keyWindow rootViewController];
|
||||||
|
|
||||||
|
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:sharingItems applicationActivities:nil];
|
||||||
|
if ( [activityController respondsToSelector:@selector(popoverPresentationController)] ) { // iOS8
|
||||||
|
activityController.popoverPresentationController.sourceView = qtUIViewController.view;
|
||||||
|
}
|
||||||
|
[qtUIViewController presentViewController:activityController animated:YES completion:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
// altImpl not used yet on iOS, on Android twi ways to use JNI
|
||||||
|
void IosShareUtils::sendFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId) {
|
||||||
|
#pragma unused (title, mimeType)
|
||||||
|
|
||||||
|
NSString* nsFilePath = filePath.toNSString();
|
||||||
|
NSURL *nsFileUrl = [NSURL fileURLWithPath:nsFilePath];
|
||||||
|
|
||||||
|
static DocViewController* docViewController = nil;
|
||||||
|
if(docViewController!=nil)
|
||||||
|
{
|
||||||
|
[docViewController removeFromParentViewController];
|
||||||
|
[docViewController release];
|
||||||
|
}
|
||||||
|
|
||||||
|
UIDocumentInteractionController* documentInteractionController = nil;
|
||||||
|
documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:nsFileUrl];
|
||||||
|
|
||||||
|
UIViewController* qtUIViewController = [[[[UIApplication sharedApplication]windows] firstObject]rootViewController];
|
||||||
|
if(qtUIViewController!=nil)
|
||||||
|
{
|
||||||
|
docViewController = [[DocViewController alloc] init];
|
||||||
|
|
||||||
|
docViewController.requestId = requestId;
|
||||||
|
// we need this to be able to execute handleDocumentPreviewDone() method,
|
||||||
|
// when preview was finished
|
||||||
|
docViewController.mIosShareUtils = this;
|
||||||
|
|
||||||
|
[qtUIViewController addChildViewController:docViewController];
|
||||||
|
documentInteractionController.delegate = docViewController;
|
||||||
|
// [documentInteractionController presentPreviewAnimated:YES];
|
||||||
|
if(![documentInteractionController presentPreviewAnimated:YES])
|
||||||
|
{
|
||||||
|
emit shareError(0, tr("No App found to open: %1").arg(filePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IosShareUtils::viewFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId) {
|
||||||
|
#pragma unused (title, mimeType)
|
||||||
|
|
||||||
|
sendFile(filePath, title, mimeType, requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IosShareUtils::editFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId) {
|
||||||
|
#pragma unused (title, mimeType)
|
||||||
|
|
||||||
|
sendFile(filePath, title, mimeType, requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IosShareUtils::handleDocumentPreviewDone(const int &requestId)
|
||||||
|
{
|
||||||
|
// documentInteractionControllerDidEndPreview
|
||||||
|
qDebug() << "handleShareDone: " << requestId;
|
||||||
|
emit shareFinished(requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IosShareUtils::handleFileUrlReceived(const QUrl &url)
|
||||||
|
{
|
||||||
|
QString incomingUrl = url.toString();
|
||||||
|
if(incomingUrl.isEmpty()) {
|
||||||
|
qWarning() << "setFileUrlReceived: we got an empty URL";
|
||||||
|
emit shareError(0, tr("Empty URL received"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qDebug() << "IosShareUtils setFileUrlReceived: we got the File URL from iOS: " << incomingUrl;
|
||||||
|
QString myUrl;
|
||||||
|
if(incomingUrl.startsWith("file://")) {
|
||||||
|
myUrl= incomingUrl.right(incomingUrl.length()-7);
|
||||||
|
qDebug() << "QFile needs this URL: " << myUrl;
|
||||||
|
} else {
|
||||||
|
myUrl= incomingUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if File exists
|
||||||
|
QFileInfo fileInfo = QFileInfo(myUrl);
|
||||||
|
if(fileInfo.exists()) {
|
||||||
|
emit fileUrlReceived(myUrl);
|
||||||
|
} else {
|
||||||
|
qDebug() << "setFileUrlReceived: FILE does NOT exist ";
|
||||||
|
emit shareError(0, tr("File does not exist: %1").arg(myUrl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IosShareUtils::handleHttpsUrlReceived(const QUrl &url)
|
||||||
|
{
|
||||||
|
if(url.isEmpty()) {
|
||||||
|
qWarning() << "handleHttpsUrlReceived: we got an empty URL";
|
||||||
|
emit shareError(0, tr("Empty URL received"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qDebug() << "IosShareUtils handleHttpsUrlReceived: we got the Other URL from IOS: " << url;
|
||||||
|
|
||||||
|
emit otherUrlReceived(url.toString(), "https");
|
||||||
|
}
|
|
@ -20,8 +20,8 @@ bool PlatformShareUtils::checkMimeTypeEdit(const QString &mimeType) {
|
||||||
QString PlatformShareUtils::getTemporaryFileLocationPath() {
|
QString PlatformShareUtils::getTemporaryFileLocationPath() {
|
||||||
return QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
|
return QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
|
||||||
}
|
}
|
||||||
void PlatformShareUtils::shareText(const QString &text) {
|
void PlatformShareUtils::shareText(const QString &text, const QUrl &url) {
|
||||||
qDebug() << text;
|
qDebug() << text << url;
|
||||||
}
|
}
|
||||||
void PlatformShareUtils::sendFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId) {
|
void PlatformShareUtils::sendFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId) {
|
||||||
qDebug() << filePath << " - " << title << "requestId " << requestId << " - " << mimeType << "altImpl? ";
|
qDebug() << filePath << " - " << title << "requestId " << requestId << " - " << mimeType << "altImpl? ";
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "shareUtils/shareutils.h"
|
#include "shareUtils/shareutils.h"
|
||||||
|
|
||||||
#ifdef Q_OS_IOS
|
#ifdef Q_OS_IOS
|
||||||
#include "cpp/ios/iosshareutils.hpp"
|
#include "shareUtils/ios/iosshareutils.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
|
@ -62,9 +62,9 @@ QString ShareUtils::getTemporaryFileLocationPath()
|
||||||
return mPlatformShareUtils->getTemporaryFileLocationPath();
|
return mPlatformShareUtils->getTemporaryFileLocationPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareUtils::shareText(const QString &text)
|
void ShareUtils::shareText(const QString &text, const QUrl &url)
|
||||||
{
|
{
|
||||||
mPlatformShareUtils->shareText(text);
|
mPlatformShareUtils->shareText(text, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareUtils::sendFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId)
|
void ShareUtils::sendFile(const QString &filePath, const QString &title, const QString &mimeType, const int &requestId)
|
||||||
|
|
Loading…
Reference in a new issue