模塊化
涉及到的類
- 底層:UPCore
- 模塊管理:moduleManager
- 協(xié)議:UPModuleProtocol
- 項(xiàng)目入口:APPDelegate
- 具體模塊:UPPush
邏輯關(guān)系
(+ load 作為 Objective-C 中的一個(gè)方法,與其它方法有很大的不同。它只是一個(gè)在整個(gè)文件被加載到運(yùn)行時(shí),在 main 函數(shù)調(diào)用之前被 ObjC 運(yùn)行時(shí)調(diào)用的鉤子方法)
- 模塊向UPCore注冊(cè)
UPPushModule.h
+ (void)load
{
[UPCore registerModuleClass:[self class]];
}
2.在UPCore中初始化并調(diào)用UPModuleManager
+ (void)registerModuleClass:(Class)moduleClass
{
[[UPModuleManager sharedInstance] registerModuleClass:moduleClass];
}
3.初始化單例UPModuleManager,初始化字典
+ (instancetype)sharedInstance
{
static dispatch_once_t predicate;
static id UPModuleManagerInstance = nil;
dispatch_once(&predicate, ^{
UPModuleManagerInstance = [[self alloc] init];
});
return UPModuleManagerInstance;
}
- (instancetype)init
{
if (self = [super init]) {
_modules = [NSMutableArray array];
_moduleEventSelectorInfoDictionary = @{ @(UPMSetupEvent) : kUPModuleSetupSelector,
@(UPMInitEvent) : kUPModuleInitSelector,
@(UPMTearDownEvent) : kUPModuleTearDownSelector,
@(UPMWillResignActiveEvent) : kUPModuleWillResignActiveSelector,
@(UPMDidEnterBackgroundEvent) : kUPModuleDidEnterBackgroundSelector,
@(UPMWillEnterForegroundEvent) : kUPModuleWillEnterForegroundSelector,
@(UPMDidBecomeActiveEvent) : kUPModuleDidBecomeActiveSelector,
@(UPMWillTerminateEvent) : kUPModuleWillTerminateSelector,
@(UPMDidReceiveMemoryWarningEvent) : kUPModuleDidReceiveMemoryWarningSelector,
@(UPMDidFailToRegisterForRemoteNotificationsEvent) : kUPModuleDidFailToRegisterForRemoteNotificationsSelector,
@(UPMDidRegisterForRemoteNotificationsEvent) : kUPModuleDidRegisterForRemoteNotificationsSelector,
@(UPMDidReceiveRemoteNotificationEvent) : kUPModuleDidReceiveRemoteNotificationSelector,
@(UPMDidReceiveLocalNotificationEvent) : kUPModuleDidReceiveLocalNotificationSelector,
@(UPMDidRegisterUserNotificationSettings) : kUPMDidRegisterUserNotificationSettingsSelector };
}
return self;
}
- (void)registerModuleClass:(Class)moduleClass
{
if (moduleClass == nil) {
UPLogError(@"CoreHive", @"%s[%d]模塊注冊(cè)失敗!該模塊類為nil!", __PRETTY_FUNCTION__, __LINE__);
return;
}
if (![moduleClass conformsToProtocol:@protocol(UPModuleProtocol)]) {
UPLogError(@"CoreHive", @"%s[%d]模塊注冊(cè)失??!該模塊類未實(shí)現(xiàn)UPModuleProtocol協(xié)議!", __PRETTY_FUNCTION__, __LINE__);
return;
}
NSString *moduleClassName = NSStringFromClass(moduleClass);
if (![moduleClassName isKindOfClass:[NSString class]] || moduleClassName.length == 0) {
UPLogError(@"CoreHive", @"%s[%d]模塊注冊(cè)失?。≡撃K類為空!", __PRETTY_FUNCTION__, __LINE__);
return;
}
if ([self.modules containsObject:moduleClassName]) {
UPLogWarning(@"CoreHive", @"%s[%d]該模塊類(%@)已注冊(cè)過!", __PRETTY_FUNCTION__, __LINE__, moduleClassName);
return;
}
[self.modules addObject:moduleClassName];
}
4.使用const聲明的selector對(duì)應(yīng)value,使用枚舉聲明key
UPModuleManager.m
NSString *kUPModuleClassName = @"moduleClass";
NSString *const kUPModuleSetupSelector = @"moduleSetup:";
NSString *const kUPModuleInitSelector = @"moduleInit:";
NSString *const kUPModuleTearDownSelector = @"moduleTearDown:";
NSString *const kUPModuleWillResignActiveSelector = @"moduleWillResignActive:";
NSString *const kUPModuleDidEnterBackgroundSelector = @"moduleDidEnterBackground:";
NSString *const kUPModuleWillEnterForegroundSelector = @"moduleWillEnterForeground:";
NSString *const kUPModuleDidBecomeActiveSelector = @"moduleDidBecomeActive:";
NSString *const kUPModuleWillTerminateSelector = @"moduleWillTerminate:";
NSString *const kUPModuleDidReceiveMemoryWarningSelector = @"moduleDidReceiveMemoryWarning:";
NSString *const kUPModuleDidFailToRegisterForRemoteNotificationsSelector = @"moduleDidFailToRegisterForRemoteNotifications:";
NSString *const kUPModuleDidRegisterForRemoteNotificationsSelector = @"moduleDidRegisterForRemoteNotifications:";
NSString *const kUPModuleDidReceiveRemoteNotificationSelector = @"moduleDidReceiveRemoteNotification:";
NSString *const kUPModuleDidReceiveLocalNotificationSelector = @"moduleDidReceiveLocalNotification:";
NSString *const kUPMDidRegisterUserNotificationSettingsSelector = @"moduleDidRegisterUserNotificationSettings:";
UPModuleManager.h
/* 模塊事件枚舉值 */
typedef NS_ENUM(NSInteger, UPModuleEventType) {
UPMSetupEvent = 0,
UPMInitEvent,
UPMTearDownEvent,
UPMWillResignActiveEvent,
UPMDidEnterBackgroundEvent,
UPMWillEnterForegroundEvent,
UPMDidBecomeActiveEvent,
UPMWillTerminateEvent,
UPMDidReceiveMemoryWarningEvent,
UPMDidFailToRegisterForRemoteNotificationsEvent,
UPMDidRegisterForRemoteNotificationsEvent,
UPMDidReceiveRemoteNotificationEvent,
UPMDidReceiveLocalNotificationEvent,
UPMDidRegisterUserNotificationSettings
};
5.進(jìn)入main函數(shù),進(jìn)入U(xiǎn)PAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
[[UPModuleManager sharedInstance] handleModuleEvent:UPMSetupEvent];
[[UPModuleManager sharedInstance] handleModuleEvent:UPMInitEvent];
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
#endif
return YES;
}
6.進(jìn)入處理方法
- (void)handleModuleEvent:(UPModuleEventType)eventType
{
NSString *selectorName = _moduleEventSelectorInfoDictionary[@(eventType)];
if (![selectorName isKindOfClass:[NSString class]]) {
return;
}
SEL selector = NSSelectorFromString(selectorName);
if (!selector) {
return;
}
[self.modules enumerateObjectsUsingBlock:^(id<UPModuleProtocol> moduleInstance, NSUInteger idx, BOOL *_Nonnull stop) {
if ([moduleInstance respondsToSelector:selector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[moduleInstance performSelector:selector
withObject:[UPContext sharedInstance]];
#pragma clang diagnostic pop
}
}];
}
7.補(bǔ)充協(xié)議內(nèi)容
#import <Foundation/Foundation.h>
@class UPContext;
/**
* 模塊協(xié)議聲明接口。該接口聲明了做為一個(gè)模塊,都需要時(shí)間的方法。
*/
@protocol UPModuleProtocol <NSObject>
@optional
/**
* @brief 模塊Setup方法。
* @param context 包含CoreHive環(huán)境信息的對(duì)象.
* @discussion 模塊可以在該方法中去進(jìn)一步注冊(cè)其對(duì)外提供的服務(wù)。
*/
- (void)moduleSetup:(UPContext *)context;
/**
* @brief 模塊初始化方法。
* @param context 包含CoreHive環(huán)境信息的對(duì)象.
*/
- (void)moduleInit:(UPContext *)context;
/**
* @brief 模塊銷毀方法。
* @param context 包含CoreHive環(huán)境信息的對(duì)象.
*/
- (void)moduleTearDown:(UPContext *)context;
/**
* @brief 當(dāng)App處于非活躍狀態(tài)時(shí),CoreHive通過該方法通知給模塊。
* @param context 包含CoreHive環(huán)境信息的對(duì)象.
*/
- (void)moduleWillResignActive:(UPContext *)context;
/**
* @brief 當(dāng)App已經(jīng)進(jìn)入后臺(tái)時(shí),CoreHive通過該方法通知給模塊。
* @param context 包含CoreHive環(huán)境信息的對(duì)象.
*/
- (void)moduleDidEnterBackground:(UPContext *)context;
/**
* @brief 當(dāng)App將要進(jìn)入后臺(tái)時(shí),CoreHive通過該方法通知給模塊。
* @param context 包含CoreHive環(huán)境信息的對(duì)象.
*/
- (void)moduleWillEnterForeground:(UPContext *)context;
/**
* @brief 當(dāng)App處于活躍狀態(tài)時(shí),CoreHive通過該方法通知給模塊。
* @param context 包含CoreHive環(huán)境信息的對(duì)象.
*/
- (void)moduleDidBecomeActive:(UPContext *)context;
/**
* @brief 當(dāng)App將要退出時(shí),CoreHive通過該方法通知給模塊。
* @param context 包含CoreHive環(huán)境信息的對(duì)象.
*/
- (void)moduleWillTerminate:(UPContext *)context;
/**
* @brief 當(dāng)App收到內(nèi)存告警時(shí),CoreHive通過該方法通知給模塊。
* @param context 包含CoreHive環(huán)境信息的對(duì)象.
*/
- (void)moduleDidReceiveMemoryWarning:(UPContext *)context;
/**
* @brief 當(dāng)App遠(yuǎn)程推送通知注冊(cè)失敗時(shí),CoreHive通過該方法通知給模塊。
* @param context 包含CoreHive環(huán)境信息的對(duì)象.
*/
- (void)moduleDidFailToRegisterForRemoteNotifications:(UPContext *)context;
/**
* @brief 當(dāng)App遠(yuǎn)程推送通知注冊(cè)成功時(shí),CoreHive通過該方法通知給模塊。
* @param context 包含CoreHive環(huán)境信息的對(duì)象.
*/
- (void)moduleDidRegisterForRemoteNotifications:(UPContext *)context;
/**
* @brief 當(dāng)App收到遠(yuǎn)程推送通知時(shí),CoreHive通過該方法通知給模塊。
* @param context 包含CoreHive環(huán)境信息的對(duì)象.
*/
- (void)moduleDidReceiveRemoteNotification:(UPContext *)context;
/**
* @brief 當(dāng)App收到本地通知時(shí),CoreHive通過該方法通知給模塊。
* @param context 包含CoreHive環(huán)境信息的對(duì)象.
*/
- (void)moduleDidReceiveLocalNotification:(UPContext *)context;
/**
* @brief 當(dāng)App收到application:didRegisterUserNotificationSettings:代理方法時(shí),CoreHive會(huì)通過該方法通知給模塊。
* @param context 包含CoreHive環(huán)境信息的對(duì)象.
*/
- (void)moduleDidRegisterUserNotificationSettings:(UPContext *)context __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_8_0);
@end
這樣,所有的模塊都在UPAppDelegate中調(diào)度,以UPModuleProtocol為核心,所有遵循此協(xié)議的模塊都可以操作。搭建了項(xiàng)目的根本,包括推送日志登錄等功能,不包括設(shè)備綁定等具體業(yè)務(wù)邏輯。