Поскольку я не получил отзывов по этому поводу, я понимаю, как это сделать. Вот и ответ.
Чтобы контролировать загрузку представления, я использовал loadView
метод из UIViewController
жизненного цикла. Этот метод запускается, когда приложению сначала нужно получить свойство view
от UIViewController
. Так что это ленивая загрузка. Этот метод также запускается, когда пользователь вызывает loadViewIfNeeded()
из UIViewController
api. В теле этого метода вам нужно быть очень осторожным, чтобы не прочитать свойство 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
person
Marcin Kapusta
schedule
12.04.2017