Unsolved UIApplication.shared.canOpenURL implements in Qt
-
Did you re-run qmake after modifying your .pro file ?
If not then either nuke the build folder and restart a build or force a run of qmake.
On a side note, your .pro file has two issues: you have
HandleURL.mm
in both SOURCES and OBJECTIVE_SOURCES. If you are using a recent version of Qt, you don't need the later.The other issue is the backslash after main.cpp.
-
@SGaist Thank you for your message.
But we have error yet!
.mm file:
#include <QDebug> #include <QUrlQuery> #include <QUrl> #include <QDesktopServices> #include "HandleURL.hpp" #import <Foundation/NSUserNotification.h> #import <AppKit/NSApplication.h> void HandleURL::handleURL(const QUrl &url) { // parse it... QUrlQuery query(url); // qDebug() << url.toString(); // qDebug() << query.queryItemValue("callbackurl"); // qDebug() << QUrl::toString(...); // NSUrl *urls = url.toNSUrl(); //NSUrl *urls = url.toString().toNSUrl(); NSUrl *urls = url.toNSUrl(); bool canOpen = [[NSApplication shared] canOpenUrl: urls]; qDebug() << canOpen; if(canOpen) { QDesktopServices::openUrl(url); } emit incomingURL(query.queryItemValue("callbackurl")); // emit incomingURL(url.toString()); }
.pro file:
#include Foundation/NSUserNotification.h> #include AppKit/NSApplication.h> QT += widgets quick webview CONFIG += c++17 TEMPLATE = app DEFINES += QT_DEPRECATED_WARNINGS LIBS += -framework AppKit -framework Foundation SOURCES += \ main.cpp RESOURCES += qml.qrc QML_IMPORT_PATH = QML_DESIGNER_IMPORT_PATH = # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target contains(ANDROID_TARGET_ARCH,arm64-v8a) { ANDROID_ARM64 = 1 ANDROID_EXTRA_LIBS = \ $$PWD/openssl-1.1.1a-clang/arm64-v8a/lib/libcrypto.so \ $$PWD/openssl-1.1.1a-clang/arm64-v8a/lib/libssl.so ANDROID_PACKAGE_SOURCE_DIR = \ $$PWD/android } contains(ANDROID_TARGET_ARCH,armeabi-v7a) { ANDROID_EXTRA_LIBS = \ $$PWD/openssl-1.1.1a-clang/armeabi-v7a/lib/libcrypto.so \ $$PWD/openssl-1.1.1a-clang/armeabi-v7a/lib/libssl.so ANDROID_PACKAGE_SOURCE_DIR = \ $$PWD/android } DISTFILES += \ android/AndroidManifest.xml \ android/build.gradle \ android/gradle/wrapper/gradle-wrapper.jar \ android/gradle/wrapper/gradle-wrapper.properties \ android/gradlew \ android/gradlew.bat \ android/res/values/libs.xml defineReplace(droidVersionCode) { segments = $$split(1, ".") for(segment, segments): vCode = "$$first(vCode)$$format_number($$segment, width=3 zeropad)" ## arm64-v8a, armeabi-v7a contains(ANDROID_TARGET_ARCH, arm64-v8a): \ suffix = 1 else:contains(ANDROID_TARGET_ARCH, armeabi-v7a): \ suffix = 0 return($$first(vCode)$$first(suffix)) } ios { QMAKE_INFO_PLIST = ios/info.plist } VERSION = 1.2.3 ANDROID_VERSION_NAME = $$VERSION ANDROID_VERSION_CODE = $$droidVersionCode($$ANDROID_VERSION_NAME) HEADERS += \ HandleURL.hpp OBJECTIVE_SOURCES = HandleURL.mm
ios -> info.plist file:
<?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>CFBundleGetInfoString</key> <string>Created by Qt/QMake</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>LSRequiresIPhoneOS</key> <true/> <key>MinimumOSVersion</key> <string>${IPHONEOS_DEPLOYMENT_TARGET}</string> <key>NOTE</key> <string>This file was generated by Qt/QMake.</string> <key>UILaunchStoryboardName</key> <string>LaunchScreen</string> <key>UISupportedInterfaceOrientations</key> <array> <string>UIInterfaceOrientationPortrait</string> <string>UIInterfaceOrientationPortraitUpsideDown</string> <string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeRight</string> </array> <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>swish</string> </array> </dict> </array> </dict> </plist>
Errors
/Users/user/Desktop/silvcopy22/HandleURL.mm:6: error: 'Foundation/NSUserNotification.h' file not found #include <Foundation/NSUserNotification.h> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /Users/user/Desktop/silvcopy22/HandleURL.mm:6: did not find header 'NSUserNotification.h' in framework 'Foundation' (loaded from '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator13.2.sdk/System/Library/Frameworks') :-1: error: Xcodebuild failed.
Qt version: 5.13.2
Can you help and guide me?
Thank you -
Are you building for macOS or iOS ?
I built successfully for macOS but you seem to target the simulator.
-
We want this for iOS (iphone). @SGaist
-
From the documentation, NSUserNotification is a macOS API that is not deprecated.
-
This post is deleted! -
How we can access to UIApplication? and how can call canopenurl?
Target is iOS using Qt.
https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl
-
It's written on the page you are linking as well as the URL: use the UIKit framework.
-
@SGaist said in UIApplication.shared.canOpenURL implements in Qt:
UIKit
I don't know how to use UIKit, UIApplication in my Qt project.
I cannot find any solution and sample code for this.
Can you help me? -
The exact same as you did with NSApplication, just use UIApplication in place.
-
@SGaist said in UIApplication.shared.canOpenURL implements in Qt:
NSURL *url = myUrl.toNSUrl();
bool canOpen = [[UIApplication shared] canOpenUrl: url];Thank you so much for your message.
Also how we can access to
shared
object when we are in another file?It's a globally object in
OBJECT C
(.mm) files? -
The same way you did there. The function returns the singleton app instance.
-
@SGaist said in UIApplication.shared.canOpenURL implements in Qt:
The same way you did there. The function returns the singleton app instance.
![photo_2020-01-21_01-25-10.jpg]
main.mm file:
#include <QApplication> #include <QQmlApplicationEngine> #include <QtWebView> #include <QDesktopServices> #include <QUrl> #include <QQmlContext> #include "HandleURL.hpp" #include <QDebug> #include <QUrlQuery> //Two of these?? #include <QUrl> #include <QDesktopServices> #include "HandleURL.hpp" //#import <AppKit/NSApplication.h> #import <UIKit/UIKit.h> #import <Foundation/Foundation.h> #include <QUrl> int main(int argc, char *argv[]) { QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); QApplication app(argc, argv); QUrl testURL("swish://paymentrequest?token=Shk9Q9C-RaatwCxZ_lYZ-u11ShJafIg5&callbackurl=https%3A%2F%2Fpay.direct2internet.com%2Fpay%2Fsuccess%3Fd2iwebpay-hh%3DV3n%252FCX%26d2iwebpay-tm%3D1579033717%26d2iwebpay%3D88c96710-5e08-43f6-bf46-f0ba89a3b3f6"); NSURL *urls = testURL.toNSURL(); bool canOpen = [[UIApplication sharedApplication] canOpenUrl: urls]; qDebug() << canOpen; if(canOpen) { QDesktopServices::openUrl(testURL); } QtWebView::initialize(); QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); HandleURL *URLHandler = new HandleURL(); QDesktopServices::setUrlHandler("swish", URLHandler, "handleURL"); engine.load(url); engine.rootContext()->setContextProperty("URLHandler", URLHandler); return app.exec(); }
Error:
ld: framework not found AppKit clang: error: linker command failed with exit code 1 (use -v to see invocation)
-
The code you pasted does not match the code you are showing in the image.
One uses
shared
and the othersharedApplication
. -
@SGaist said in UIApplication.shared.canOpenURL implements in Qt:
The code you pasted does not match the code you are showing in the image.
One uses
shared
and the othersharedApplication
.Sorry,
shared
have error: Class method 'shared' not found.So we did used
sharedApplication
in images.Please check old my message, i did update it.
-
You know that Objective-C/C++ like C/C++ is case sensitive ?
It's canOpenURL.
-
@SGaist said in UIApplication.shared.canOpenURL implements in Qt:
You know that Objective-C/C++ like C/C++ is case sensitive ?
It's canOpenURL.
Thank you.
After This:
.pro file:
QT += widgets quick webview CONFIG += c++17 TEMPLATE = app DEFINES += QT_DEPRECATED_WARNINGS LIBS += -framework AppKit -framework Foundation # += \ # main.mm RESOURCES += qml.qrc QML_IMPORT_PATH = QML_DESIGNER_IMPORT_PATH = # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target contains(ANDROID_TARGET_ARCH,arm64-v8a) { ANDROID_ARM64 = 1 ANDROID_EXTRA_LIBS = \ $$PWD/openssl-1.1.1a-clang/arm64-v8a/lib/libcrypto.so \ $$PWD/openssl-1.1.1a-clang/arm64-v8a/lib/libssl.so ANDROID_PACKAGE_SOURCE_DIR = \ $$PWD/android } contains(ANDROID_TARGET_ARCH,armeabi-v7a) { ANDROID_EXTRA_LIBS = \ $$PWD/openssl-1.1.1a-clang/armeabi-v7a/lib/libcrypto.so \ $$PWD/openssl-1.1.1a-clang/armeabi-v7a/lib/libssl.so ANDROID_PACKAGE_SOURCE_DIR = \ $$PWD/android } DISTFILES += \ android/AndroidManifest.xml \ android/build.gradle \ android/gradle/wrapper/gradle-wrapper.jar \ android/gradle/wrapper/gradle-wrapper.properties \ android/gradlew \ android/gradlew.bat \ android/res/values/libs.xml defineReplace(droidVersionCode) { segments = $$split(1, ".") for(segment, segments): vCode = "$$first(vCode)$$format_number($$segment, width=3 zeropad)" ## arm64-v8a, armeabi-v7a contains(ANDROID_TARGET_ARCH, arm64-v8a): \ suffix = 1 else:contains(ANDROID_TARGET_ARCH, armeabi-v7a): \ suffix = 0 return($$first(vCode)$$first(suffix)) } ios { QMAKE_INFO_PLIST = ios/info.plist } VERSION = 1.2.3 ANDROID_VERSION_NAME = $$VERSION ANDROID_VERSION_CODE = $$droidVersionCode($$ANDROID_VERSION_NAME) HEADERS += \ HandleURL.hpp OBJECTIVE_SOURCES =main.mm # HandleURL.mm
error:
d Debug-iphonesimulator/StnTaxi.app/StnTaxi normal x86_64 cd /Users/diyar/Desktop/build-StnTaxi-Qt_5_13_2_for_iOS_Simulator-Release export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -target x86_64-apple-ios11.0-simulator -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator13.2.sdk -L/Users/diyar/Desktop/build-StnTaxi-Qt_5_13_2_for_iOS_Simulator-Release/Debug-iphonesimulator -L/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator13.2.sdk/System/Library/Frameworks -L/Users/diyar/Qt/5.13.2/ios/plugins/platforms -L/Users/diyar/Qt/5.13.2/ios/plugins/webview -L/Users/diyar/Qt/5.13.2/ios/lib -L/Users/diyar/Qt/5.13.2/ios/plugins/imageformats -L/Users/diyar/Qt/5.13.2/ios/plugins/qmltooling -L/Users/diyar/Qt/5.13.2/ios/plugins/bearer -L/Users/diyar/Qt/5.13.2/ios/qml/QtQuick/Layouts -L/Users/diyar/Qt/5.13.2/ios/qml/Qt/labs/platform -L/Users/diyar/Qt/5.13.2/ios/qml/QtWebView -L/Users/diyar/Qt/5.13.2/ios/qml/QtQuick.2 -L/Users/diyar/Qt/5.13.2/ios/qml/QtQuick/Templates.2 -L/Users/diyar/Qt/5.13.2/ios/qml/QtQuick/Controls.2 -L/Users/diyar/Qt/5.13.2/ios/qml/QtQuick/Controls.2/Fusion -L/Users/diyar/Qt/5.13.2/ios/qml/QtQuick/Controls.2/Universal -L/Users/diyar/Qt/5.13.2/ios/qml/QtQuick/Controls.2/Material -L/Users/diyar/Qt/5.13.2/ios/qml/QtGraphicalEffects/private -L/Users/diyar/Qt/5.13.2/ios/qml/QtQuick/Window.2 -L/Users/diyar/Qt/5.13.2/ios/qml/QtGraphicalEffects -L/Users/diyar/Qt/5.13.2/ios/qml/QtQuick/Controls.2/Imagine -F/Users/diyar/Desktop/build-StnTaxi-Qt_5_13_2_for_iOS_Simulator-Release/Debug-iphonesimulator -filelist /Users/diyar/Desktop/build-StnTaxi-Qt_5_13_2_for_iOS_Simulator-Release/.xcode/StnTaxi.build/Debug-iphonesimulator/StnTaxi.build/Objects-normal/x86_64/StnTaxi.LinkFileList -dead_strip -Xlinker -object_path_lto -Xlinker /Users/diyar/Desktop/build-StnTaxi-Qt_5_13_2_for_iOS_Simulator-Release/.xcode/StnTaxi.build/Debug-iphonesimulator/StnTaxi.build/Objects-normal/x86_64/StnTaxi_lto.o -Xlinker -no_deduplicate -Xlinker -objc_abi_version -Xlinker 2 -fobjc-link-runtime -stdlib=libc++ -Wl,-e,_qt_main_wrapper -Wl,-rpath,@executable_path/../Frameworks -L/Users/diyar/Qt/5.13.2/ios/plugins/platforms -framework AssetsLibrary -lz -framework MobileCoreServices -lm -framework UIKit -framework OpenGLES -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __entitlements -Xlinker /Users/diyar/Desktop/build-StnTaxi-Qt_5_13_2_for_iOS_Simulator-Release/.xcode/StnTaxi.build/Debug-iphonesimulator/StnTaxi.build/StnTaxi.app-Simulated.xcent -framework AppKit -lqios_debug -lqtwebview_darwin_debug -framework WebKit -framework QuartzCore -framework AudioToolbox -lQt5FontDatabaseSupport_debug -lqtfreetype_debug -lQt5GraphicsSupport_debug -lQt5ClipboardSupport_debug -lqgif_debug -lqicns_debug -lqico_debug -lqjpeg_debug -lqmacheif_debug -lqmacjp2_debug -framework ImageIO -lqtga_debug -lqtiff_debug -lqwbmp_debug -lqwebp_debug -lqmldbg_debugger_debug -lqmldbg_inspector_debug -lqmldbg_local_debug -lqmldbg_messages_debug -lqmldbg_native_debug -lqmldbg_nativedebugger_debug -lqmldbg_preview_debug -lqmldbg_profiler_debug -lqmldbg_quickprofiler_debug -lqmldbg_server_debug -lQt5PacketProtocol_debug -lqmldbg_tcp_debug -lqgenericbearer_debug -lqquicklayoutsplugin_debug -lqtlabsplatformplugin_debug -lQt5Widgets_debug -ldeclarative_webview_debug -lQt5WebView_debug -lqtquick2plugin_debug -lqtquicktemplates2plugin_debug -lqtquickcontrols2plugin_debug -lqtquickcontrols2fusionstyleplugin_debug -lqtquickcontrols2universalstyleplugin_debug -lqtquickcontrols2materialstyleplugin_debug -lqtgraphicaleffectsprivate_debug -lwindowplugin_debug -lqtgraphicaleffectsplugin_debug -lqtquickcontrols2imaginestyleplugin_debug -lQt5QuickControls2_debug -lQt5QuickTemplates2_debug -lQt5Quick_debug -lQt5Gui_debug -lqtlibpng_debug -lqtharfbuzz_debug -framework CoreText -framework CoreGraphics -lQt5Qml_debug -lQt5Network_debug -framework Security -lQt5Core_debug -framework CoreFoundation -framework Foundation -lqtpcre2_debug -Xlinker -dependency_info -Xlinker /Users/diyar/Desktop/build-StnTaxi-Qt_5_13_2_for_iOS_Simulator-Release/.xcode/StnTaxi.build/Debug-iphonesimulator/StnTaxi.build/Objects-normal/x86_64/StnTaxi_dependency_info.dat -o /Users/diyar/Desktop/build-StnTaxi-Qt_5_13_2_for_iOS_Simulator-Release/Debug-iphonesimulator/StnTaxi.app/StnTaxi ld: framework not found AppKit clang: error: linker command failed with exit code 1 (use -v to see invocation)
#include <QApplication> #include <QQmlApplicationEngine> #include <QtWebView> #include <QDesktopServices> #include <QQmlContext> #include "HandleURL.hpp" #include <QDebug> #include <QUrlQuery> #include <QDesktopServices> #include "HandleURL.hpp" //#import <AppKit/NSApplication.h> #import <UIKit/UIKit.h> #import <Foundation/Foundation.h> #include <QUrl> int main(int argc, char *argv[]) { QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); QApplication app(argc, argv); QUrl testURL("swish://paymentrequest?token=Shk9Q9C-RaatwCxZ_lYZ-u11ShJafIg5&callbackurl=https%3A%2F%2Fpay.direct2internet.com%2Fpay%2Fsuccess%3Fd2iwebpay-hh%3DV3n%252FCX%26d2iwebpay-tm%3D1579033717%26d2iwebpay%3D88c96710-5e08-43f6-bf46-f0ba89a3b3f6"); NSURL *urls = testURL.toNSURL(); bool canOpen = [[UIApplication sharedApplication] canOpenURL: urls]; qDebug() << canOpen; if(canOpen) { QDesktopServices::openUrl(testURL); } QtWebView::initialize(); QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); HandleURL *URLHandler = new HandleURL(); QDesktopServices::setUrlHandler("swish", URLHandler, "handleURL"); engine.load(url); engine.rootContext()->setContextProperty("URLHandler", URLHandler); return app.exec(); }
-
AppKit is a macOS only framework. Don't link to it when building for iOS.