web-dev-qa-db-ja.com

NSITemProvider LoadItemメソッドは、URLの代わりに_nsitemProviderSandboxedResourceを返します

開発したアプリの1つでは、私は財布のパスをインポートするために共有拡張を使用します(PKPASS)。

IOS 13(最新のベータ8を含む)、IOSメールアプリ内から共有拡張子を呼び出すとき、拡張子は予想されるフォーマット(URL)でデータを受信して​​いません。

これは、共有拡張のShareviewControllerからの関連スニペットです。

if let inputItems = self.extensionContext?.inputItems,
   let inputItem = inputItems.first as? NSExtensionItem,
   let attachments = inputItem.attachments,
   let attachment = attachments.first,
   attachment.hasItemConformingToTypeIdentifier("com.Apple.pkpass" as String){
    attachment.loadItem(forTypeIdentifier: "com.Apple.pkpass" as String, options: nil) { data, error in
        print ("data: \(String(describing: data))")
}
 _

IOS 12(最新バージョン)では、iOSメールアプリの添付ファイルにもうまくいきます(追加例:ファイルアプリ内のファイルに)。データはオプションのURLを保持します。上記のPRINTステートメントは、コンソールで次のように表示されます。

data: Optional(file:///var/mobile/Library/Mail/8EF174CF-68B9-414E-A166-D04C9DBE020E/INBOX.imapmbox/Attachments/13846/2/Attachment-1.pkpass)
 _

IOS 13(Beta 8)では、IOSメールアプリでは、データはオプションの_nsitemProviderSandboxedResourceを保持します。上記のPRINTステートメントは、コンソールで次のように表示されます。

data: Optional(<_NSItemProviderSandboxedResource: 0x2839aa9e0>)
 _

これはメールアプリだけに影響を与えるようです。ファイルでアプリのデータが保持されています - 期待通り - URL。

これは、iOS 13によって導入されたいくつかの新しいセキュリティ機能を使用して、これはBuge(実際にはフィードバックアシスタントを参照してこれをすでに報告しています)またはいくつかの新しいセキュリティ機能は?この場合は添付ファイルのURL /データにアクセスする方法を教えてください。

8
Lobo

この問題の解決策を見つけました。

呼び出し時のiOS 13の前に

attachment.loadItem(forTypeIdentifier: "com.Apple.pkpass" as String, options: nil) data, error in
 _

以下のURLにもデータをダウンキャストすることができます。

if let pkPassURL = data as? URL
 _

上記の問題に記載されているように、iOS 13ではこれはもう不可能ではありません。

代わりに、Type IDとして「PUBLIC.FILE-URL」を指定してLoadItemを呼び出す必要があります。

attachment.loadItem(forTypeIdentifier: "public.file-url" as String, options: nil) { (data, error) in
 _

PKPASSアイテムの特定の場合では、私はそれらを共有するときに気づいたことに気づいた

  • walletアプリから添付ファイルは "com.apple.pkpass"にのみ適合します
  • e.からメールアプリ添付ファイルは "com.apple.pkpass"と "public.file-url"の両方に準拠します

そのため、次のコードを使用して両方の場合に対処できます。

if let inputItems = self.extensionContext?.inputItems,
   let inputItem = inputItems.first as? NSExtensionItem,
   let attachments = inputItem.attachments,
   let attachment = attachments.first,
   attachment.hasItemConformingToTypeIdentifier("com.Apple.pkpass" as String) {
    if attachment.hasItemConformingToTypeIdentifier("public.file-url" as String) {
        // extension is being called e.g. from Mail app
        attachment.loadItem(forTypeIdentifier: "public.file-url" as String, options: nil) { (data, error) in 
            if let sourcePKPassURL = data as? URL {
                //handle url here
            }
        }
    } else {
        // extension is being called from Wallet app
        attachment.loadItem(forTypeIdentifier: "com.Apple.pkpass" as String, options: nil) { (data, error) in
            if let pkPassData = data as? Data,
               let pkPass = try? PKPass(data: pkPassData) {
               // handle pkPass here
            }
        }
    }
}
 _

これはiOS 12とiOS 13の両方にとって機能します。

2
Lobo