Missing Info.plist value - A value for the Info.plist key 'CFBundleIconName' is missing in the bundle 'xxxxxxxxxxxxxxx'. Apps built with iOS 11 or later SDK must supply app icons in an asset catalog and must also provide a value for this Info.plist key. For more information see http://help.apple.com/xcode/mac/current/#/dev10510b1f7.

Starting with Xcode 9 your App icons must be provided as part of your asset catalog.

Since more then 30 years I’m developing business solutions for SMP and Enterprise, where the last 8 years I’m focused on mobile APP development.

There are many challenges to master while developing mobile APPs for different platforms (Android, iOS, Windows 10 mobile, BlackBerry10) and there are many frameworks out there to do this (Angular, Ionic, React Native, Xamarin, Qt, …). The decision about the right framework for more complicated and complex mobile business APPs isn’t easy. You’ll find small example apps and all looks good. Then you start with your project and some weeks or months later you reach the limits, performance goes down, APP becomes instable and you’re in real trouble.

I went through all of this and finally found the best framework for my APPs: Qt. Yes – Qt is an ‘old’ framework and exists since more then 20 years, but Qt 2017 isn’t the same as Qt 1990. Qt covers development for desktop, mobile or embedded APPs and provides QtQuick, QtWidgets and the new QtQuickControls2. QtQuickControls2 are not an update of QtQuick, but a complete new framework and from my experiences last 2 years I must say: you can develop very performant stable mobile APPs with NO LIMITS.

This doesn’t mean that I was lazy 😉 I was heavy working on one of my more complex mobile Business APPs: ProfSys – an APP to support Care Services (outbound and inbound) and I’m glad to present this APP at Qt World Summit 2017 in Berlin. Knowing that thousands of Care-Services-employees are running the APP successfully for their daily work is great. There will be two sessions:

Bluetooth LE for mobile Business APPs

As you know I’m developing mobile business apps for Enterprises and SMBs. There are many use-cases where Bluetooth LE (BTLE) devices can help to streamline the workflow. Last years I already have done some BT LE powered APPs on BlackBerry 10.

In the meantime BlackBerry devices are running Android and most of my enterprise customers are moving from BB10 to Android, some to iOS, some both.

Thanks to QtQuickControls2 I found my way into Android and iOS development using Qt.

After some weeks of exploring and developing I’m happy what can be done with Qt for BT LE APPs on Android and iOS. A big thx to all the Qt developers !

NFC Tags are used per ex. to identify attendees of Conferences / Events / Trainings:

NFC works well on most Android Smartphones with an integrated NFC chip. But when it comes to Tablets even high end Tablets as Goggle Pixel C miss the NFC Chip. iOS devices have a NFC Chip integrated, but Apple blocked acces for developers in the past. Starting with iOS11 developers get partly access to NFC Tags: you can read NDEF Records etc. But in all business APPs I developed last years where NFC was used to identify persons or locations, only the UUID was used.

So for some customers looking for a way to register from a mobile device perhaps an extra NFC Reader conencted via Bluetooth LE is the only solution.

Discover and explore BT LE devices

Hint: Beacons are not supported yet – have to learn HowTo deal with Beacons from Qt.

Selecting first time the Scanner, ekkes BTLE example APP discovers all BT LE devices nearby. While searching for devices there’s a progress view. (see Fire HD 8 screenshot above). Your devices isn’t listed ? Switch it off and on – this helps in most cases. Then hit theblue ‘+‘ Button to discover again and add devices currently not listed. Tap on the red ‘x‘ Button to clear the list and start again.

In the list you get: RSSI, name, MAC Address and current state.

From the list you can Connect or Disconnect devices – tapping on a row will give you a Popup Menu:

First option “Select” is only available for known device types (HeartRate, Lock, NFC Reader).

Tapping on “Select” will select this device as your default device, store MAC address in settings, open the special Page and do a Connect.

“Explore Services” opens a detail Page wit all the Services.

“Connect / Disconnect” does exactly this

Explore Services

Here are all Services found for Addimat Lock:

You get the name and Service UUID. Tap on a row to see the Characteristics of this Service.

Characteristics

Battery Level Characteristics from Addimat Lock:

Battery Level Value can be Read.

Characteristics of Addimat Custom Services:

Custom Characteristics can be Read to get the current Value or you can subscribe for notifications.

Tap on a row to see the details or to interact:

Tap on the red “R” Button to read the current value.

Tap on the red “N” Button to subscribe to the values. There’s a switch if all values should be collected or if you only want to see the last one.

ekkes BTLE example APP displays values as String, HEX or INT. Please take a look at the documentation of your device or Bluetooth GATT service. Sometime values are not human readable and must be analyzed by some business logic.

