[ Solved ] [ iOS ] How to open a custom file extension using "Open in MyApp" ?
-
wrote on 1 Jun 2015, 22:27 last edited by Eddie 6 Feb 2015, 13:29
I have a Qt 5.5 widget app.
After adding UTExportedTypeDeclarations and CFBundleDocumentTypes sections to my Info.plist, I can now open a file attachment in Apple Mail and select "Open in MyApp" then MyApp launches.
How can I receive the file and open it? Has anyone figured this out?
I see openURL and didFinishLaunchingWithOptions being discussed.
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
// handle the URL here
}
The LaunchMe Example uses OpenURL.
https://developer.apple.com/library/ios/samplecode/LaunchMe/Introduction/Intro.htmlHow to do same in Qt seems challenging.
Thanks in advance for any tips,
-Ed
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
-
I have a Qt 5.5 widget app.
After adding UTExportedTypeDeclarations and CFBundleDocumentTypes sections to my Info.plist, I can now open a file attachment in Apple Mail and select "Open in MyApp" then MyApp launches.
How can I receive the file and open it? Has anyone figured this out?
I see openURL and didFinishLaunchingWithOptions being discussed.
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
// handle the URL here
}
The LaunchMe Example uses OpenURL.
https://developer.apple.com/library/ios/samplecode/LaunchMe/Introduction/Intro.htmlHow to do same in Qt seems challenging.
Thanks in advance for any tips,
-Ed
wrote on 2 Jun 2015, 12:34 last edited by Eddie 6 Feb 2015, 13:28Ben Lau on Qt Interest mailing list explained that Objective-C categories can be used to override classes even if you do not have the header file.
I do not understand how. The following somehow works without having to initialize it to the instance of UIApplication.
I put a breakpoint in openURL. When I open an email attachment, my app is launched, and the breakpoint is hit. Magic.
File: myappdelegate.mm
#include <UIKit/UIKit.h>
#include "qiosapplicationdelegate.h"
#include "mainwindow.h"
@implementation QIOSApplicationDelegate (CmsApplicationDelegate)
-
(BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
Q_UNUSED(application);
Q_UNUSED(annotation);NSLog(@"sourceApplication: %@",sourceApplication);
NSLog(@"url: %@",url);// A bit of ugly code involving adding a static instance method and a static variable
// But it works!
//
cms::MainWindow* mainWindow = cms::MainWindow::instance();
if(0 != mainWindow)
{
QString filePath = QString::fromNSString(url.path);
qDebug("filePath %s", filePath.toLatin1().data());
mainWindow->openFile(filePath);
}return YES;
}
@end
I added an INCLUDEPATH to my project file.
File: myapp.pro
ios {
QTBASE=$$clean_path($$QMAKE_QMAKE/../../..)/Src/qtbase
INCLUDEPATH += $$QTBASE/src/plugins/platforms/ios
}-Ed
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
-
wrote on 2 Jun 2015, 12:49 last edited byThis post is deleted!
-
wrote on 2 Jun 2015, 16:24 last edited by Eddie 6 Feb 2015, 16:26
I found a solution I like better that posts a QFileOpenEvent.
I like it better because in order to handle file open on OS X I had to subclass QApplication and give it a pointer to my MainWindow to handle the QFileOpenEvent. Now my OS X and iOS implementation are similar and easier to maintain.
File: cmsapplication.h
<pre>
#include <UIKit/UIKit.h>#include <QDebug>
#include <QFileOpenEvent>#include "qiosapplicationdelegate.h"
/// \category QIOSApplicationDelegate(CmsApplicationDelegate)
/// \abstract A category on QIOSApplicationDelegate to override openURL/// Use the Objective-C category feature to override the openURL method
@implementation QIOSApplicationDelegate (CmsApplicationDelegate)/// Posts a QFileOpenEvent to QCoreApplication when iOS calls openURL.
///
/// This allows userto open a TSR file from Apple Mail,
/// select "Open in TSR", to launch TSR and pass openURL the
/// file to open.
///
/// Must add UTExportedTypeDeclarations and CFBundleDocumentTypes to your
/// Info.plist for this to work.
///
/// Example: Info.plist
/// \verbatim
/// <key>UTExportedTypeDeclarations</key>
/// <array>
/// <dict>
/// <key>UTTypeConformsTo</key>
/// <array>
/// <string>public.data</string>
/// </array>
/// <key>UTTypeDescription</key>
/// <string>Tracking Status Report</string>
/// <key>UTTypeIdentifier</key>
/// <string>com.ditchwitch.tsr</string>
/// <key>UTTypeTagSpecification</key>
/// <dict>
/// <key>public.filename-extension</key>
/// <string>tsr</string>
/// <key>public.mime-type</key>
/// <string>public.data</string>
/// </dict>
/// </dict>
/// </array>
/// <key>CFBundleDocumentTypes</key>
/// <array>
/// <dict>
/// <key>CFBundleTypeIconFiles</key>
/// <array>
/// <string>Icon.png</string>
/// </array>
/// <key>CFBundleTypeName</key>
/// <string>Tracking Status Report</string>
/// <key>CFBundleTypeRole</key>
/// <string>Editor</string>
/// <key>LSHandlerRank</key>
/// <string>Owner</string>
/// <key>LSItemContentTypes</key>
/// <array>
/// <string>com.ditchwitch.tsr</string>
/// <string>public.data</string>
/// </array>
/// </dict>
/// </array>
/// \endverbatim
///
/// See file: cmsapplication.cpp
/// \see cmsapplication.cpp
///
/// \see https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html
///-
(BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
Q_UNUSED(application);
Q_UNUSED(annotation);NSLog(@"sourceApplication: %@",sourceApplication);
NSLog(@"url: %@",url);QString filePath = QString::fromNSString(url.path);
qDebug("filePath %s", filePath.toLatin1().data());QFileOpenEvent *fileOpenEvent = new QFileOpenEvent(filePath);
QCoreApplication::postEvent(QCoreApplication::instance(), fileOpenEvent);return YES;
}
@end
</pre>File: cmsapplication.cpp
// class CmsApplication : public QApplication
<pre>
#if defined(Q_OS_OSX) || defined(Q_OS_IOS)
// Looks for QFileOpenEvent to implement TSR file open from
/// other apps, for example, Finder on OS X, or Apple Mail on iOS and OS X.
///
///
/// \remarks Could this work on Android too?
///
/// See file: cmsapplicationdelegate.mm
/// \see cmsapplicationdelegate.mm
///
bool CmsApplication::event(QEvent* event)
{
qDebug() << event->type();
// iOS receives ApplicationDeactivate, ApllicationStateChange, when Home is pressed
// When iOS user opens Mail file attachment using "Open in TSR", ApplicationActivate event received but NOT QEvent::FileOpen
switch (event->type())
{
case QEvent::ApplicationActivate:
{
//clean();
if (false == m_mainWindow.isMinimized())
{
m_mainWindow.show();
}
return true;
}
case QEvent::FileOpen:
{
QString fileName = static_cast<QFileOpenEvent *>(event)->file();
m_mainWindow.openFile(fileName);
return true;
}
default:
break;
}
return QApplication::event(event);
}
#endif
</pre> -
1/4