window.open в приложении PhoneGap на iOS: этому приложению не разрешено запрашивать файл схемы

У меня есть гибридное приложение, разработанное с помощью DevExpress и PhoneGap.

Я пытаюсь открыть локальное изображение в формате jpeg через

window.open('file:///var/mobile/Containers/Data/.../image.jpg', '_system');

но он больше не работает на iPhone и iPad (последняя версия iOS 9), выдавая ошибку error: "This app is not allowed to query for scheme file".

(Приложение предварительно загрузило изображение с помощью метода Phonegap FileTransfer.download в папку, полученную с помощью метода window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, ...).)

Он отлично работает на Android, а несколько недель назад также отлично работал на iPhone. Я думаю, что это может быть связано с обновлением PhoneGap из-за обновления DevExtreme.

Раньше я использовал PhoneGap 3.7.0, теперь использую cli-5.2.0.

Я уже нашел этот вопрос (https://www.devexpress.com/Support/Center/Question/Details/Q486439), который похож, но ему уже 2 года и он, похоже, не решает мои вопросы.

Используя GapDebug, я вижу это в журнале:

<Warning>: THREAD WARNING: ['InAppBrowser'] took '38.211914' ms. Plugin should use a background thread.
<Warning>: THREAD WARNING: ['File'] took '26.509033' ms. Plugin should use a background thread.
<Warning>: -canOpenURL: failed for URL: "file:///var/mobile/Containers/Data/Application/9425CCB6-77F7-4337-B37C-7DB577C2F6B4/Documents/myDocuments/a96e7238-a502-49e6-bcd3-186937afc3cb/camera_1458208164206.jpg" - error: "This app is not allowed to query for scheme file"

Это какая-то проблема с правами доступа, но что добавить в config.xml?

Это мой config.xml:

<widget xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0" id="com.devexpress.apptemplate" version="1.0" versionCode="1">
  <name>ApplicationTemplate</name>
  <preference name="phonegap-version" value="cli-5.2.0" />
  <preference name="permissions" value="none" />
  <preference name="prerendered-icon" value="true" />
  <preference name="android-windowSoftInputMode" value="adjustResize" />
  <preference name="SplashScreen" value="splash" />
  <preference name="SplashScreenDelay" value="60000" />
  <preference name="AutoHideSplashScreen" value="false" />
  <preference name="DisallowOverscroll" value="true" />
  <preference name="StatusBarOverlaysWebView" value="false" />
  <preference name="StatusBarBackgroundColor" value="#000000" />
  <preference name="KeyboardDisplayRequiresUserAction" value="false" />
  <feature name="http://api.phonegap.com/1.0/network" />
  <gap:plugin name="com.devexpress.plugins.devextremeaddon" version="1.0.1" />
  <gap:plugin name="cordova-plugin-ios-longpress-fix" version="1.1.0" source="npm" />
  <gap:plugin name="org.apache.cordova.camera" version="0.3.6" />
  <gap:plugin name="org.apache.cordova.file" version="1.3.3" />
  <gap:plugin name="org.apache.cordova.file-transfer" version="0.5.0" />
  <gap:plugin name="org.apache.cordova.inappbrowser" version="0.6.0" />
  <gap:plugin name="org.apache.cordova.media-capture" version="0.3.6" />
  <gap:plugin name="org.apache.cordova.media" version="0.2.16" />
  <gap:plugin name="org.apache.cordova.network-information" version="0.2.15" />
  <gap:plugin name="cordova-plugin-statusbar" version="2.1.0" source="npm" onload="true" />
  <gap:plugin name="org.apache.cordova.splashscreen" version="1.0.0" onload="true" />
  <access origin="*" subdomains="true"/>
  <gap:plugin name="cordova-plugin-whitelist" source="npm"/>
  <allow-navigation href="*" />
  <allow-intent href="*" />
</widget>

Я даже добавил две строчки

  <allow-navigation href="*" />
  <allow-intent href="*" />

согласно https://github.com/apache/cordova-plugin-whitelist и это не помогает.

Я видел, что Ionic, другой гибридный фреймворк, также упоминает в своей документации http://docs.ionic.io/docs/cordova-whitelist, что могут быть проблемы с разрешениями в более новых версиях Phonegap, таких как версии CLI, и что следует использовать указанный выше <allow-navigation href="*" />, однако в моем случае это не помогает.

=== Обновление ===

Я создал два билета на github Phonegap и Cordova:

=== Обновление 2 ===

Как показано ниже, теперь я использую https://github.com/pwlin/cordova-plugin-file-opener2, который отлично работает.


person Mathias Conradt    schedule 04.04.2016    source источник
comment
У меня та же проблема... Я начал использовать cordova-plugin-file-opener2 (github.com/pwlin/cordova-plugin-file-opener2), чтобы избежать этой проблемы.   -  person gmartini20    schedule 07.04.2016
comment
@ gmartini20 Спасибо, у меня это тоже работает :)   -  person Mathias Conradt    schedule 08.04.2016
comment
@gmartini20 Не могли бы вы сделать свой комментарий ответом? Кстати: у плагина file-opener2, похоже, есть проблемы с путями к файлам, в которых есть пробелы, а у window.open() нет.   -  person Mathias Conradt    schedule 08.04.2016
comment
Проблема с пробелами в путях к файлам: github.com/pwlin/cordova-plugin -file-opener2/issues/14   -  person Mathias Conradt    schedule 08.04.2016


