iOS元件化(六)-AppDelegate優化
AppDelegate隨著我們開發的深入,裡面會產生很多的初始化、生命週期處理、推送、通知等方法,這些程式碼對我們元件化各個獨立工程的開發環境搭建有很大的影響,例如:我們單獨的業務線可能不需要對生命週期有處理,但是獨立開發環境的AppDelegate如果定製化過大,後續可能會產生問題,所以需要一種統一的方式,減少各工程AppDelegate的差異。
一、分模組載入AppDelegate方法
基於上述考慮,我們可以採用一種分模組載入的方式載入所有AppDelegate方法,該方式會依次載入各個模組,當主AppDelegate某個方法被呼叫時,會依次呼叫各個模組的方法,這樣各個模組都存在一套自己的AppDelegate方法,互不干擾,而我們主AppDelegate裡面只需要存在相應的呼叫程式碼,其餘的程式碼都可以分散在各個工程,從而保持一份穩定且乾淨的AppDelegate。
1、 FRDModuleManager
FRDModuleManager是豆瓣開源的輕量級模組管理工具,它通過減小 AppDelegate 的程式碼量來把很多職責拆分至各個模組中去,這樣 AppDelegate 會變得容易維護。其主要類 FRDModuleManager 只有 300 多行程式碼,使用方式也很簡單。
GitHub地址:https://github.com/lincode/FRDModuleManager
- FRDModuleManager僅有三個方法
+ (instancetype)sharedInstance;
- (void)loadModulesWithPlistFile: (NSString *)plistFile;
- (NSArray<id<YRDModule>> *)allModules;
- FRDModuleManager通過讀取plist陣列存放的module名稱完成初始化,將module全部載入起來:
let plistPath = Bundle.main.path(forResource: "ModulesRegister", ofType: "plist");
let manager = YRDModuleManager.sharedInstance();
manager?.loadModules(withPlistFile: plistPath);
- 在主AppDelegate中分別新增呼叫方法,這裡使用了自己維護的module管理器:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
YRDModuleManager.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions);
return true
}
func applicationWillResignActive(_ application: UIApplication) {
YRDModuleManager.sharedInstance().applicationWillResignActive(application);
}
func applicationDidEnterBackground(_ application: UIApplication) {
YRDModuleManager.sharedInstance().applicationDidEnterBackground(application);
}
- 在各個模組的生命週期類中,新增鉤子函式
//需要遵守的協議
<UIApplicationDelegate, UNUserNotificationCenterDelegate>
各自的模組中鉤子函式:
@implementation YRDPlatformModule
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSLog(@"%@ Timeline", NSStringFromSelector(_cmd));
return YES;
}
2、JSDecoupledAppDelegate
JSDecoupledAppDelegate 是由 JSBadgeView 的作者開發的一款輕量級的 AppDelegate 解耦工具。它將 AppDelegate 各個功能點獨立出來,並通過代理的方式將控制權下發。
- 將 main.m 中的 AppDelegate 替換成JSDecoupledAppDelegate:
return UIApplicationMain(argc, argv, nil, NSStringFromClass([JSDecoupledAppDelegate class]));
- 指定你需要處理的各個 JSDecoupledAppDelegate 的子 delegate。例如,你需要實現didFinishLaunchingWithOptions 方法,則新建一個類,在其中新增
+ (void)load
{
[JSDecoupledAppDelegate sharedAppDelegate].appStateDelegate = [[self alloc] init];
}
然後就可以在裡面實現我們以前在 didFinishLaunchingWithOptions 的方法。
這兩種方法各有優缺點,相對來說,我推薦使用第一種方法,實現各模組的AppDelegate拆分。
二、FRDModuleManager獨立工程如何接入
1、需要的檔案
一般情況下,我們直接copy主工程的AppDelegate即可,因為已經優化完成,不存在多餘程式碼。另外需要建立自己的module,用來實現鉤子函式,例如:
@interface YRDPlatformModule()
@end
@implementation YRDPlatformModule
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
return YES;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//自己的初始化等方法
return YES;
}
而上訴的YRDPlatformModule
就是在plist裡面需要新增的module名稱,這時候,我們就可以一股腦的將自己業務線原本放在AppDelegate的東西放在自己的module裡面了。
三、資原始檔優化
到這裡,我們的工程級別元件化已經基本完車了,但是我們後續基於該工程還有很多的優化項,我們可以不斷的拆分細化元件,優化資原始檔copy方式,優化編譯速度等。
我們下一次將進行資原始檔的優化。