我正在使用 loadItemForTypeIdentifier:options:completionHandler:NSItemProvider对象上的方法,用于通过iOS 8中的Share扩展从Safari中提取URL。
在Objective-C中,此代码和工作以及块运行。
[itemProvider loadItemForTypeIdentifier:(@"public.url" options:nil completionHandler:^(NSURL *url, NSError *error) {
//My code
}];
在Swift中,它看起来非常相似,但是关闭并没有运行。此外,itemProvider.hasItemConformingToTypeIdentifier("public.url")
会返回YES
,因此必须有一个有效的对象来解析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>
我做错了什么?
答案 0 :(得分:10)
呼叫
self.extensionContext!.completeRequestReturningItems([], completionHandler: nil)
在completionHandler结束时而不是在didSelectPost()结束时调用它
答案 1 :(得分:5)
由于必须在调用所有completionHandler之后调用completeRequestReturningItems,因此以下是我的工作。
s.public_header_files = 'AFNetworking/*.h'
s.source_files = 'AFNetworking/AFNetworking.h'
s.subspec 'Serialization' do |ss|
ss.source_files = 'AFNetworking/AFURL{Request,Response}Serialization.{h,m}'
ss.ios.frameworks = 'MobileCoreServices', 'CoreGraphics'
ss.osx.frameworks = 'CoreServices'
end
s.subspec 'Security' do |ss|
ss.source_files = 'AFNetworking/AFSecurityPolicy.{h,m}'
ss.frameworks = 'Security'
end
s.subspec 'Reachability' do |ss|
ss.source_files = 'AFNetworking/AFNetworkReachabilityManager.{h,m}'
ss.frameworks = 'SystemConfiguration'
end
答案 2 :(得分:4)
我不相信这一点,但看看这个人是如何做到的:https://github.com/oguzbilgener/SendToInstapaper/blob/master/ShareExtension/SendingViewController.swift
答案 3 :(得分:0)
过去几周我一直在争论这个问题,并最终找到了这个问题。我与Objective C或Swift无关,它似乎只是Apple代码中的一个错误。
似乎(在iOS 8.0中),只有在使用自己的UIViewController
子类时才会调用完成块。如果您使用的是SLComposeServiceViewController
的子类,则不会调用完成块。
这真的很烦人,因为默认情况下,XCode会为您创建一个ShareViewController
,其子类为SLComposeServiceViewController
。要解决此问题,您只需修改ShareViewController以继承UIViewController
。这仍然可以访问extensionContext
属性,但您显然会失去所有不错的标准功能,并且必须从头开始实现您的用户界面。
我已经向Apple提交了雷达,但尚未得到答复。希望这将在未来的更新中得到修复。
答案 4 :(得分:0)
我从来没有管理completionHandler正常工作,没有用户界面的Share扩展(在这种情况下扩展&#39; s类是NSObject的子类)。
尽管[itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeURL]
返回YES
,但在设备或模拟器上永远不会调用completionHandler。
在尝试不同的方法后,我最终得到了基于javascript将URL传递回扩展的解决方法(抱歉,因为我使用ObjC而不是Swift作为我的例子)。
Info.plist
NSExtension部分:
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>NSExtensionActivationRule</key>
<dict>
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
<integer>1</integer>
</dict>
<key>NSExtensionJavaScriptPreprocessingFile</key>
<string>Action</string>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.services</string>
<key>NSExtensionPrincipalClass</key>
<string>ActionRequestHandler</string>
</dict>
Javascript Action.js
文件:
var Action = function() {};
Action.prototype = {
run: function(arguments) {
arguments.completionFunction({ "currentURL" : window.location.href })
},
finalize: function(arguments) {
}
};
var ExtensionPreprocessingJS = new Action
ActionRequestHandler.h
头文件:
@interface ActionRequestHandler : NSObject <NSExtensionRequestHandling>
@end
ActionRequestHandler.m
基于默认操作扩展模板:
#import "ActionRequestHandler.h"
#import <MobileCoreServices/MobileCoreServices.h>
@interface ActionRequestHandler ()
@property (nonatomic, strong) NSExtensionContext *extensionContext;
@end
@implementation ActionRequestHandler
- (void)beginRequestWithExtensionContext:(NSExtensionContext *)context {
// Do not call super in an Action extension with no user interface
self.extensionContext = context;
BOOL found = NO;
// Find the item containing the results from the JavaScript preprocessing.
for (NSExtensionItem *item in self.extensionContext.inputItems) {
for (NSItemProvider *itemProvider in item.attachments) {
if ([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypePropertyList]) {
[itemProvider loadItemForTypeIdentifier:(NSString *)kUTTypePropertyList options:nil completionHandler:^(NSDictionary *dictionary, NSError *error) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self itemLoadCompletedWithPreprocessingResults:dictionary[NSExtensionJavaScriptPreprocessingResultsKey]];
}];
}];
found = YES;
}
break;
}
if (found) {
break;
}
}
if (!found) {
// We did not find anything - signal that we're done
[self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
// Don't hold on to this after we finished with it
self.extensionContext = nil;
}
}
- (void)itemLoadCompletedWithPreprocessingResults:(NSDictionary *)javaScriptPreprocessingResults
{
// Get the URL
if ([javaScriptPreprocessingResults[@"currentURL"] length] != 0) {
NSLog(@"*** URL: %@", javaScriptPreprocessingResults[@"currentURL"]);
}
// Signal that we're done
[self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
// Don't hold on to this after we finished with it
self.extensionContext = nil;
}
@end
希望它可以帮助某人节省几个小时来完成握手问题。
答案 5 :(得分:0)
我的iOS 12.1中有相同的问题。我在打电话
loadItemForTypeIdentifier:kUTTypeData
代替kUTTypeImage
等。它对我有用。