Cordova iOS вылетает при таргетинге на удаленный сервер - PullRequest
0 голосов
/ 18 декабря 2018

У меня есть приложение Cordova, построенное на Angular 1.6 и Ionic v1.У меня ужасная проблема с iOS, и я даже не знаю, что происходит не так.Я объясню проблему и то, что я пробовал до сих пор, надеюсь, кто-то пролил некоторый свет на это.

Проблема
У нас есть экран, который является простой формойВы вводите текст и добавляете вложения, если хотите.Для вложений вы можете:

  • Сделать снимок с камеры
  • Снимать видео с вашей камерой
  • Запись звука
  • Выберите из своегобиблиотека
  • Выберите из вашего iCloud Drive (iOS) или Файловой системы (Android)

Затем можно сохранить запись, в которой все хранится в файловой системе.Или загрузите на сервер, который снова сохраняет запись на вашем устройстве.

Проблема заключается в том, что, когда я выбираю файл из библиотеки или любого другого источника, приложение неожиданно падает вскоре после этого.Я могу добавить вложения и сохранить / загрузить, но когда я ухожу, приложение вылетает.Это происходит только на iOS.Нет ошибок, нет предупреждений, нет отладочной информации, просто происходит сбой.Я проверил журналы сбоев на своем iPhone, и, по-видимому, основной поток блокируется более 5 секунд.Что вызывает исключение Watchdog .Трудно сказать, что вызывает блокировку потока, не знаю.

Я использую iPhone 8 под управлением iOS 12.1.Стоит отметить, что приложение отлично работает на симуляторе, там нет ошибок или сбоев.

Что я уже пробовал
Сначала я подумал, что, возможно, что-то не так с моимкод.Поэтому я построчно просматривал каждый файл кода, реорганизовывал свой код JS и улучшал качество кода.Убедился, что обещания работают должным образом, исправлены предупреждения JSLint / TSLint и т. Д.

Я обновил все плагины Cordova до их последних версий.Также удалены обе платформы и добавлены последние версии.Никто из них не помог.Поэтому я подумал, может быть, мне не хватает причуд конфигурации или что-то.Копался в документации github и SO-потоках, не нашел ничего полезного.Некоторые другие вещи, которые я пробовал:

  • Отключил HTTPS на нашем производственном сервере и отправил все через HTTP
  • Добавил NSAppTransportSecurity в настройки * .plist файл и занесен в белый список нашего домена
  • Имеет дело с Content-Security-Policy , даже полностью его удалил
  • Конфиденциальность Описания настроены правильно(NSCameraUsage и т. Д.)

Ни один из них не работал.Я боролся с этой проблемой уже две недели.

Странная часть
Что меня смущает, так это то, что когда я нацеливаюсь на свою локальную машину разработчика, то есть когда я устанавливаю базовый URL-адрес для своих вызовов API, чтобы указывать на мой локальныйIIS, приложения работают отлично.Нет ошибок / ошибок, нет сбоев.

Но когда я нацеливаюсь на наш удаленный сервер, приложение вылетает, когда я пытаюсь работать с вложениями (камерой, iCloud и т. Д.).Я понятия не имею, что мне здесь не хватает.Там нет никаких различий между моей машиной и нашим удаленным сервером.Оба запускают одно и то же программное обеспечение, одну и ту же конфигурацию, а мобильное приложение имеет одинаковую сборку и работает на одном устройстве.

Так что я могу с уверенностью сказать, что эта проблема не имеет ничего общего с кодом моего приложения или Cordova и его плагинами.Та же самая сборка отлично работает при нацеливании на мой локальный IIS.

Мое приложение уже запущено, и это нужно исправить СЕЙЧАС.Это сводит меня с ума, я перепробовал все, что только мог придумать, и все же не повезло.У кого-нибудь была похожая проблема?Любая помощь приветствуется.

Я не уполномочен делиться своим кодом, и, как я уже сказал, в коде нет ничего плохого, он работает абсолютно нормально при настройке моего локального IIS.Но для справки, вот некоторая информация о моем проекте.

Настройки в Config.xml

