Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Share iOS 8共享扩展loadItemForTypeIdentifier:选项:completionHandler:未执行完成关闭_Share_Swift_Ios8_Ios App Extension - Fatal编程技术网

Share iOS 8共享扩展loadItemForTypeIdentifier:选项:completionHandler:未执行完成关闭

Share iOS 8共享扩展loadItemForTypeIdentifier:选项:completionHandler:未执行完成关闭,share,swift,ios8,ios-app-extension,Share,Swift,Ios8,Ios App Extension,我在用电话 NSItemProvider对象上的loadItemForTypeIdentifier:options:completionHandler:method,通过iOS 8中的共享扩展从Safari提取url 在Objective-C中,此代码和代码有效,块运行 [itemProvider loadItemForTypeIdentifier:(@"public.url" options:nil completionHandler:^(NSURL *url, NSError *error)

我在用电话 NSItemProvider对象上的loadItemForTypeIdentifier:options:completionHandler:method,通过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
,因此必须有一个有效的对象才能从
itemProvider
内部解析url

itemProvider.loadItemForTypeIdentifier("public.url", options: nil, completionHandler: { (urlItem, error) in
    //My code
})
对于Objective-C和Swift版本,Info.plist NSExtension部分完全相同,如下所示:

<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>
NSExtension
N扩展属性
NSExtensionActivationRule
NSExtensionActivationSupportsWebUrWithMaxCount
1.
NSExtensionPointName
com.apple.share-services
NSExtensionPointVersion
1
NSExtensionPointIdentifier
com.apple.share-services
NSextensionMainstryBoard
主界面

我做错了什么?

我不认为这是我的功劳,但看看这家伙是怎么做到的:

过去几周,我一直在断断续续地与这个问题作斗争,终于找到了问题所在。我与Objective C或Swift无关,它只是苹果代码中的一个bug

似乎(在iOS 8.0中),只有在使用自己的
UIViewController
子类时才会调用completion块。如果您使用的是
SLComposeServiceViewController
的子类,则不会调用完成块

这真的很烦人,因为默认情况下,XCode会创建一个
ShareViewController
,其子类为
SLComposeServiceViewController
。要解决此问题,您只需修改ShareViewController以继承自
UIViewController
。这仍然可以访问
extensionContext
属性,但是很明显,您将失去所有良好的标准功能,必须从头开始实现UI

我已经向苹果公司提交了一份雷达报告,但还没有得到回复。希望这将在未来的更新中修复

呼叫

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

在completionHandler的末尾,而不是在didSelectPost()的末尾调用它。

我从来没有被管理过completionHandler,以便在没有用户界面的共享扩展中正常工作(在这种情况下,扩展的类是NSObject上的子类)

尽管有
[itemProvider hasItemConformingToTypeIdentifier:(NSString*)kUTTypeURL]
返回
但在设备或模拟器上永远不会调用completionHandler

在尝试了不同的方法之后,我最终找到了基于javascript将URL传递回扩展的解决方案(很抱歉,我的示例中使用了ObjC not Swift)

Info.plist
n扩展部分:


ActionRequestHandler.h
头文件:

@接口ActionRequestHandler:NSObject
@结束

ActionRequestHandler.m
基于默认操作扩展模板:

#导入“ActionRequestHandler.h”
#进口
@接口ActionRequestHandler()
@属性(非原子,强)NSExtensionContext*extensionContext;
@结束
@实现ActionRequestHandler
-(void)beginRequestWithExtensionContext:(NSExtensionContext*)context{
//不要在没有用户界面的操作扩展中调用super
self.extensionContext=上下文;
BOOL-found=NO;
//查找包含JavaScript预处理结果的项。
for(self.extensionContext.inputItems中的NSExtensionItem*项){
对于(item.attachments中的NSItemProvider*itemProvider){
if([itemProvider hasItemConformingToTypeIdentifier:(NSString*)kUTTypePropertyList]){
[itemProvider loadItemForTypeIdentifier:(NSString*)kUTTypePropertyList选项:nil completionHandler:^(NSDictionary*字典,NSError*错误){
[[NSOperationQueue mainQueue]添加操作与块:^{
[self-itemLoadCompletedWithPreprocessingResults:dictionary[NSExtensionJavaScriptPreprocessingResultsKey];
}];
}];
发现=是;
}
打破
}
如果(找到){
打破
}
}
如果(!找到){
//我们什么也没找到——发出我们已经完成的信号
[self.extensionContext completeRequestReturningItems:@[]completionHandler:nil];
//在我们完成后不要再坚持这个了
self.extensionContext=nil;
}
}
-(void)itemLoadCompletedWithPreprocessingResults:(NSDictionary*)javaScriptPreprocessingResults
{
//获取URL
如果([javaScriptPreprocessingResults[@“currentURL”]长度]!=0){
NSLog(@“***URL:%@”,JavaScriptPrepreprocessingResults[@“currentURL]”);
}
//发出信号,我们结束了
[self.extensionContext completeRequestReturningItems:@[]completionHandler:nil];
//在我们完成后不要再坚持这个了
self.extensionContext=nil;
}
@结束

希望它能帮助一些人节省几个小时来处理completionHandler问题。

由于在所有completionHandler被回调后必须调用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)
    })

我的iOS 12.1也有同样的问题。我打电话来

loadItemForTypeIdentifier:kUTTypeData 

而不是
kUTTypeImage
等。它对我很有效。

我不想说,但这是否违反了开发人员的条款和条件?新发布的NDA等@ScottMcGready你一定错过了备忘录,但他们已经放松了NDA。谷歌它。我只是认为,这是苹果-它可能在保密协议。很高兴他们能多开放一点。现在需要阅读已经更新的文档。在最新的Beta版中,在Objective-C中看到类似的问题,没有调用块
 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)
    })
loadItemForTypeIdentifier:kUTTypeData