If a Characteristic has “Write” permissions you’ll see a “W” Button. Tapping on the “W” allows you to enter String or HEX values and to write to the Device:

HeartRate Monitor

Selecting a HR Device a special Page opens:

The header shows you name, MAC address and state and you can Connect, Initialize Services or Disconnect from there.

The “Play” Button subscribes Notifications and you’ll see the HR values:

Addimat Lock Manager

Addimat Manager Page works similar.

Attention: Addimat Lock can work as HID or as BT LE with custom Service. iOS doesn’t know about the custom BT LE Service, so every time you connect to Addimat, iOS tries to connect as HID. There’s an easy way to get rid of this message:

First time enter 307630:

Then open Addimat from Settings – Bluetooth and tap in ‘I’:

Then tap on “Ignore Device”:

Now Addimat is only used as a BT LE Device with custom Services and Characteristics.

Here the Notifications about magnetic keys plugged-in or out are already subscribed (Progress Bar is running):

No User was found for this Addimat Key. In a real-life app you would check the ID against a REST service or a local database.

To simulate this you can add the Mapping between Key ID and User.

Please open ‘Mapping’ from “Settings Menu”:

While the Configure – Popup is open, the values from the keys are still received, but now the APP knows that you’re configuring and you can enter the Name. Do this for all your Keys. (In a real life APP this would be done at Server site and the APP does a Login with Key ID as credentials)

Next time you plug-in the Key, ekkes BTLE example APP “knows” the user:

Select “Settings” from Menu above to see the default device address or to change battery levels:

ekkes BTLE example APP notifies you if the device is disconnected:

NFC Reader

Here’s the NFC Reader Page – Notifications are subscribed to get the NFC Tag IDs:

NFC Reader allows you to “Write” values to the buzzer and LED. Commands Buttons “BUZZER” and “LED” lets you test this.

Here’s the Menu you get from “Buzzer”:

and here’s the Menu you get from “LED”.

ekkes BTLE example APP also uses the LED: if a Tag ID was found, the LED becomes green, if not the LED becomes red.

You can map the NFC Tag IDs same way as for the Addimat magnetic Keys:

Here are some issues and workarounds I found out while testing my apps under 5.9

Update QML Imports

This is always the first step after moving a project from 5.8 to 5.9: I’m updating the QML Imports.

From a technical point you can use the ‘old’ imports. I’m always doing search/replace to update the imports. Then I’m sure all my QML files are accessing the newest Controls and Properties. Updating from 5.8 to 5.9 I replaced

I found a workaround to block those unwanted touch events on the Pages below the Drawer by inserting another Popup between Drawer und Pages below. looks ugly but it works in the meantime. The bug is classified as P1 so hopefully will be fixed soon.

Read more about Open Source vs Commercial also in my blog about ‘Install Qt 5.6‘

Here are my steps to download and install Qt 5.9 (commercial):

Install Qt 5.9

Go to your Qt Account – Downloads and select the Qt Online Installer:

See available downloads:

I selected the macOS online installer:

Here’s my download on OSX:

Double click to install:

Log into your Account:

Select the folder where to install:

It’s a good idea to use installation pathes without spaces. see also here.

As next select your components:

accept the license:

and wait for the installer:

If Installer finished, I’m not launching Qt Creator yet.

Start Qt Creator with -settingsPath

All Qt Creator instances by default share the settings. Having the new Qt Creator 4.3 and old 4.2.1, 4.0.2, 3.6.2 using the same settings is no good idea. Also I want to use different working directories for my Qt 5.6, 5.7, 5.8 and the new Qt 5.9 Release.

You can start Qt Creator with parameter -settingsPath – here’s HowTo do this from OSX:

Search for the Qt Creator.app from Qt 5.9 and do a right-click on the app. Here’s the content:

rename Qt Creator to something like Qt Creator-bin:

From a Text Editor create a Script to execute the Qt Creator-bin with a parameter.

Qt Creator will create the QtProject folder to store all the configuration settings.

Now you can start multiple Qt Creator versions without any collision.

Qt Creator 4.3

At first I’m changing QtCreator’s language on my german MacBookPro to english and restart

Qt Creator Preferences Working Directory

Set your working directory for 5.9, if you are using different directories as I’m doing:

Qt Creator Preferences Android

Take a look at your Devcies -> Android preferences:

Select your SDK and NDK locations and check ‘Gradle’:

Important: Don’t use a newer NDK ! Please always use r10e because of some trouble with the newer ones.

Qt Creator External Tools

Translations

I’m developing business apps and business apps always need support of languages (i18n). Configuring the External Tools for Linguist (Qt’s Tool to translate text from your QML and C++ sources) will make it more comfortable.

