11

NSItemProvider オブジェクトで loadItemForTypeIdentifier:options:completionHandler: メソッドを使用して、iOS 8 の共有拡張機能を介して Safari から URL を抽出しています。

Objective-C では、このコードと動作し、ブロックが実行されます。

[itemProvider loadItemForTypeIdentifier:(@"public.url" options:nil completionHandler:^(NSURL *url, NSError *error) {
    //My code
}];

Swift では非常に似ていますが、クロージャーは実行されません。また、 itemProvider.hasItemConformingToTypeIdentifier("public.url")が返さYESれるため、 内から URL を解析するには有効なオブジェクトが必要ですitemProvider

itemProvider.loadItemForTypeIdentifier("public.url", options: nil, completionHandler: { (urlItem, error) in
    //My code
})

Info.plist NSExtension 部分は、Objective-C と Swift の両方のバージョンでまったく同じで、次のようになります。

<key>NSExtension</key>
<dict>
    <key>NSExtensionAttributes</key>
    <dict>
        <key>NSExtensionActivationRule</key>
        <dict>
            <key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
            <integer>1</integer>
        </dict>
        <key>NSExtensionPointName</key>
        <string>com.apple.share-services</string>
        <key>NSExtensionPointVersion</key>
        <string>1.0</string>
    </dict>
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.share-services</string>
    <key>NSExtensionMainStoryboard</key>
    <string>MainInterface</string>
</dict>

私は何を間違っていますか?

4

6 に答える 6

12

電話

self.extensionContext!.completeRequestReturningItems([], completionHandler: nil) 

didSelectPost() の最後に呼び出す代わりに、completedHandler の最後に

于 2014-10-14T10:06:45.900 に答える
6

すべての completionHandlers がコールバックされた後に completeRequestReturningItems を呼び出す必要があるため、以下のようにします。

 let group = dispatch_group_create()

    for item: AnyObject in self.extensionContext!.inputItems {
        let inputItem = item as! NSExtensionItem
        for provider: AnyObject in inputItem.attachments! {
            let itemProvider = provider as! NSItemProvider
            if itemProvider.hasItemConformingToTypeIdentifier("public.url") {
                dispatch_group_enter(group)
                itemProvider.loadItemForTypeIdentifier("public.url", options: nil, completionHandler: {
                    (result: NSSecureCoding!, error: NSError!) -> Void in
                    //...
                    dispatch_group_leave(group)
                });
            }
            if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeImage as String) {
                dispatch_group_enter(group)
                itemProvider.loadItemForTypeIdentifier(kUTTypeImage as String, options: nil, completionHandler: { (result, error) -> Void in
                    if let resultURL = result as? NSURL {
                        if let image = UIImage(data: NSData(contentsOfURL: resultURL)!) {
                            // ...
                        }
                    }
                    dispatch_group_leave(group)
                });
            }
        }
    }
    dispatch_group_notify(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), {
        self.extensionContext!.completeRequestReturningItems([], completionHandler: nil)
    })
于 2015-07-06T06:03:04.223 に答える
0

ここ数週間、この問題と格闘してきましたが、ついに問題を発見しました。私は Objective C や Swift とは何の関係もありません。Apple のコードのバグのようです。

UIViewController(iOS 8.0 のように) 独自のサブクラスを使用している場合にのみ、完了ブロックが呼び出されるようです。のサブクラスを使用している場合SLComposeServiceViewController、完了ブロックは呼び出されません。

デフォルトでは、XCode はShareViewControllerのサブクラスで を作成するため、これは非常に厄介ですSLComposeServiceViewController。この問題を回避するには、ShareViewController を から継承するように変更するだけですUIViewController。これでもプロパティにアクセスできextensionContextますが、明らかに標準の優れた機能がすべて失われ、UI を最初から実装する必要があります。

Apple にレーダーを提出しましたが、まだ返信がありません。うまくいけば、これは将来のアップデートで修正されるでしょう。

于 2014-09-26T09:47:28.793 に答える