<preference name="SplashScreen" value="screen" />
<preference name="windows-target-version" value="10.0" />
<preference name="AndroidPersistentFileLocation" value="Internal" />
<preference name="iosPersistentFileLocation" value="Library" />
<preference name="webviewbounce" value="false" />
<preference name="UIWebViewBounce" value="false" />
<preference name="DisallowOverscroll" value="true" />
<preference name="BackupWebStorage" value="local" />

Плагины Cordova

<plugin name="cordova-plugin-geolocation" spec="^2.4.3">
    <variable name="GEOLOCATION_USAGE_DESCRIPTION" value="Location access allows you to capture your geolocation information on to your records." />
</plugin>
<plugin name="cordova-plugin-device" spec="^1.1.7" />
<plugin name="cordova-plugin-whitelist" spec="^1.3.3" />
<plugin name="cordova-plugin-app-icon-changer" spec="^1.0.0" />
<plugin name="es6-promise-plugin" spec="^4.2.2" />
<plugin name="cordova-plugin-ios-camera-permissions" spec="^1.2.0">
    <variable name="CAMERA_USAGE_DESCRIPTION" value="Camera access allows you to capture and attach photos that you take to your records." />
    <variable name="MICROPHONE_USAGE_DESCRIPTION" value="Microphone access allows you to capture voice information to your records." />
    <variable name="PHOTOLIBRARY_ADD_USAGE_DESCRIPTION" value="Photo library access allows you to upload your photos and media files to your records." />
    <variable name="PHOTOLIBRARY_USAGE_DESCRIPTION" value="Photo library access allows you to upload your photos and media files to your records." />
</plugin>
<plugin name="cordova-plugin-android-fingerprint-auth" spec="^1.4.1" />
<plugin name="cordova-plugin-inappbrowser" spec="^3.0.0" />
<plugin name="cordova-plugin-filechooser" spec="1.1.0" />
<plugin name="cordova-plugin-crosswalk-webview" spec="2.4.0">
    <variable name="XWALK_VERSION" value="23+" />
    <variable name="XWALK_LITEVERSION" value="xwalk_core_library_canary:17+" />
    <variable name="XWALK_COMMANDLINE" value="--disable-pull-to-refresh-effect" />
    <variable name="XWALK_MODE" value="embedded" />
    <variable name="XWALK_MULTIPLEAPK" value="true" />
</plugin>
<plugin name="cordova-plugin-statusbar" spec="2.4.2" />
<plugin name="cordova-plugin-add-swift-support" spec="1.7.2" />
<plugin name="cordova-plugin-touch-id" spec="3.4.0">
    <variable name="FACEID_USAGE_DESCRIPTION" value="OnRecord would like to access your touch ID to let you log in securely." />
</plugin>
<plugin name="cordova-plugin-media-playback" spec="1.0.2-dev5" />
<plugin name="cordova-plugin-documentpicker" spec="1.0.0" />
<plugin name="cordova-plugin-file" spec="6.0.1" />
<plugin name="cordova-plugin-file-transfer" spec="1.7.1" />
<plugin name="cordova-plugin-media-capture" spec="3.0.2" />
<plugin name="cordova-plugin-camera" spec="4.0.3" />

Content-Security-Policy в index.html

<meta http-equiv="Content-Security-Policy" content="default-src 'self' gap://ready ms-appdata file://* *; img-src 'self' content: android-webview-video-poster: data: *; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://maps.googleapis.com https://maps.gstatic.com; media-src *; connect-src *">

Политики безопасности транспорта приложения

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
  <key>NSAllowsArbitraryLoadsInWebContent</key>
  <true/>
  <key>NSAllowsLocalNetworking</key>
  <true/>
  <key>NSExceptionDomains</key>
  <dict>
      <key>your.domain.com</key>
      <dict>
          <key>NSIncludesSubdomains</key>
          <true/>
          <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
          <true/>
          <key>NSTemporaryExceptionMinimumTLSVersion</key>
          <string>1.0</string>
          <key>NSTemporaryExceptionRequiresForwardSecrecy</key>
          <false/>
      </dict>
  </dict>
