Aleksandr PanjushkinDec. 24, 2019, 2:58 p.m.

Создание приложения для iOS в QtCreator

Content

Данная статья - это записка для самого себя на тему создания приложения для iOS в среде QtCreator.

Задача: сделать приложение для iPhone/iPad, которое можно выложить в AppStore. При этом максимально задействовать инструменты QtCreator и минимально Xcode.

Что имеем:

  • MacBook Pro с macOS Catalina (ver.10.15.2) (подойдёт любой мак, будет ли работать на виртуалках - не знаю)
  • Xcode (ver.11.3) (нужен обязательно, без него ничего не заработает)
  • QtCreator (ver.4.10.2) и Qt 5.12.6 (последняя LTS версия на момент написания статьи)
  • iPhone 7 Plus для тестирования работоспособности
  • Некоторое кол-во времени, нервов и настойчивости, чтобы во всём разобраться.

Запуск тестового приложения

Приложение, для которого я занялся вопросом установки на iOS, работает с картой и геолокацией пользователя, поэтому для данной статьи возьмём приложение из стандартных примеров - Places Map (QML) ( ссылка ).

Копируем пример (мы будем вносить в него небольшие дополнения) и открываем в QtCreator.

Вибираем подходящий кит (симулятором из QtCreator я не пользовался):

Конфигурационный файл

И первое, что мы должны сделать - собрать проект.

Затем мы переходим в папку сборки (в моём случае это /Users/ap/Downloads/build-places_map-Qt_5_12_6_for_iOS-Debug) берём оттуда файл Info.plist, который переносим в папку ios, которую создаём в корне нашего проекта.

Добавляем файл Info.plist в наш проект.

Получаем вот такую структуру проекта:

Осталось добавить наш файл в сборку. Для этого в *.pro файл - places_map.pro добавляем следующий код:

ios {
    QMAKE_INFO_PLIST = ios/Info.plist
}

Делаем данное добавление только для платформы ios.

Теперь при сборке проекта всегда будет использоваться наш Info.plist.

Версия, компания, исполняемый файл

Вносим дополнения в *.pro файл. Добавляем информацию о версии, нашей компании и наименовании исполняемого файла (не путать названием, которое будет отображатся для пользователя на телефоне).

VERSION = 0.1.1

QMAKE_TARGET_BUNDLE_PREFIX = "ru.mycompany"
QMAKE_BUNDLE = "places_map"
TARGET = "places_map"

QMAKE_BUNDLE и TARGET указывают на одно и то же. Я не понял принципиальных различий между ними. И вообще они не являются обязательными (если для вас только не принципиально, чтобы название исполняемого файла отличалось от названия проекта).

Версия обязательна. Без версии проект не скомпилируется.

Данные параметры не являются платформозависимыми.

Минимальная версия iOS

В *.pro файле можно также указать минимальную версию iOS, на которой будет работать ваше приложение.

К моему большому сожалению, я не нашёл таблички, где было бы указано, с какими версиями работают компоненты Qt. Логично было бы предположить, что Qt при сборке сама сможет вычислить минимальную версию и подставить её, но, к сожалению, мне приходилось действовать наугад. Возможно, я просто не нашёл нужную информацию и буду рад, если мне подскажут где её искать.

Для этого добавляем в секцию ios *.pro файла следующую строку:

QMAKE_IOS_DEPLOYMENT_TARGET =9.0

В приведённом примере - минимальная версия 9.0.

Если строку не указать, будет подставлена самая последняя на текущий момент версия (на сегодня это 11).

Наименование приложения

В ряде случаев мне не удалось найти способа внесения параметров только в .pro файл, пришлось прописывать напрямую в Info.plist. На мой взгляд это не совсем правильно, поэтому я буду благодарен, если мне подскажут, как эти данные можно было внести в .pro и не трогать Info.plist.

Для изменения названия приложения (названия, которое будет видеть пользователь iOS), необходимо изменить значение (string) ключа (key) CFBundleDisplayName в файле Info.plist. Например, так:

<key>CFBundleDisplayName</key>
<string>Places Map</string>

Использование геолокаций

