A native iOS app with a Qt third-party library

Reading Time: 4 minutes

I’m wrapping up here pieces of information that I used to setup a working native iOS project taking advantage of a library I wrote mainly using Qt. The library I wrote has nothing to do with GUI, it just helps me dealing with connectivity, REST API interaction, file system access, compression… Also, the library was born for the Desktop but the porting effort to mobile is feasible due to the lack of GUI interaction.
In particular, the following has been tested using Qt 5.3.

Despite the huge integration level now Qt has reached over the year even on the iOS platform, I still prefer having the UI developed using the native SDK. I’m a rather experienced Cocoa developer, not that experienced with Cocoa Touch, but I managed to have everything I needed working. Since the information I found is rather sparse regarding this topic, I thought it could be nice to have everything here in a blog post.

Project info

In the following post I’m assuming you want to link a native iOS Xcode project to a third party library written using C++ and Qt. I’m also assuming you are using statically linked Qt for this project (which is the default for the iOS solution).

So what we have:

  • A native Xcode project for iOS: NativeHelloWorld.xcodeproj
  • A static lib Qt project: FancyStaticLib.pro

What we are going to have

  • NativeHelloWorld.xcodeproj
  • FancyStaticLib.xcodeproj as a subproject to NativeHelloWorld
  • Qt for iOS properly linked to make NativeHelloWorld run and use FancyStaticLib

Let’s get things started

So, first of all let’s instruct Xcode about where to find Qt on our system.
Go to Xcode -> Preferences -> Locations (Tab) -> Source Trees (Sub Tab).
Add the path to your Qt for iOS packages and name it as you wish. I just chose QTLIB_IOS.
Screen Shot 2014-12-18 at 18.25.05

I like setting my paths this way in order to keep my project as “exportable” as possible. This way, other devs can join my project pretty easily.

Now, if you haven’t already, you should create an Xcode project for your static library you want to link into your native iOS project.
In order to do so you have to run something like this:

/path/to/your/Qt/ios/bin/qmake -spec macx-xcode -r /path/to/FancyStaticLib.pro CONFIG+=staticlib CONFIG+=whatever_you_need

This will output FancyStaticLib.xcodeproj file for your static library. You can drag it to your our NativeHelloWorld.xcodeproj inside Xcode and add its product (the static lib) as a link dependency to your project.
NOTE: You will have to re-generate the FancyStaticLib.xcodeproj each time you change your static library .pro file

Link to Qt

Now that we have the project feeling more like a completely native Xcode one we have to set a few things up in order to easily keep developing directly from Xcode through our NativeHelloWorld.xcodeproj

First of all, look for the Headers Search path section in the Build Settings section of your Xcode project:
Screen Shot 2014-12-18 at 18.54.07

We want to make it easy for Xcode to find Qt headers, and also our static lib headers.
Now the variable we previously defined through the Source Trees section in the Xcode preferences comes in handy.
Let’s add the following to the Headers Search Path section:

  • $(QTLIB_IOS)/include
  • /path/to/FancyStaticLib/headers

Now, the actual linker flags.
You will probably need to start your project inside the emulator. When doing so bare in mind that the simulator has a different architecture from your iOS device. Simulator runs an i386 architecture and we want to link our project both to the static Qt lib files compiled for such architecture and for arm. This way we will be able to run our project both in the simulator and on the native device.

Scroll down to the Other Linker Flags section: you should at least have a Debug section. Under Debug, as a child item, you should have Any iOS Simulator SDK. If you don’t, click the little “+” icon on the side of the Debug item and add Any iOS Simulator SDK as child item.Screen Shot 2014-12-18 at 19.06.30

Our project dependencies are satisfied by the following modules:

  • QtCore
  • QtGui
  • QtNetwork
  • QtScript

The Debug section will host the option for running our app on a native device with debug symbols:

