Sfoglia il codice sorgente

Finish Module life cycle

xcbosa mbp16 2 anni fa
parent
commit
4eb7740770

+ 23 - 0
XCComponentization/Classes/Componentization/XCMContext.h

@@ -0,0 +1,23 @@
+//
+//  XCMContext.h
+//  Pods-ComponentizationDemo
+//
+//  Created by 邢铖 on 2023/7/8.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface XCMContext : NSObject
+
+@property (nonatomic, strong) UIApplication *application;
+@property (nonatomic, strong) NSDictionary<NSString *, NSObject *> *launchOptions;
+@property (nonatomic, strong) UIWindow *mainWindow;
+@property (nonatomic, strong) UIViewController *mainViewController;
+
+@property (nonatomic, strong) NSDictionary<NSString *, NSObject *> *customParam;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 12 - 0
XCComponentization/Classes/Componentization/XCMContext.m

@@ -0,0 +1,12 @@
+//
+//  XCMContext.m
+//  Pods-ComponentizationDemo
+//
+//  Created by 邢铖 on 2023/7/8.
+//
+
+#import "XCMContext.h"
+
+@implementation XCMContext
+
+@end

+ 28 - 0
XCComponentization/Classes/Componentization/XCMEngine.h

@@ -0,0 +1,28 @@
+//
+//  XCMEngine.h
+//  XCComponentization
+//
+//  Created by 邢铖 on 2023/7/8.
+//
+
+#import <Foundation/Foundation.h>
+#import "XCMContext.h"
+#import "XCModuleProtocol.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface XCMEngine : NSObject
+
+@property (nonatomic, readonly, class) XCMEngine *sharedEngine;
+
+@property (nonatomic, strong) XCMContext *context;
+
+- (void)registerModule:(Class)moduleClass;
+- (void)registerModule:(Class)moduleClass shouldInit:(BOOL)shouldInit;
+- (void)unregisterModule:(Class)moduleClass;
+
+- (void)forEachModules:(BOOL(^)(id<XCModuleProtocol>))forEachModuleBlock;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 100 - 0
XCComponentization/Classes/Componentization/XCMEngine.m

