WKAppDelegate 0.0.7

WKAppDelegate 0.0.7

GitWangKai维护。



  • 作者
  • 王凯

WKAppDelegate

Version Pod License iOS 6.0+ ARC

注:在 v0.0.3 版本引入 NSObject+AppEventModule 分类,用以解决 NSObject 的 performSelector: 函数最多支持 2 个参数的问题。

注:v0.0.5 版本进行了 prefix 变更,SHRM 变更为 WK。

链接

介绍

深度解耦AppDelegate的逻辑,教您如何实现AppDelegate模块化拆分,将本来数千行的代码简化到10行以内,操作简便,最小化代码侵入。支持iOS 6及以上版本。 图片文字

AppDelegate简化后的样子:

#import "WKAppDelegate.h"
@interface AppDelegate : WKAppDelegate
@property (strong, nonatomic) UIWindow *window;
@end
#import "MainViewController.h"
@implementation AppDelegate
@synthesize window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[super application:application didFinishLaunchingWithOptions:launchOptions];
[self initMainController];
return YES;
}

- (void)initMainController {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
self.window.rootViewController = [[MainViewController alloc] init];
[self.window makeKeyAndVisible];
}
@end

没错,引入框架后,AppDelegate的代码就变成这样!怎么做?请看示例。

特性

  • 积木式设计,业务插件化隔离。
  • AppDelegate.m内的代码精简到10行以内。
  • 原有的功能模块拆分为独立的子模块,模块独立,模块之间无耦合。
  • 每个模块都拥有自己的生命周期,目前支持模块的初始化->销毁。
  • 模块可自定义执行的优先级,也就是说可以自定义原AppDelegate中不同业务功能的加载顺序。
  • 模块扩展性高,易于维护,新增需求只需新增模块即可,并在模块内部管理该模块的生命周期。
  • 代码可读性强,每个模块只负责自身的业务。
  • 模块支持热插拔,需要时拖入项目中,不需要时无需删除也不会影响项目编译!
  • 其他特性,请参阅demo中自行探索。

安装

1.CocoaPods

  1. 在 Podfile 中添加 pod 'WKAppDelegate', '~> 0.0.3'
  2. 执行 pod installpod update
  3. 在 AppDelegate 中导入 <WKAppDelegate.h> 并继承。

2.手动导入

下载WKAppDelegate文件夹,将WKAppDelegate文件夹拖入您的工程中。

用法

  • WKAppDelegate是暴露给外的主类,内部实现了所有的App生命周期方法,当然你也可以指定实现一类方法,或者不需要框架实现,只需在您的AppDelegate中重写即可。
  • WKAppEventModuleManager是模块的管理类,管理所有注册的模块。
  • WKBaseAppEventModule是所有模块需要继承的基类,为所有模块提供公共方法,包括模块执行顺序,模块生命周期管理等,可自行扩充。
  • WKAppEventAnnotation是模块注册专用类,每个模块都需要注册的,为什么注册?不注册怎么管理呢。
  • NSObject+AppEventModule为NSObject分类,扩充了NSObject的performSelector:函数,用以支持多参数传递。

1.AppDelegate继承WKAppDelegate,使WKAppDelegate管理App的生命周期函数。

2.创建插件,继承WKBaseAppEventModule

#import "WKBaseAppEventModule.h"

@interface testMudule : WKBaseAppEventModule

@end
WKAppEventMod(testMudule)

@implementation testMudule

// 该插件执行顺序
- (NSInteger)moduleLevel {
return 1;
}

//该插件需要在didFinishLaunchingWithOptions:生命周期函数中做些操作
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//插件初始化
[self initMudule];
//插件销毁,父类实现
[self destroyModule];
return YES;
}

- (void)initMudule {
NSLog(@"testMudule init");
}

@end

插件概念:每个插件代表一个独立业务,例如程序启动后的数据库处理、定位处理等都可以定义为一个插件。继承WKBaseAppEventModule的插件将被管理。如果希望在程序启动时执行插件,可以在插件中重写didFinishLaunchingWithOptions:,如上所示。如果希望在程序进入后台时执行插件的某些业务,只需重写applicationDidEnterBackground:即可,然后在函数中进行业务处理。

3.如果需要自定义App周期函数,只需在AppDelegate中重写即可。

4.NSObject+AppEventModule分类

提供了一种通过performSelector:函数传递多个参数的解决方案,基于NSMethodSignatureNSInvocation实现。核心代码如下:

- (id)performSelector:(SEL)selector
           withObject:(id)p1
           withObject:(id)p2
           withObject:(id)p3 {
    NSMethodSignature *sig = [self methodSignatureForSelector:selector];
    if (sig) {
        NSInvocation* invo = [NSInvocation invocationWithMethodSignature:sig];
        [invo setTarget:self];
        [invo setSelector:selector];
        [invo setArgument:&p1 atIndex:2];
        [invo setArgument:&p2 atIndex:3];
        [invo setArgument:&p3 atIndex:4];
        [invo invoke];
        if (sig.methodReturnLength) {
            return [self handleReturnType:sig invo:invo];
        } else {
            return nil;
        }
    } else {
        return nil;
    }
}
- (id)handleReturnType:(NSMethodSignature *)sig invo:(NSInvocation *)aInvo
{
    int booResult = strcmp([sig methodReturnType], @encode(BOOL));
    int floatResult = strcmp([sig methodReturnType], @encode(float));
    int intResult = strcmp([sig methodReturnType], @encode(int));
    
    id anObject = nil;
    if (booResult == 0)
    {
        BOOL result;
        [aInvo getReturnValue:&result];
        anObject = [NSNumber numberWithBool:result];
    }
    else if (floatResult == 0)
    {
        float result;
        [aInvo getReturnValue:&result];
        anObject = [NSNumber numberWithFloat:result];
    }
    else if (intResult)
    {
        int result;
        [aInvo getReturnValue:&result];
        anObject = [NSNumber numberWithInt:result];
    }
    return anObject;
}

5.详细使用请参考demo,如有疑问欢迎提交issue,欢迎star。

License

WKAppDelegate遵循MIT许可证。有关更多信息,请参阅LICENSE文件。