iOS共享扩展流程

5
我遇到了创建共享扩展的问题,就像Pinterest应用程序的共享扩展一样。当用户没有登录到包含应用程序时,共享扩展只会显示一个带有“登录”和“取消”选项的警报。
在代码中,我需要决定在我的共享扩展中显示哪个视图控制器。我认为我需要从共享容器中检查授权状态,如果状态为“未登录”,则需要显示警报控制器。如果状态为“已登录”,则需要显示我的主视图控制器“ShareViewController”,它是“SLComposeServiceViewController”的子类。
我的问题不是与UI相关的,而是在哪里放置此检查代码。我没有找到任何方法可以启动应用程序扩展,以便我可以选择一些初始视图控制器,以基于某些状态扩展。
在Pinterest扩展中,当用户从包含应用程序注销时,我看不到他们的主视图控制器,只看到带有选项的警报。
第二个问题:如何在程序中从共享扩展切换到包含应用程序。当用户需要进行身份验证时,Pinterest共享扩展是如何实现这一点的?
我正在使用最新的iOS SDK 10.2。
1个回答

6

因为我没有收到任何反馈,所以我自己找到了如何做到这一点。以下是答案。

为了控制哪个视图加载,我使用了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)
    }
}

这里是从分享扩展打开包含应用程序的方法。我希望它会有用,并且苹果公司不会出现任何问题。代码使用 Objective-C 编写,因为在 Swift 中没有 NSInvocation 类,所以只能执行最多具有两个参数的选择器。

#import <UIKit/UIKit.h>

@interface UIViewController (OpenURL)

- (void)openURL:(nonnull NSURL *)url
        options:(nonnull NSDictionary<NSString *, id> *)options
completionHandler:(void (^ __nullable)(BOOL success))completion;

@end

实现。

#import "UIViewController+OpenURL.h"

@implementation UIViewController (OpenURL)


- (void)openURL:(nonnull NSURL *)url
        options:(nonnull NSDictionary<NSString *, id> *)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

请问您能否解释一下如何使用这段代码?我卡在了共享部分,网络上也没有找到任何帮助。 - Sagar Panwala

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接