</dict>

КонфиденциальностьОписания (разрешения)

<key>NSFaceIDUsageDescription</key>
<string>This app would like to access your touch ID to let you log in securely.</string>
<key>NSCameraUsageDescription</key>
<string>This app needs camera access</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app would like to access your location to let you track your records.</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app needs microphone access</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app needs write-access to photo library</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs read/write-access photo library access</string>

Дайте мне знать, если вам нужна дополнительная информация или какие-либо дополнительные объяснения.Я попытался описать проблему как можно лучше.Напомним:

Приложение работает без сбоев при нацеливании на мой локальный компьютер, но вылетает при нацеливании на наш удаленный сервер.Меня беспокоит то, что это не должно иметь ничего общего с моим приложением.Плагин камеры, выбор файлов из разных источников и т. Д. Происходит локально на устройстве, какое отношение это имеет к моему базовому адресу API ?!Очень странно.

Обновление: уточнение
После дополнительных тестов я выяснил, что вызывает сбой приложения.Хотя все еще неясно, с точки зрения UX, это то, что происходит на iOS:

Как только я использую плагин Camera (cordova-camera), вскоре после этого происходит сбой приложения.Не имеет значения, выбираю ли я файл из списка / библиотеки фотоаппарата, или делаю снимок и т. Д. Я просто открываю камеру или библиотеку, отменяю и перемещаюсь.Приложение вылетает.Ясно, что это как-то связано с плагином камеры.

Что меня беспокоит, так это то, что, как я упоминал ранее, когда я нацеливаюсь на свой локальный IIS путем изменения базового URL-адреса, приложение работает нормально.Я не понимаю, почему это связано с использованием камеры, потому что это происходит локально на устройстве.Сейчас я размышляю о том, что, возможно, что-то заставляет приложение генерировать исключения, потому что удаленный URL-адрес использует HTTPS.Но я не получаю никаких предупреждений / ошибок в XCode, так что, кто знает.

Конечно, проблема не в cordova-ios, плагине камеры, моем коде JS или каких-либо конфигурациях безопасности (App Transport Security и Content-Security-Policy).Потому что приложение отлично работает, ориентируясь на мой IIS.Я думаю, что я что-то здесь упускаю.

1 Ответ

0 голосов
/ 25 декабря 2018

Я наконец нашел причину сбоя приложения для iOS.Проблема была в нашем коде, но, тем не менее, она имела отношение и к Cordova, в частности к плагинам File и Camera.

В нашем проекте был класс TypeScript, который был разработан кем-то давно.Этот класс обрабатывает доступ к данным, используя плагин File и собственную файловую систему.Мы использовали его для хранения объектов JSON на устройстве, которое работало нормально, но только для небольших случаев, таких как сохранение файла или двух.Вы получаете некоторые данные с сервера, и для каждой записи мы создаем файл JSON в файловой системе и сохраняем его.Проблема возникла, когда мы использовали это в цикле.Скажем, вы получаете 100 записей обратно с сервера, и внутри цикла вы вызываете метод save для хранения записей.

Это работало нормально, но сразу после использования плагина «Камера» (или иногда других плагинов, таких как «Выбор документов iCloud») приложение внезапно зависало.Я предполагаю, что плагин File или операции записи приводили к утечкам памяти, или приложению не хватало памяти, а впоследствии доступ к плагину Camera приводил к сбою приложения.Я не совсем уверен, почему на Android все работало нормально, возможно, потому, что движок Cordova и файловая система Android отличаются.

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

Я рад, что наконец понял это, но это ужасный кошмар для отладки плагинов Cordova и обнаружения утечек памяти.Осталось только заменить LocalStorage на что-то более надежное, например SQLite.Потому что ОС может решить очистить данные, когда мало памяти / пространства, и мы не можем их контролировать.На данный момент это совершенно нормально.Я пытался использовать модуль Ionic Storage, потому что он использует SQLite и позволяет хранить пары JSON или ключ / значение.Но я не смог использовать модуль в Angular 1, который является обломом, потому что я могу нормально использовать другие модули Ionic Native.Дело закрыто.

...