测试已测试 | ✗ |
语言语言 | SwiftSwift |
许可证 | MIT |
版本发布最新版本发布 | 2017年6月 |
SwiftSwift 版本 | 3.0 |
SPM支持 SPM | ✓ |
由 Chris Stephan 维护。
Initializable 是一组协议,它允许您在应用程序启动时初始化第三方框架和其他设置。它还允许您的框架与 applicationDidEnterForeground
绑定。
当构建新的应用程序时,您有多少次在 application:didFinishLaunchingWithOptions
中添加大量代码来初始化第三方框架或其他全局设置呢?这个框架旨在帮助减少 AppDelegate 中的噪音,并允许这些代码分离到各自负责的对象中。
您需要实现一些符合 Configurable 协议和 Initializable 协议的对象。
// Configuration.swift
class Configuration: NSObject, Configurable {
static let sharedConfiguration = Configuration()
var serviceStorage: [String : [Int : [String : String]]] = [:]
override init() {
serviceStorage = [
"FakeService" : [
ReleaseStage.development.rawValue : [
"ApiKey": "abc123"
]
]
]
}
static func defaultConfiguration() -> Configurable {
return sharedConfiguration
}
func currentStage() -> ReleaseStage {
return .development
}
// Notice we don't define `value(for:key:)` in Swift
// this is because of the default implementation provided by the
// extension to Configurable
}
// ThirdpartyInitializer.swift
import Initializable
class ThirdpartyInitializer: NSObject, Initializable {
func perform(with configuration: Configuration) {
let apiKey = configuration.value(for: "ThirdParty", key: "apiKey")
let _ = Thirdparty(apiKey: apiKey)
}
func shouldPerformWhenApplicationEntersForeground() -> Bool {
return false
}
}
然后进入您的应用程序代理,并将初始化器(们)连接到应用程序生命周期方法中。
// AppDelegate.swift
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
let initializers: [Initializable] = [
ThirdPartyInitializer(),
]
let configuration = Configuration.defaultConfiguration()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
for initializer in initializers {
initializer.perform(with: configuration)
}
return true
}
func applicationWillEnterForeground(application: UIApplication) {
for initializer in initializers {
if initializer.respondsToSelector(#selector(Initializable.shouldPerformWhenApplicationEntersForeground)) {
initializer.perform(with: configuration)
}
}
}
// ...
}
您需要实现一些符合 Configurable 协议和 Initializable 协议的对象。
// Configuration.h
#import <Foundation/Foundation.h>
@import Initializable;
@interface Configuration : NSObject <Configurable>
@property (nonatomic, copy) NSDictionary<NSString *, NSDictionary<NSNumber *, NSDictionary<NSString *, NSString *> *> *> *serviceStorage;
@end
// Configuration.m
#import "Configuration.h"
@implementation Configuration
+ (Configuration *)defaultConfiguration
{
static id instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
- (ReleaseStage)currentStage
{
return ReleaseStageDevelopment;
}
- (NSDictionary *)serviceStorage
{
if (!_serviceStorage) {
_serviceStorage = @{
@(ReleaseStageDevelopment) : @{
@"FakeService": @{
@"apiKey": @"abc123"
}
}
};
}
return _serviceStorage;
}
// Notice we define `valueFor:key:` in Objective-C
// this is because the default implementation provided by the extension
// to Configurable is not visible to Objective-C code.
- (NSString *)valueFor:(NSString *)service key:(NSString *)key
{
Configuration *configuration = [Configuration defaultConfiguration];
NSDictionary *serviceStorage = [configuration serviceStorage];
NSDictionary *stageStorage = serviceStorage[@([configuration currentStage])];
NSDictionary *serviceKeys;
if (stageStorage) {
if ((serviceKeys = stageStorage[service])) {
return serviceKeys[key];
}
}
return nil;
}
@end
// ThirdpartyInitializer.h
#import <Foundation/Foundation.h>
@import Initializable;
@interface ThirdpartyInitializer <Initializable>
@end
// ThirdpartyInitializer.m
#import "ThirdpartyInitializer.h"
@implementation ThirdpartyInitializer
// Notice we substitute id<Configurable> here for our custom class that
// implements the Configurable protocol in the method implementation
- (void)performWith:(Configuration *)configuration
{
NSString *apiKey = [configuration valueFor:@"Thirdparty" key:@"apiKey"];
[Thirdparty initWithApiKey:apiKey];
}
- (BOOL)shouldPerformWhenApplicationEntersForeground
{
return NO;
}
@end
然后进入您的应用程序代理,并将初始化器(们)连接到应用程序生命周期方法中。
// AppDelegate.m
#import "AppDelegate.h"
@import Initializable;
@interface AppDelegate ()
@property (nonatomic, strong) NSArray<id<Initializable>> *initializers;
@end
@implementation AppDelegate
- (void)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self.initializers makeObjectsPerformSelector:@selector(performWith:) withObject:[Configuration defaultConfiguration]];
return YES
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[self.initializers enumerateObjectsUsingBlock:^void(id<Initializable> initializer, NSUInteger index, BOOL *stop) {
if ([initializer respondsToSelector:@selector(shouldPerformWhenApplicationEntersForeground)] &&
[initializer shouldPerformWhenApplicationEntersForeground]) {
[initializer performWithConfiguration:[Configuration defaultConfiguration]];
}
}];
}
- (NSArray<id <Initializable>> *)initializers
{
if (!_initializers) {
_initializers = @[
[ThirdPartyInitializer new],
];
}
return _initializers;
}
@end