I like to use Tools in english, but the language cannot be changed yet for Linguist, so the trick is to rename the translations file, which in my case is 5.9 –> clang_64 –> translations –> linguist_de.qm:

Under Preferences –> Environment –> External Toolsthere already exist access to commands for lupdate and lrelease. (lupdate is looking for the strings you marked as translatable and to create or update the translation files <app>.ts. Using Linguist or external tools you can then translate the strings. lrelease compiles these translations from *.ts into *.qm. Only *.qml files will be deployed to your device)

I found out that the default configuration doesn’t work on Android and iOS – so I’m using the executable from …/5.9/clang_64/bin:

Test if Linguist will start. From External Tools

Linguist should start:

it’s a good idea to use a shortcut:

Refresh .pro

Adding new QML files to a project doesn’t refresh the project view automatically. Open the .pro change something, close .pro updates project folders.

I wanted to do this by a shortcut. The trick is to execute a script to “touch” the .pro file.

Run Android for Work APPs

Some of my mobile business apps are installed on customers mobile management systems (BlackBerry UEM 12.6 or so) and deployed as ‘AndroidForWork’ APPs. see also my blog here. Unfortunately Qt Creator doesn’t support setting the user id, so after debug/run on device I have to stop the deployed App using the default user and start the same app for another (AndroidForWork) user.

I created external commands for those projects and execute from External tools.

Qt 5.8 brings some more support of Text Selection Handles, but there are still also some problems. Text Selection Handles are important to make it easy on touch devices to insert text, copy text, replace text or cut text. With 5.7 single taps to get a handle to move the insert position around already works.

Select words by double tap

Qt 5.8 also supports double tap to select words – but it doesn’t work as expected. This selection mode will only be enabled if you set

selectByMouse: true

on TextField or TextArea. This works fine with TextFields, but having TextArea inside Flickable makes scrolling difficult or impossible. Qt doesn’t know if you want to change the selection or scroll inside the TextField or scroll the Page. Users will be confused and it’s not easy to know where outside the Textfield scrolling works. Hopefully in Qt 5.9 this will befixed and double tap works without setting ‘selectByMouse’.

One of my app contains many TextAreas and users are waiting for word-selection-mode, so I developed some workarounds for 5.8.

To make it easier to distinguish where’s the TextArea I placed the TextArea on top of a Pane. Now you can tell your user to scroll the Page place fingers outside the TextArea:

As soon as TextArea gets active focus, 3 buttons will appear on the right side:

clear

toggle selection mode

done

As soon as the user does a double-tap on a word both text selection handlers become visible and it’s easy to move them around to select more or less.

Also please notice on top a menu to select all, cut, copy and paste.

On iOS this is different: at first do the double tap to select a word – then please do a long press on the selection to get a cut, copy, paste, delete menu just on top of the selection:

Single tap does work with or without setting ‘selectByMouse’:

To insert from clipboard do a long-press: ‘insert’ menu appears on top of cursor position.

Tap on the Toggle Button to set selectByMouse = false to make it easier to scroll also while inside the Textfield.

When you’re ready with text editing tap on the ‘Done’ Button. Done Button gets focus and all Handles disappear. Also Done and Toggle Button disappear.

As long as there’s some text, the clear Button makes it easy to clear the field:

Here’s the workaround. I placed all of this into ‘TextAreaRow.qml’ – then it will be easy to change when 5.9 comes out.

Deploy to Device

Hint: Deploying the APP from QtCreator the first time you’ll get this info:

YES will delete the installed work app and install your APP. If installing fails, then probably the APP is marked as ‘required’ – ask your admin to set the APP as ‘optional’ to be able to delete the APP.

If all works well, the APP (named PegelMeter) will appear twice on your device.

Run as Work App

QtCreator starts the APP without –user which always will use the default one (0)

I’ll open a bug report and request to add a Variable USER_ID so this can be placed inside .pro and added to adb start command by Qt build process.

Starting the work APP from Terminal you’re loosing the log output inside QT Creator. Workaround could be to log from adb or to use an extra tool.

This will give you the logs using adb:

adb -d logcat libpegelMeter_x.so:D *:S

A special tool gives you some more comfort filtering the logs. For OSX I can recommend LogRabbit. It’s easy to filter out the logs from your APP.

External Tool

As we have seen, Build and Run the APP starts the private APP. So you have to stop and close the private APP and then start the work APP from Terminal.

To make this easier I added this to External Tools in Qt Creator:

I checked Output: Show in Pane – but nothing is printed. Probably I forgot something to tell External Tools that APP output should be visible in Application Output Pane. As long as this doesn’t work I’m using LogRabbit (see above)