iOS Share Extension流程

我在创建共享扩展时遇到问题,例如Pinterest应用程序的共享扩展。 当用户未登录到包含应用程序时,共享扩展程序仅显示警报,并提供log incancel选项。

代码中的哪个位置决定在我的共享扩展中显示哪个视图控制器。 我看到这就像我需要从共享容器检查授权状态,如果not logged此状态,我需要提供警报控制器。 如果状态被logged我需要显示我的主视图控制器ShareViewController这是ShareViewController的子类

我的问题不是UI相关,而是放置此检查代码的位置。 我没有找到应用程序扩展启动的任何方法,所以我可以根据某些状态为扩展选择一些初始视图控制器。

在Pinterest扩展中,当用户从其包含的应用程序注销时,我看不到它们的主视图控制器。 我只看到提示选项。

第二个问题:如何以编程方式从共享扩展切换到包含应用程序。 当用户需要进行身份validation时,此Pinterest共享扩展如何执行此操作?

我正在研究最新的iOS SDK 10.2

由于我没有收到任何反馈,我想出了如何做到这一点。 这是答案。

要控制从UIViewController生命周期使用loadView方法的视图加载。 当应用程序首先需要从UIViewController获取view属性时会触发此方法。 所以这是懒加载。 当用户从UIViewController api调用loadViewIfNeeded()时,也会触发此方法。 在这个方法的主体中你需要非常小心,不要读取view属性,因为这将再次调用loadView ,你将有递归循环。

我对此方法的实现如下。 我需要告诉用户是否已登录或不包含应用程序,并根据此选择要加载的视图。

 override func loadView() { // check in shared Keychain if user is authenticated self.userAuthenticated = userService.isAuthenticated() if self.userAuthenticated { // load default view of the ShareViewController super.loadView() } else { // if user is not logged in show only alert view controller with transparent dummy view let view = UIView() self.view = view } } 

如果用户没有登录,我会显示警报

 override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) let context = self.extensionContext! if !self.userAuthenticated { let alert = UIAlertController(title: "Error", message: "User not logged in", preferredStyle: .alert) let cancel = UIAlertAction(title: "Cancel", style: .cancel) { _ in context.completeRequest(returningItems: nil, completionHandler: nil) } let login = UIAlertAction(title: "Log In", style: .default, handler: { _ in let url = URL(string: "fashionapp://login")! // This is utility method written in Objective-C. // I don't know yet if it passes Apple Review process or not. // We will see ;) self.open(url, options: [:], completionHandler: nil) context.completeRequest(returningItems: nil, completionHandler: nil) }) alert.addAction(cancel) alert.addAction(login) present(alert, animated: true, completion: nil) } } 

以下是从共享扩展中打开包含应用程序的方法。 我希望它会有用,Apple会毫无问题地对此进行审核。 它是用Objective-C编写的,因为在Swift中没有NSInvocation类,所以你只能执行最多两个参数的选择器。

 #import  @interface UIViewController (OpenURL) - (void)openURL:(nonnull NSURL *)url options:(nonnull NSDictionary *)options completionHandler:(void (^ __nullable)(BOOL success))completion; @end 

并实施。

 #import "UIViewController+OpenURL.h" @implementation UIViewController (OpenURL) - (void)openURL:(nonnull NSURL *)url options:(nonnull NSDictionary *)options completionHandler:(void (^ __nullable)(BOOL success))completion { SEL selector = NSSelectorFromString(@"openURL:options:completionHandler:"); UIResponder* responder = self; while ((responder = [responder nextResponder]) != nil) { if([responder respondsToSelector:selector] == true) { NSMethodSignature *methodSignature = [responder methodSignatureForSelector:selector]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; [invocation setTarget: responder]; [invocation setSelector: selector]; [invocation setArgument: &url atIndex: 2]; [invocation setArgument: &options atIndex:3]; [invocation setArgument: &completion atIndex: 4]; [invocation invoke]; break; } } } @end