Для использования геолокаций, микрофона, камеры и т.п. сервисов необходимо в файле Info.plist указать об этом запрос на разрешение. Делается это путём добавления специальных ключей.

В случае, если нам нужно запросить разрешение на использование геолокации во время использования приложения, мы используем ключ NSLocationWhenInUseUsageDescription. В значении ключа мы должны указать описание, которое будет видно пользователю, в котором нужно указать причину, по которой нам требуется данный сервис. Без этого описания вашу программу могут заблокировать на AppStore.

<key>NSLocationWhenInUseUsageDescription</key>
<string>This app uses a user's locations to find nearest pizza.</string>

Подробнее информацию об используемых ключах можно найти в документации к iOS.

Иконки приложения

Важный этап - создание иконок приложения. Без них ваше приложение не будет добавлено в AppStore.

Подробно о создании иконок для разных версий описано в инструкции на сайте qt.io - https://doc.qt.io/qt-5/ios-platform-notes.html.

Я сделал всё проще. Нам потребуется файл размером 1024х1024 с нашей иконкой.

Заходим на сайт https://www.iconsgenerator.com/Home/AppIcons (есть и другие, но этот сгенерировал все нужные размеры, чем не смогли похвастаться другие сервисы), закидываем наш файл и скачиваем сгенерированные иконки.

Получим папку Assets.xcassets (название не важно, расширение важно), в которой будут наши иконки и json файлы с привязанными размерами по типам устройств.

Добавляем эту папку в наш проект в папку ios.

Затем нам осталось добавить в раздел ios файла *.pro информацию о наших иконках:

    QMAKE_ASSET_CATALOGS += ios/Assets.xcassets

Загрузочный экран

Этот шаг не является обязательным, т.к. простой загрузочный экран с указанием наименования вашего исполняемого файла будет создан при сборке. Но согласитесь, с красивой загрузочной картинкой приложение выглядит лучше. Поэтому создадим свою.

Создадим файл с логотипом. Назовём его, например, CustomScreenLogo.png . Разместим его в папке ios и добавим в проект.

Теперь нужно собрать проект, перейти в папку сборки и найти файл с расширением xcodeproj . В нашем случае это places_map.xcodeproj . Щелкаем по нему правой кнопкой и переходим в его содержимое. Копируем файл LaunchScreen.xib в папку ios нашего приложения и переименовываем его в CustomScreen.xib .

В названии важно, чтобы расширение было xib, а в названии не фигурировало LaunchScreen.

Стоит отметить, что по информации на различных сайтах Apple сейчас постепенно старается всех переводить на Storyboard. Но я всё же старался использовать вариант с xib файлом, как это предложено в документации к Qt.

Добавляем в файл *.pro в раздел ios следующие строки:

    app_launch_screen.files = $$PWD/ios/CustomScreen.xib $$files($$PWD/ios/CustomScreenLogo.png)
    QMAKE_BUNDLE_DATA += app_launch_screen

А в файле Info.plist в ключе UILaunchStoryboardName указываем CustomScreen (название нашего xib файла без расширения).

И заново собираем проект. И запускаем файл xcodeproj в Xcode.

В папке BundleData у нас должны теперь быть наши добавленные файлы:

Открываем файл CustomScreen.xib.

Удаляем лейблы Label и places_map. Щёлкаем на плюсик в верхней правой части и добавляем в раздел View элемент Image VIew. И в правой части в разделе Image выбираем наш логотип CustomScreenLogo.png.

Открываем вкладку Size Inspector и указываем Autoresizing, чтобы наш логотип изменял размер на разных устройствах.

Стоит ещё поменять цвет фона View.

Затем всё сохраняем, закрываем Xcode и ещё раз собираем проект в QtCreator.

Проверка работоспособности

Теперь можно запустить проект на вашем iOS устройстве и проверить его работоспособность.

Рассказывать о том, как выложить проект в AppStore не буду - он полностью готов к выгрузке как обычный проект Xcode, а в сети довольно много инструкций, как это сделать. Только для выгрузки используйте Release сборку.

Использованные материалы

Platform Notes - iOS

QMAKE Variable reference

Icon generator

