Share iOS 8共享扩展loadItemForTypeIdentifier:选项:completionHandler:未执行完成关闭
我在用电话 NSItemProvider对象上的loadItemForTypeIdentifier:options:completionHandler:method,通过iOS 8中的共享扩展从Safari提取url 在Objective-C中,此代码和代码有效,块运行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)
[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