@@ -0,0 +1,100 @@
+//
+//  XCMEngine.m
+//  XCComponentization
+//
+//  Created by 邢铖 on 2023/7/8.
+//
+
+#import "XCMEngine.h"
+#import <objc/runtime.h>
+
+@interface XCMRuntimeModuleInfo : NSObject
+
+@property (nonatomic, assign) NSInteger priority;
+@property (nonatomic, copy) NSString *className;
+@property (nonatomic, strong) id<XCModuleProtocol> classInstance;
+
+@end
+
+@implementation XCMRuntimeModuleInfo
+
+@end
+
+@interface XCMEngine ()
+
+@property (nonatomic, strong) NSMutableDictionary<NSString *, XCMRuntimeModuleInfo *> *modules;
+@property (nonatomic, strong) NSMutableArray<XCMRuntimeModuleInfo *> *sortedModules;
+
+@end
+
+@implementation XCMEngine
+
+- (instancetype)init {
+    self = [super init];
+    if (self) {
+        self.modules = [NSMutableDictionary new];
+        self.sortedModules = [NSMutableArray new];
+    }
+    return self;
+}
+
++ (XCMEngine *)sharedEngine {
+    static XCMEngine *engineInstance;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        engineInstance = [XCMEngine new];
+    });
+    return engineInstance;
+}
+
+- (void)registerModule:(Class)moduleClass {
+    [self registerModule:moduleClass shouldInit:false];
+}
+
+- (void)registerModule:(Class)moduleClass shouldInit:(BOOL)shouldInit {
+    NSString *className = NSStringFromClass(moduleClass);
+    if (self.modules[className]) {
+        @throw [NSException exceptionWithName:NSInvalidArgumentException
+                                       reason:[NSString stringWithFormat:@"Module %@: already registered", className]
+                                     userInfo:nil];
+    }
+    id<XCModuleProtocol> instance = class_createInstance(moduleClass, 0);
+    XCMRuntimeModuleInfo *moduleInfo = [XCMRuntimeModuleInfo new];
+    moduleInfo = [moduleInfo init];
+    moduleInfo.className = className;
+    moduleInfo.classInstance = instance;
+    moduleInfo.priority = instance.modulePriority;
+    self.modules[className] = moduleInfo;
+    [self.sortedModules addObject:moduleInfo];
+    [self.sortedModules sortUsingComparator:^(XCMRuntimeModuleInfo *left, XCMRuntimeModuleInfo *right) {
+        return left.priority - right.priority;
+    }];
+    [instance moduleRegister:self.context];
+    if (shouldInit) {
+        [instance moduleInit:self.context];
+    }
+}
+
+- (void)unregisterModule:(Class)moduleClass {
+    NSString *className = NSStringFromClass(moduleClass);
+    XCMRuntimeModuleInfo *moduleInfo = self.modules[className];
+    if (!moduleInfo) {
+        @throw [NSException exceptionWithName:NSInvalidArgumentException
+                                       reason:[NSString stringWithFormat:@"Module %@: not registered", className]
+                                     userInfo:nil];
+    }
+    id<XCModuleProtocol> instance = moduleInfo.classInstance;
+    [instance moduleTearDown:self.context];
+    self.modules[className] = nil;
+    [self.sortedModules removeObject:moduleInfo];
+}
+
+- (void)forEachModules:(BOOL (^)(id<XCModuleProtocol> _Nonnull))forEachModuleBlock {
+    for (XCMRuntimeModuleInfo *moduleInfo in self.sortedModules) {
+        if (!forEachModuleBlock(moduleInfo.classInstance)) {
+            return;
+        }
+    }
+}
+
+@end

+ 29 - 0
XCComponentization/Classes/Componentization/XCModuleProtocol.h

@@ -0,0 +1,29 @@
+//
+//  XCModuleProtocol.h
+//  XCComponentization
+//
+//  Created by 邢铖 on 2023/7/8.
+//
+
+#import <Foundation/Foundation.h>
+#import <UserNotifications/UserNotifications.h>
+#import "XCMContext.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol XCModuleProtocol <NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate>
+
+@required
+- (NSInteger)modulePriority;
+
+@optional
+- (void)moduleRegister:(XCMContext *)context;
+- (void)moduleInit:(XCMContext *)context;
+- (void)moduleTearDown:(XCMContext *)context;
+
+- (void)allModuleSetDown:(XCMContext *)context;
+- (void)windowDisplay:(XCMContext *)context;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 0 - 0
XCComponentization/Classes/ReplaceMe.m


+ 25 - 0
XCComponentization/Classes/XCMKit.h

@@ -0,0 +1,25 @@
+//
+//  XCMKit.h
+//  XCComponentization
+//
+//  Created by 邢铖 on 2023/7/8.
+//
+
+#import <Foundation/Foundation.h>
+#import "XCMContext.h"
+
+#define ModuleDefine(Module) \
+__attribute__((constructor)) \
+static void registerModuleFor##Module(void) { \
+    [XCMEngine registerModule:Module.class];\
+}
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface XCMKit : NSObject
+
+@property (nonatomic, strong, class) XCMContext *context;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 25 - 0
XCComponentization/Classes/XCMKit.m

@@ -0,0 +1,25 @@
+//
+//  XCMKit.m
+//  XCComponentization
+//
+//  Created by 邢铖 on 2023/7/8.
+//
+
+#import "XCMKit.h"
+#import "XCMEngine.h"
+
+@interface XCMKit ()
+
+@end
+
+@implementation XCMKit
+
++ (XCMContext *)context {
+    return XCMEngine.sharedEngine.context;
+}
+
++ (void)setContext:(XCMContext *)context {
+    XCMEngine.sharedEngine.context = context;
+}
+
+@end