Вопросы, которые у меня остались

  • Как проверить, что пользователь разрешил использование геолокации и иных сервисов? Как запросить разрешение в процессе работы приложения по мере необходимости?
  • При сборке выскакивает одна ошибка -
    AppIcon.appiconset/[][ipad][76x76][][][1x][][]:-1: error: notice: 76x76@1x app icons only apply to iPad apps targeting releases of iOS prior to 10.0.
    . Её можно избежать, если прописывать иконки непосредственно в Info.plist, но подобная пропись затем не даёт выгрузить программу в AppStore. По идее ошибка ничему не мешает, но раздражает. Возможно есть способ как-то её убрать?
  • Как-то можно устанавливатьразмер картинки в статье? А то уж больно большие некоторые картинки получились.
We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
Support the author Donate

для последнего Xcode и для последних версий iOS нужно брать Qt 5.14.
по поводу виртуалки - все работает нормально но без сборки на живой айфон у меня не получилось получить бинарник который принимает стор.
согласно последним соглашениям в Info.plist дожны быть обязательно указаны поля NSCameraUsageDescription, NSLocationAlwaysUsageDescription, NSLocationWhenInUseUsageDescription.
после первого создания Info.plist и вносения в него изменений - рекомендую его бекапить, посколько при каждой сборке он будет перезатираться

Comments

Only authorized users can post comments.
Please, Log in or Sign up
Timeweb

Let me recommend you the excellent hosting on which EVILEG is located.

For many years, Timeweb has been proving his stability.

For projects on Django I recommend VDS hosting

View Hosting
VS

C++ - Тест 003. Условия и циклы

  • Result:14points,
  • Rating points-10
VS

C++ - Тест 003. Условия и циклы

  • Result:14points,
  • Rating points-10
IP

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:10points,
  • Rating points-10
Last comments
A
  • Andrey
  • April 28, 2021, 1:25 a.m.

Django - Tutorial 036. How to add authentication through social networks. VKontakte

после того как дам разрешение для просмотра моего емайл, вот такая ошибка: AuthForbidden at /social-auth/complete/vk-oauth2/ Your credentials aren't allowed Вот сетингс: SOC…
DV

Qt/C++ - Lesson 051. QMediaPlayer – simple audio player

Добрый вечер. Хотел бы получить консультацию по работе с проектом на Mac OS. Открыл проект в QT и собрал его. Проблема в том, что он не воспроизводит треки и их названия зацикленно мелькают в по…
SS

Как соответствовать новым требованиям Google Play

Добрый день. Спасибо вам огромное за вашу статью! только начинаю изучать QT под Андроид 4 дня потратил на то чтобы подобрать версию QT которая наконец то скомпилирует мне на windo…
YA

PyQt5 - Tutorial 009. Using QThread with MoveToThread

Hello. Let's say I want to send some variables to "run" define. How can we do that? I modified your code, I tried something like below, but the GUI is frozen that way. I could not be able to und…
R

Распознавание изображений на Python с помощью TensorFlow и Keras

почему то вместо 50000 обрабатывает по 782 картинки кажду. эпоху
Now discuss on the forum

Потеря данных в сигнал/слот

вопрос решен
M

Qt/QML/Android(navigation button) - Стандартные клавиши навигации Андроид

Здравствуйте, пытаюсь заставить работать стандартную андроид-клавишу "назад", пытался разными способоами, они приведены в закомментированном коде. В том числе использовал https://evileg.com/ru/f…
M

Как включить OpenGL в Adnroid эмуляторе QtCreator

Здравствуйте, у меня работают виртуальные машины с Android, но только в дефолтной был включен OpenGL. Потом я удалил дефолтную, создал новые, а в них OpenGL отключен. Справа на втором скриншоте …

QScrollArea dynamically add QCheckBoxes

Всё правильно. Это просто спамер, который отправился в вечный бан.

qml зажатая кнопка мыши в одной MouseArea и сигналы мыши из другой MouseArea

добрый, вы не пробовали отслеживать область видимости мышки через: _mouseArea.containsMouse и когда мышка будет в другой зоне видимости обрабатывать ее состояния?
About
Services
© EVILEG 2015-2021
Recommend hosting TIMEWEB