因为我没有收到任何反馈,所以我自己找到了如何做到这一点。以下是答案。
为了控制哪个视图加载,我使用了UIViewController生命周期中的loadView
方法。当应用程序首次需要从UIViewController
获取view
属性时,将触发此方法。因此,这是懒加载。当用户从UIViewController
api调用loadViewIfNeeded()
时,也会触发此方法。在此方法体内,您需要非常小心,不要读取view
属性,因为这将再次触发loadView
,并且您将陷入递归循环。
我的实现方法如下。我需要告诉包含应用程序的用户是否已登录,基于此选择要加载的视图。
override func loadView() {
self.userAuthenticated = userService.isAuthenticated()
if self.userAuthenticated {
super.loadView()
} else {
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")!
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