Qt for iOS A to Z
Mike Krus, Senior Software Engineer at KDAB Qt on iOS Requirements
Recent version of Qt & Creator A Mac Qt 5.4 Basic laptop or Mac Mini sufficient Static build Mac Mini works as headless build machine Not a VM on Not a Mac non-GUI layers of Qt compile as normal Unix / Mach backend for files, sockets, memory An Apple Id
QPA layers maps QWindow to UIView An Apple developer subscription Applies to more than one Apple ID Widget-based UI possible No limit on team size Not recommended iOS 9 introduce 'Personal Teams' QtQuick UI rendered using OpenGL ES (2 or 3) Xcode iOS 8 and up (for Qt 5.5)
p.2 p.3
Demo QMake
Time to try Creator... qmake generates
Makefiles
MyProject.xcodeproj
Info.plist
qml files, contained in a qrc
main.cpp
myproject_plugin_import.cpp
myproject_qml_plugin_import.cpp
p.4 p.5 Anatomy of an App QMake Variables
Application is a bundle darwin/mac vs osx vs ios Specially structured directory Variables Documents, Library/Cache... Not a compressed zip/jar 1 QMAKE_IOS_DEPLOYMENT_TARGET = 8.0 2 QMAKE_IOS_TARGETED_DEVICE_FAMILY = 2 Bundles contain an Info.plist XML file 3 QMAKE_IOS_DEVICE_ARCHS = armv7 arm64 4 QMAKE_IOS_SIMULATOR_ARCHS = i386 x86_64 Metadata about author, supported platforms, architectures, copyright 5 6 VERSION = 1.2.3 Specifies executable to launch inside the bundle 7 BUILDID = 55 File-types / URLs / mime-types 8 9 plist.input = Info.plist.in Bundle has a unique identifier (reverse DNS style), version number, build 10 plist.output = $$OUT_PWD/Info.plist 11 QMAKE_SUBSTITUTES += plist number 12 QMAKE_INFO_PLIST = $$OUT_PWD/Info.plist
Also contains arbitrary resources as plain files Qt 5.8: uikit, macos, tvos, watchos, QMAKE_APPLE_...
p.6 p.7
PList Template Icons & Splash Screens - Resources
1 Include properly named files in your bundle 2 meta.files = $$files($$PWD/meta/*) 4
p.8 p.9 Icons & Splash Screens - Asset Catalogs Getting to know Xcode
Include asset bundles in your bundle Don't be afraid of Xcode
meta.files = $$files($$PWD/meta/*.xcassets) Entrypoint to dedicated editors QMAKE_BUNDLE_DATA += meta Manages developer account Edit in Xcode Manages devices and applications
Builds & deploys your code
Archive management
SDK documentation and examples
Excellent debugger Remember you're working on a copy!
p.10 p.11
The Simulator Running on real hardware
The simulator is not an emulator You must run your app on real hardware
Application compiled for x86 or x64 iOS applications must always be code signed Certifies origin of the app Links against custom frameworks providing iOS APIs Prevents tampering Simulator frontend allows hardware emulation Entitlements Runtime environment Enables some features, iCloud, Health, Push Notifications...
Differences from real hardware Deployment requires Provisioning Profiles Code-signing, OpenGL performance, sensors Controls where app can run Developer profiles AppStore or Ad-Hoc profiles
p.12 p.13 p.14 p.15
Sandboxing Qt UI - Widgets
iOS never exposes the filesystem to the user Widgets work, but...
At runtime, applications can only access files within their 'sandbox' Implemented as kernel access control (ACL), not a chroot
No access to other application's data
Other restrictions No use of private APIs Checked mechanically by tooling No downloading code or JIT-ing Attempts to mark data as executable will fail
Application groups in iOS 8 Apps with matching group IDs can share containers Group IDs defined in the member center, registered in the provisioning
... don't
p.16 p.17 QML - 1 QML - 2
QML Retina & resources UI rendered using OpenGL Coordinates are in qreal, points NOT pixels Designer friendly Set border.pixelAligned: false Animations Image sources support @2x Quick.Controls, Quick.Dialogs More layouts Image { src: "/images/foo.png"; width: 200; height 200 } ComboBox If present, will load [email protected] (400x400 px) on retina devices StackView Embrace this, don't fight it by playing with size and scale of root item! FileDialog (fileDialog.folder: fileDialog.shortcuts.pictures) Text Input Selection is different (much better in 5.7!) Keyboard avoidance is a pain (see Qt.inputMethod.hide())
p.18 p.19
QML - 3 UIKit idioms
Plain QML has no visual style UIKit provides standard high-level view structures Paged, tabbed, master / detail Controls1 look like widgets User and designers familiar with the behaviour and visual presentation Controls2 no iOS look Also supports basic navigation and transitions Native appearance is problematic Push / Pop navigation Define native! Modal presentation Moving target: Apple restyle UIKit across OS upgrades Absence of pop-up / pop-over UI Qt Demo /Users/Shared/Qt/Examples/Qt-5.7/quickcontrols/controls/touch Modal yes / no dialogs the (infrequent) exception
Qt Demo /Users/Shared/Qt/Examples/Qt-5.7/quickcontrols2/gallery Transitory modal UI for rotary wheels
Powerful animation engine
p.20 p.21 Handling Views Other UI issues
Hard to not load everything at start up Phone vs tablets
Loader useful but destructive, can't transition Portrait vs landscape
Using components Cross-platform considerations
1 var component = Qt.createComponent("foo.qml") Accessibility 2 if (component.status == Component.Ready) { 3 newView = component.createObject(parent, {opacity: 0, "anchors.fill": parent}) 4 5 previousView = currentView 6 currentView = newView 7 if (previousView) { 8 previousView.viewWillDisappear() 9 fadeOut.target = previousView 10 fadeOut.running = true 11 } 12 currentView.viewWillAppear() 13 fadeIn.target = currentView 14 fadeIn.running = true 15 }
p.22 p.23
Qt Modules Qt not enough?
Sensors Coverage not complete File-type association Camera Background operations Position (GPS), Location (Maps) Sharing In-App purchase iCloud Access to contacts, accounts (Twitter / Facebook) Qt3D CoreMotion (steps...), MapKit, HealthKit, GameKit, PassKit, Security, PushKit...... WebKit! ...
Through specialised Objective-C APIs
Not wrapped by Qt, easy to invoke yourself
p.24 p.25 Software Platform Objective-C++
Low-level system shared with OS X Objective-C & C++ combined Mach microkernel Language syntaxes are orthogonal BSD userspace libraries (libC, crypto) .mm file extension Apple system libraries CoreAudio, CoreAnimation, CoreLocation, AVFoundation, CoreWLAN OBJECTIVE_SOURCES in qmake
Cocoa Touch Bridging the Objective-C and Qt object systems is possible. Potentially relevant Objective-C, like Cocoa if incorporating a 3rd-party framework for iOS. Natively designed for mobile & touch UIKit, Standard widgets UI class prefix Many others (MapKit, HealthKit, ...)
p.26 p.27
Mixing Qt & UIKit - Using QQuickItem Mixing Qt & UIKit - Using QPA
Derive from QQuickItem QPA layer exposes native resources
Handle windowChanged(QQuickWindow*) signal to create UIView Parent UIView hierarchy to main Qt window
Handle visibleChanged() signal to show/hide Unsuitable for embedding individual widgets QT += gui-private Overload geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) to resize 1 QWindow* window = ... ; 2 UIView *view = static_cast
Create a view / controller heirarchy programmatically
Via a system or 3rdparty library
p.28 p.29 Application Delegate Application Delegate
Use Objective C categories Use own delegate
1 @interface QIOSApplicationDelegate 1 @interface MyAppDelegate : UIResponder
p.30 p.31
Debugging & Profiling Debugging & Profiling
p.32 p.33 Common Issues External Testing
QML / JS: slow startup, no JIT compiler Test Flight
Memory allocation The applicationDidReceiveMemoryWarning: method of your app delegate. The didReceiveMemoryWarning method of your UIViewController classes. The UIApplicationDidReceiveMemoryWarningNotification notification.
Graphical effects...
Hockey App, AWS Device Farm...
p.34 p.35
Thank you!
[email protected] - www.kdab.com