【问题标题】:iOS Share Extension flowiOS 共享扩展流程
【发布时间】:2017-03-17 13:12:45
【问题描述】:

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

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

我的问题与 UI 无关,而是在哪里放置此检查代码。我没有找到任何启​​动应用扩展的方法,因此我可以根据某些状态选择一些初始视图控制器进行扩展。

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

第二个问题:如何以编程方式从共享扩展切换到包含应用。当用户需要进行身份验证时,这个 Pinterest 分享扩展是如何做到这一点的?

我正在开发最新的 iOS SDK 10.2

【问题讨论】:

    标签: ios swift3 ios-extensions share-extension


    【解决方案1】:

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

    为了控制我使用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 <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
    

    【讨论】:

    • 你能解释一下如何使用这个代码吗?我坚持这个分享的东西,并没有在网上找到帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多