AppDelegate組件化
AppDelegate瘦身
- AppDelegate是App的入口,對(duì)于開(kāi)發(fā)耦合性來(lái)說(shuō)憔维,AppDelegate除了負(fù)責(zé)應(yīng)用生命周期之外淹辞,盡量不要有大量的代碼地沮。
- 但是在iOS 實(shí)際開(kāi)發(fā)過(guò)程中攀例,很多人習(xí)慣將全局變量定義在 AppDelegate 中,會(huì)導(dǎo)入比如推送皿曲、統(tǒng)計(jì)唱逢、分享、三方登陸屋休、地圖等組件坞古,但如此這般,AppDelegate就變得更加臃腫劫樟。在大型項(xiàng)目中痪枫,想要解除耦合和模塊化時(shí),都不利于AppDelegate的維護(hù)叠艳。
- 將很多全局變量放在AppDelegate上奶陈,將AppDelegate作為一個(gè)依賴(lài)中心點(diǎn),雖然很多模塊可以訪問(wèn)全局變量附较,但會(huì)產(chǎn)生相互依賴(lài)吃粒,不利于模塊化開(kāi)發(fā);
- 不同的模塊拒课,會(huì)根據(jù)需要在AppDelegate的不同生命周期方法中徐勃,調(diào)用各種方法。比如在程序啟動(dòng)時(shí)在application:didFinishLaunchingWithOptions:內(nèi)注冊(cè)一個(gè)初始化方法早像;
組件化分開(kāi)引入
創(chuàng)建繼承NSObject的AppModuleManager單利類(lèi)
AppModuleManager.h文件
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@import UIKit;
@import UserNotifications;
@protocol AppModuleManagerDelegate <UIApplicationDelegate, UNUserNotificationCenterDelegate>
@end
@interface AppModuleManager : NSObject<UIApplicationDelegate, UNUserNotificationCenterDelegate>
+ (instancetype)sharedInstance;
- (void)loadModulesWithPlistFile:(NSString *)plistFile;
- (NSArray<id<AppModuleManagerDelegate>> *)allModules;
@end
NS_ASSUME_NONNULL_END
AppModuleManager.m文件
#import "AppModuleManager.h"
@interface AppModuleManager ()
@property (nonatomic, strong) NSMutableArray<id<AppModuleManagerDelegate>> *modules;
@end
@implementation AppModuleManager
+ (instancetype)sharedInstance
{
static AppModuleManager *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[[self class] alloc] init];
});
return instance;
}
- (NSMutableArray<id<AppModuleManagerDelegate>> *)modules
{
if (!_modules) {
_modules = [NSMutableArray array];
}
return _modules;
}
- (void)addModule:(id<AppModuleManagerDelegate>) module
{
if (![self.modules containsObject:module]) {
[self.modules addObject:module];
}
}
- (void)loadModulesWithPlistFile:(NSString *)plistFile
{
NSArray<NSString *> *moduleNames = [NSArray arrayWithContentsOfFile:plistFile];
for (NSString *moduleName in moduleNames) {
id<AppModuleManagerDelegate> module = [[NSClassFromString(moduleName) alloc] init];
[self addModule:module];
}
}
- (NSArray<id<AppModuleManagerDelegate>> *)allModules
{
return self.modules;
}
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module applicationDidFinishLaunching:application];
}
}
}
#pragma mark - State Transitions / Launch time:
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module application:application willFinishLaunchingWithOptions:launchOptions];
}
}
return YES;
}
#pragma mark - 程序第一次加載完畢僻肖,就會(huì)調(diào)用此方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module application:application didFinishLaunchingWithOptions:launchOptions];
}
}
return YES;
}
#pragma mark - 程序?qū)⒁ソ裹c(diǎn) - 不能交互
- (void)applicationWillResignActive:(UIApplication *)application
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module applicationWillResignActive:application];
}
}
}
#pragma mark - 程序已經(jīng)進(jìn)入后臺(tái),通常我們會(huì)在這個(gè)時(shí)候保存數(shù)據(jù)
- (void)applicationDidEnterBackground:(UIApplication *)application
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module applicationDidEnterBackground:application];
}
}
}
#pragma mark - 程序?qū)⒁M(jìn)入前臺(tái)卢鹦,通常我們會(huì)在這個(gè)時(shí)候恢復(fù)數(shù)據(jù)
- (void)applicationWillEnterForeground:(UIApplication *)application
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module applicationWillEnterForeground:application];
}
}
}
#pragma mark - 程序已經(jīng)獲取焦點(diǎn) - 可以交互
- (void)applicationDidBecomeActive:(UIApplication *)application
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module applicationDidBecomeActive:application];
}
}
}
#pragma mark - 程序掛了臀脏,將要完全退出。
- (void)applicationWillTerminate:(UIApplication *)application
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module applicationWillTerminate:application];
}
}
}
#pragma mark - 程序接收到內(nèi)存警告
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module applicationDidReceiveMemoryWarning:application];
}
}
}
#pragma mark - 程序接收到url處理
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
for (id<AppModuleManagerDelegate> module in self.modules) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
if ([module respondsToSelector:_cmd]) {
return [module application:application handleOpenURL:url];
}
#pragma clang diagnostic pop
}
return YES;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation
{
for (id<AppModuleManagerDelegate> module in self.modules) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
if ([module respondsToSelector:_cmd]) {
return [module application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
}
#pragma clang diagnostic pop
}
return YES;
}
#pragma clang diagnostic pop
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options API_AVAILABLE(ios(9.0))
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
return [module application:app openURL:url options:options];
}
}
return YES;
}
#pragma mark - Handling Remote Notification
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
}
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module application:application didFailToRegisterForRemoteNotificationsWithError:error];
}
}
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
}
}
#pragma mark - Handling Local Notification
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module application:application didReceiveRemoteNotification:userInfo];
}
}
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)(void))completionHandler
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module application:application handleActionWithIdentifier:identifier forRemoteNotification:userInfo completionHandler:completionHandler];
}
}
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)(void))completionHandler
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module application:application handleActionWithIdentifier:identifier forRemoteNotification:userInfo withResponseInfo:responseInfo completionHandler:completionHandler];
}
}
}
#pragma mark - Handling Local Notification
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
API_AVAILABLE(ios(10.0)){
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module userNotificationCenter:center willPresentNotification:notification withCompletionHandler:completionHandler];
}
}
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler
API_AVAILABLE(ios(10.0)){
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
}
}
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module application:application didReceiveLocalNotification:notification];
}
}
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)(void))completionHandler
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module application:application handleActionWithIdentifier:identifier forLocalNotification:notification completionHandler:completionHandler];
}
}
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)(void))completionHandler
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module application:application handleActionWithIdentifier:identifier forLocalNotification:notification withResponseInfo:responseInfo completionHandler:completionHandler];
}
}
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module application:application didRegisterUserNotificationSettings:notificationSettings];
}
}
}
#pragma mark - Handling Continuing User Activity and Handling Quick Actions
- (BOOL)application:(UIApplication *)application willContinueUserActivityWithType:(NSString *)userActivityType
{
BOOL result = NO;
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
result = result || [module application:application willContinueUserActivityWithType:userActivityType];
}
}
return result;
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
BOOL result = NO;
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
result = result || [module application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
}
}
return result;
}
- (void)application:(UIApplication *)application didUpdateUserActivity:(NSUserActivity *)userActivity
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module application:application didUpdateUserActivity:userActivity];
}
}
}
- (void)application:(UIApplication *)application didFailToContinueUserActivityWithType:(NSString *)userActivityType error:(NSError *)error
{
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module application:application didFailToContinueUserActivityWithType:userActivityType error:error];
}
}
}
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL succeeded))completionHandler
API_AVAILABLE(ios(9.0)){
for (id<AppModuleManagerDelegate> module in self.modules) {
if ([module respondsToSelector:_cmd]) {
[module application:application performActionForShortcutItem:shortcutItem completionHandler:completionHandler];
}
}
}
@end
// AppModulesRegister.plist
截屏2021-04-18 下午11.48.23.png
AppDelegate.m中實(shí)現(xiàn)
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"AppModulesRegister" ofType:@"plist"];
AppModuleManager *manager = [AppModuleManager sharedInstance];
[manager loadModulesWithPlistFile:plistPath];
[manager application:application willFinishLaunchingWithOptions:launchOptions];
return YES;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[UIApplication sharedApplication].statusBarHidden = NO;
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
[[AppModuleManager sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
return YES;
}
在需要的方法實(shí)現(xiàn)
AppModulePush.h文件
#import <Foundation/Foundation.h>
#import "AppModuleManager.h"
NS_ASSUME_NONNULL_BEGIN
@interface AppModulePush : NSObject<AppModuleManagerDelegate>
@end
NS_ASSUME_NONNULL_END
AppModulePush.m文件
#pragma mark - 程序?qū)⒁ソ裹c(diǎn) - 不能交互
- (void)applicationWillResignActive:(UIApplication*)application
{
[[AppModuleManager sharedInstance] applicationWillResignActive:application];
}
#pragma mark - 程序已經(jīng)進(jìn)入后臺(tái)冀自,通常我們會(huì)在這個(gè)時(shí)候保存數(shù)據(jù)
- (void)applicationDidEnterBackground:(UIApplication*)application
{
[[AppModuleManager sharedInstance] applicationDidEnterBackground:application];
}
#pragma mark - 程序?qū)⒁M(jìn)入前臺(tái)揉稚,通常我們會(huì)在這個(gè)時(shí)候恢復(fù)數(shù)據(jù)
- (void)applicationWillEnterForeground:(UIApplication*)application
{
[[AppModuleManager sharedInstance] applicationWillEnterForeground:application];
}
#pragma mark - 程序已經(jīng)獲取焦點(diǎn) - 可以交互
- (void)applicationDidBecomeActive:(UIApplication*)application
{
[[AppModuleManager sharedInstance] applicationDidBecomeActive:application];
}
#pragma mark - 程序掛了,將要完全退出凡纳。
- (void)applicationWillTerminate:(UIApplication*)application
{
[[AppModuleManager sharedInstance] applicationWillTerminate:application];
}
#pragma mark - 程序接收到內(nèi)存警告
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
[[AppModuleManager sharedInstance] applicationDidReceiveMemoryWarning:application];
}