alex_lip
alex_lip14 січня 2018 р. 14:15

Розробка на Qt для iOS

Преамбула

Найдемократичніша країна у світі створила найтоталітарнішу операційну систему. Тому якщо ви хочете тестувати ваше програмне забезпечення на IPad або IPhone вам потрібно обов'язково зареєструватися на сайті https://developer.apple.com/ як розробник. На першому етапі грошей платити необов'язково. Добрий дядько Джобс дасть вам сертифікат на використання для тестування вашого ж пристрою терміном на 7(сім) днів. Після закінчення дії сертифіката ваше ПЗ не запускатиметься і його треба буде знову закачати з комп'ютера. Якщо ви захочете встановити ваше ПЗ на пристрій іншої людини – його apple ID потрібно буде так само прописати в Xcode як і ваш.


Проблеми

Для вивчення Qt я для тестового завдання вирішив розробити мобільне робоче місце для документообігу. Оскільки документи може бути як word , pdf , jpg тощо. Мені природним чином потрібно після завантаження їх із сервера чимось їх відкривати. У Qt є чудова конструкція

QDesktopServices :: openUrl ( QUrl :: fromLocalFile ( QStandardPaths :: writableLocation ( QStandardPaths :: GenericDataLocation ) + "/temp_esd/file." + file_ext ));
// File _ ext я вытаскиваю в соответствии с MIME типом
if ( head == "Content-Type" ) {
    if ( content_from_url == "image/jpeg" )
        file_ext = "jpg";
    else if ( content_from_url == "application/pdf" )
        file_ext = "pdf";
    else if ( content_from_url == "application/vnd.openxmlformats-officedocument.wordprocessingml.document" )
        file_ext = "docx";
    else if ( content_from_url == "application/msword" )
        file_ext = "doc";
    else if ( content_from_url == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" )
        file_ext = "xlsx";
    else if ( content_from_url == "application/vnd.ms-excel" )
        file_ext = "xls";
    else if ( content_from_url == "application/vnd.oasis.opendocument.text" )
        file_ext = "odt";
    else if ( content_from_url == "application/vnd.oasis.opendocument.spreadsheet" )
        file_ext = "ods";
    else if ( content_from_url == "application/octet-stream" )
        file_ext = "7z";
    else if ( content_from_url == "video/x-msvideo" )
        file_ext = "avi";
    else if ( content_from_url == "image/bmp" )
        file_ext = "bmp";
    else if ( content_from_url == "application/cdr" )
        file_ext = "cdr";
    else if ( content_from_url == "image/gif" )
        file_ext = "gif";
    else if ( content_from_url == "video/quicktime" )
        file_ext = "mov";
    else if ( content_from_url == "audio/mpeg" )
        file_ext = "mp3";
    else if ( content_from_url == "image/png" )
        file_ext = "png";
    else if ( content_from_url == "application/vnd.ms-powerpoint" )
        file_ext = "ppt";
    else if ( content_from_url == "application/vnd.openxmlformats-officedocument.presentationml.presentation" )
        file_ext = "pptx";
    else if ( content_from_url == "application/x-rar-compressed" )
        file_ext = "rar" ;
    else if ( content_from_url == "application/rtf" )
        file_ext = "rtf";
    else if ( content_from_url == "image/tiff" )
        file_ext = "tif";
    else if ( content_from_url == "text/plain" )
        file_ext = "txt" ;
    else if ( content_from_url == "audio/x-ms-wma" )
        file_ext = "wma";
    else if ( content_from_url == "application/zip" )
        file_ext = "zip";
}

Але в IOS – відповідно до нещодавно прийнятих стандартів безпеки заборонено відкриття локального URL в одному додатку за допомогою запуску іншого. Тому під IOS використання даної конструкції викликало помилку

цей плагін не підтримується

Спочатку я пішов у бік використання Info.plist – тим більше, що під IOS він все одно потрібний. Прописав у секції

<key>LSApplicationQueriesSchemes</key>
    <array>
        <string>ms-word</string> 
        <string>ms-powerpoint</string> 
        <string>ms-excel</string>
    </array>

Але це працює, тільки якщо файли відкриваються НЕ локально – а через інтернет посилання. Після подальшого вивчення проблеми я натрапив на статтю https://code.tutsplus.com/tutorials/ios-sdk-previewing-and-opening-documents--mobile-15130 в якій описано використання UIDocumentInteractionController для відкриття файлів у «пісочниці» ios програми. Також велике спасибі Ekkehard Gentz за чудовий блог, в якому детально розписаний приклад використання вищеописаної функції Qt.

Рішення проблеми

І так маємо MAC MINI для компіляції вихідників та IPAD для тестування. На MAC MINI встановлюємо Qt. Під час встановлення вам запропонують завантажити XCODE – погоджуємось. Все чудово встановлюється. Далі в Xcode – Preferences – Accounts додаємо свій Apple аккаунт та запитуємо сертифікат (через Manage Certificates). Природно попередньо треба зареєструватися на сайті Apple як розробник. Далі слід підключити ваш IPAD і в розділі Налаштування – Developer – UI AUTOMATION – увімкнути Enable UI Automation. Таким чином, ми перевели IPAD у режим дозволеного налагодження.

У Xcode – Window – Devices and Simulators ви можете перевірити ваш підключений пристрій. Звичайно, в процесі підключення вас кілька разів запитають про довіру комп'ютера пристрою і пристрої комп'ютера - говоріть ТАК.

У QT у файлі проекту додаємо наступну секцію

ios {
OBJECTIVE_SOURCES += ios/iosshareutils.mm \
ios/docviewcontroller.mm

QMAKE_INFO_PLIST = ios/Info.plist

LIBS += - framework UIKit
}

У цій секції ми вказуємо розташування Info.plist – це текстовий конфігураційний файл, який можна правити вручну.

OBJECTIVE_SOURCES – це наші файли на OBJECTIVE-С

Директива LIBS – можливо, вже застаріла. Але я її прибирати не став.

У самих вихідниках дуже зручно використовувати директиву

#if defined( Q_OS_IOS )

QString temp_url= QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/temp_esd/file." +file_ext;
qDebug() << "path_file " << temp_url;
IosShareUtils ios;
ios.viewFile(temp_url, "View File" , "application/pdf" , 21 );

#else
QDesktopServices :: openUrl ( QUrl :: fromLocalFile ( QStandardPaths :: writableLocation ( QStandardPaths :: GenericDataLocation ) + "/temp_esd/file." + file_ext ));
#endif

Вихідні тексти ви можете переглянути у блозі https://blog.qt.io/blog/2017/12/01/sharing-files-android-ios-qt-app/

Загалом після того, як готові вихідні тексти, приступаємо до деплою. Зверніть увагу, щоб у Qt Creator при випуску на Qt 5.10 for iOS праворуч унизу від іконки телефону з яблуком горіла зелена цятка. Наведіть на неї мишкою і побачте інформацію про пристрій і чи цей пристрій працює в режимі розробника. Після цього компіляємо вихідні дані і намагаємося завантажити їх на телефон. З першого разу не виходить. Йдемо в папку Release та відкриваємо Xcode проект нашої програми. Нагорі, там, де ім'я вашої схеми, вибираємо активну схему на той пристрій, який приєднаний до комп'ютера. Потім натискаємо значок "Build and then run the current scheme". Але це ще не все. На вашому пристрої з'явиться піктограма програми, але вона не запуститься. Або запуститься, але швидко закриється. Відкриваємо Ipad - йдемо в налаштування - основні - управління пристроєм - програмне забезпечення розробника - вибираємо свій apple id - далі говоримо, що ми довіряємо цьому розробнику. Після всіх цих операцій можна спокійно деплоїти програму безпосередньо з Qt Creator.

Дякуємо всім з інтернету, хто терпляче відповідав на мої дурні питання. І бог простить тих, хто намагався струсити з мене грошей. Мені здається - якийсь альтруїзм має бути присутнім у кожного професіонала.

Невелике додавання про компіляцію проекту під старі версії iOS (8-9)

Я відкомпиляв свій проект на Qt 5.10 під iOS 10 та архітектуру arm64 (за допомогою Xcode9) – все чудово. Але коли я спробував віддеплоїти той же проект під старий iPad з iOS 9 та архітектурою armv7 у мене виникло багато проблем, які я так і не зміг вирішити. Я пробував налаштовувати архітектуру в Xcode - отримував помилки на кшталт - ignoring file LibQt5Core_debu.a

 QMAKE_IOS_DEVICE_ARCHS = armv7
 CONFIG += armv7
 QMAKE_IOS_DEPLOYMENT_TARGET = 9.0

Відкочувався на Xcode 7 – все безрезультатно. І нарешті після кількох днів безуспішних спроб ось що я вичитав

https://bugreports.qt.io/browse/QTBUG-65544

Опис Будь-якій програмі, зібраній з Qt 5.10, потрібна щонайменше iOS 10 і не розгортається на старіших пристроях (iPad 1, iPhone 5 тощо)

Навіть завантажені в AppStore, що програми не встановлюються на пристрої з iOS < 10.

Є занадто багато пристроїв з iOS 9, щоб відмовитися від його підтримки.

Ті самі програми, скомпільовані з Qt 5.9.3, чудово працюють на всіх пристроях.

Eskil Abrahamsen Blomfeldt додав коментар - 03 січня '18 10:43 Qt 5.9 є довгостроковою підтримуваною версією, яка продовжує підтримка iOS 9, якщо вашій програмі потрібна підтримка старіших пристроїв.

Для Qt 5.10, як ви кажете, мінімальна цільова версія — iOS 10. Повний список підтримуваних платформ можна переглянути тут: http://doc.qt.io/qt-5/supported-platforms.html

За даними Apple, 92% активних пристроїв зараз працюють на iOS 10 або iOS 11.

Таким чином, якщо ви хочете підтримувати старі версії iOS - використовуйте Qt 5.9.3 - все компіляється нормально відразу під потрібну архітектуру.

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

BlinCT
  • 14 січня 2018 р. 14:28

Вот честно, на сколько же муторно под огрызок что то делать. Куча проблем)
А вод линь или под Андроид все просто и тривиально))

Коментарі

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

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:50бали,
  • Рейтинг балів-4
m
  • molni99
  • 26 жовтня 2024 р. 01:37

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80бали,
  • Рейтинг балів4
m
  • molni99
  • 26 жовтня 2024 р. 01:29

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:20бали,
  • Рейтинг балів-10
Останні коментарі
ИМ
Игорь Максимов22 листопада 2024 р. 11:51
Django - Підручник 017. Налаштуйте сторінку входу до Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii Legotckoi31 жовтня 2024 р. 14:37
Django - Урок 064. Як написати розширення для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZE19 жовтня 2024 р. 08:19
Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь Максимов05 жовтня 2024 р. 07:51
Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas505 липня 2024 р. 11:02
QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Тепер обговоріть на форумі
Evgenii Legotckoi
Evgenii Legotckoi24 червня 2024 р. 15:11
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey115 листопада 2024 р. 06:04
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProject04 червня 2022 р. 03:49
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9Anonim25 жовтня 2024 р. 09:10
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Слідкуйте за нами в соціальних мережах