-L$(QTLIB_IOS)/lib -lQt5Core_debug -lQt5Gui_debug -lQt5Network_debug -lQt5Script_debug
Also, don’t forget to include proper platform support with:
-lQt5PlatformSupport_debug -L$(QTLIB_IOS)/plugins/ -lqios_debug
You’ll also need -lz -lqtharfbuzzng_debug most probably.
Also, if you are taking advantage of the bearer plugin to handle connectivity, add the following:
-L$(QTLIB_IOS)/plugins/bearer -lqgenericbearer_debug

Now the Any iOS Simulator SDK section:
Simply replace what you typed in the previous section changing “_debug” with “_iphonesimulator_debug” and you are good to go.

The last touch

Your Qt lib will most probably need an instance of QGuiApplication. This usually requires you to replace the default main coming with your project template with a custom one that actually calls QGuiApplication::exec(). Luckily, Qt has made things relatively easy and you won’t need a custom main body. Looks like the Qt guys are cool enough to inject their Qt Event Dispatcher inside the main CocoaTouch run loop making it easy to spawn QTimers and queued methods invocations from Objective-C(++).
Just make sure you initialize a QGuiApplication instance (but you won’t need to call .exec()).

We are going to add the following piece of code inside your application delegate - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions after having renamed the application delegate file from .m to .mm. Renaming to .mm enables Objective-C++ which helps us mix C++ and Objective-C in the same source.

Conclusions

This is pretty much what is needed to mix a native iOS project with a Qt library. If you encounter linker issues you should be able to easily address them by inspecting the .a symbols you can find inside your $(QTLIB_IOS)/{lib,plugins} directories.
Otherwise please post here your issues so that we can try address them together.

Cheers.


Posted

in

,

by

Tags:

Comments

9 responses to “A native iOS app with a Qt third-party library”

  1. Matthieu avatar
    Matthieu

    Hi !

    Thanks for this post, this is exactly what I’m trying to do.
    I’ll test it soon !

    Cheers !

  2. smallsix avatar
    smallsix

    Dear Alessandro,
    I have tried your steps with non GUI Qt class such as QString successfully on iOS, with Qt 5.4.
    But when I come to the last part of your article, the app crashed at new QGuiApplication, and there are some hints in console window:

    This application failed to start because it could not find or load the Qt platform plugin “ios”.
    Reinstalling the application may fix this problem.

    I also tried to generate pure Qt app, eg, analogclock in examples, and it seems there are many difference in xcode project settings.

    Could you help me how to improve this ? I’m looking forward to your reply.

    1. smallsix avatar
      smallsix

      Hi,
      After I add
      -u _qt_registerPlatformPlugin
      to Other Linking Flag, it won’t crash anymore.

  3. Parker avatar
    Parker

    Hi,
    I’m trying to do the same on QT 5.5.

    I’m getting some Linker errors which i cannot resolve, maybe you can help me with that:
    Undefined symbols for architecture i386:
    “_adler32”, referenced from:
    _png_compare_ICC_profile_with_sRGB in libbQt5Gui_iphonesimulator_debug.a(png.o)

    and 12 more of that kind.

    I’d be very very thanksful if you could help me with this!

    Cheers, Parker

  4. ttka avatar
    ttka

    Hi I try your code but I ave this erro on Linker : QRasterBackingStore:: some method .. undefined symbol. Which library I have tiro link? Thanks

  5. Karen avatar
    Karen

    Thanks for this wonderful post, this is exactly what I’m trying to do.
    If it is possible can you describe how to keep a strong reference to the QGuiApplication instance.
    Thanks,
    Karen

  6. Jerry Walton avatar

    can you use UI from both iOS framework (UIKit) and QT UI in the same app?
    for example, it is possible to use Unity (3D) and iOS framework (UIKit) in the same app,
    by sharing the “window” object.

  7. charanjit singh avatar
    charanjit singh

    Hi Every One

    I am getting this error while follow above step.

    Unknown type name ‘QGuiApplication’; did you mean ‘UIApplication’?

    This error in coming in Appdelege.mm class. Please help to resolved this error.

    Regards
    Charanjit Singh

  8. Bryan avatar
    Bryan

    Hi! Could you do a new Version of this Guide using Xcode 14 with a Swift Project?
    It would really help so much!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.