Ответы (2)


Я столкнулся с той же проблемой... Я начал использовать cordova-plugin-file-opener2 (github.com/pwlin/cordova-plugin-file-opener2), чтобы избежать этой проблемы.

Чтобы решить проблему с пробелами, я удалил их из targetPath:

targetPath = targetPath.replace(/ /g,'')

Итак, мой код загрузки/открытия выглядит так:

$cordovaFileTransfer.download(url, targetPath, options, trustHosts)
  .then(function(result) {
    $cordovaFileOpener2.open(targetPath, mimeType)
  })
person gmartini20    schedule 08.04.2016
comment
Я хотел сохранить исходное название. Я решил это, используя encodeURI при загрузке файла. github.com/pwlin/cordova-plugin-file-opener2/issues/ 53 - person Mathias Conradt; 08.04.2016

В iOS 9 вам нужно настроить URL-адреса, которые вы хотите запрашивать (узнайте, можете ли вы их открыть).

Для этого вам нужно отредактировать info.plist и добавить LSApplicationQueriesSchemeskey и массив строк со схемами, которые вы хотите запросить.

<key>LSApplicationQueriesSchemes</key>
<array>
 <string>file</string>
 <string>whatsapp</string>
 <string>...</string>
</array> 

Поскольку вы используете кордову, вы можете сделать это несколькими различными способами.

Вы можете открыть проект Xcode внутри платформы/ios и отредактировать файл info.plist, но в некоторых случаях проект Xcode удаляется и создается заново, и ваши изменения будут потеряны.

Другой вариант — создать простой плагин Cordova, который просто пишет в info.plist. Для этого вам нужно использовать тег config-file в файле plugin.xml.

<config-file target="*-Info.plist" parent="LSApplicationQueriesSchemes">
    <array>
        <string>file</string> 
    </array>
</config-file>

http://cordova.apache.org/docs/en/latest/plugin_ref/spec.html#platform

Третий вариант — использовать хук, хук — это файл сценария (узел, bash), который выполняется, и вы можете использовать его для записи в info.plist http://cordova.apache.org/docs/en/latest/guide/appdev/hooks/index.html

person jcesarmobile    schedule 08.04.2016
comment
Я работаю с DevExtreme (js.devexpress.com), используя Visual Studio (без XCode), который, в свою очередь, использует PhoneGap в конце концов. Там я просто использую некоторые плагины Cordova (например, белый список). У меня нет файла info.plist в моем проекте. (Извините, это мое первое гибридное приложение, использующее Phonegap/Cordova). Но, возможно, я передам ваш совет в службу поддержки DevExtreme. Спасибо за подсказку. - person Mathias Conradt; 08.04.2016
comment
Просто примечание: прежде в моем проекте window.open отлично работал на iOS 9, он просто больше не работает после недавнего обновления версии PhoneGap. - person Mathias Conradt; 08.04.2016
comment
Я дал вам 3 варианта, по крайней мере вариант с плагином должен подойти для вашего случая. Ошибка, которую вы получаете, появляется, когда используется canOpenURL, возможно, предыдущая версия Cordova не использовала ее и использовала openURL напрямую, использование openURL будет работать несколько раз (я думаю, 50), прежде чем начать сбой без сообщения об ошибке. Или, может быть, devexpress использовал Xcode 6, где вам не нужно было делать то, что я вам говорил. Чтобы использовать плагины, см. devexpress.com/Support/Center/Question/Details/KA18816< /а> - person jcesarmobile; 08.04.2016
comment
Извините, я только что погуглил плагины devexpress Cordova и вставил первую найденную ссылку. Хорошо, что вы нашли альтернативу. В любом случае, я рассмотрю вашу проблему Cordova JIRA, я думаю, что allow-intent должен обрабатывать LSApplicationQueriesSchemes - person jcesarmobile; 08.04.2016
comment
Кто-нибудь сделал крюк для этого на всякий случай. На всю жизнь я не могу понять создание хуков, но мне это нужно для моего проекта. - person Christopher D. Emerson; 19.05.2016