UIAppDelegate解耦

1.OC版的UIAppDelegate 解耦

oc版本的解耦demo有很多,大家可以google出来很多的方法。这里我推荐使用豆瓣的FRDModuleManager。推荐阅读这篇文章http://www.cocoachina.com/articles/17938。简单的说一下使用方法。

1.1 加载所有模块,文件从 plist中获取,将不同的模块填写到 plist 文件中。

1567072713370.jpg

1.2 在 UIApplicationDelegate 各方法中留下钩子

  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"ModulesRegister" ofType:@"plist"];
    FRDModuleManager *manager = [FRDModuleManager sharedInstance];
    [manager loadModulesWithPlistFile:plistPath];

    [manager application:application didFinishLaunchingWithOptions:launchOptions];

    return YES;
  }

  - (void)applicationWillResignActive:(UIApplication *)application {
    [[FRDModuleManager sharedInstance] applicationWillResignActive:application];
  }

  - (void)applicationDidEnterBackground:(UIApplication *)application {
    [[FRDModuleManager sharedInstance] applicationDidEnterBackground:application];
  }

  - (void)applicationWillEnterForeground:(UIApplication *)application {
    [[FRDModuleManager sharedInstance] applicationWillEnterForeground:application];
  }

  - (void)applicationDidBecomeActive:(UIApplication *)application {
    [[FRDModuleManager sharedInstance] applicationDidBecomeActive:application];
  }

  - (void)applicationWillTerminate:(UIApplication *)application {
    [[FRDModuleManager sharedInstance] applicationWillTerminate:application];
  }

1.3 在特定模块,根据需求完成注册即可,比如以下为PushModule的模块

//这是一个遵守了FRDModule协议的模块PushModule.h
@interface PushModule : NSObject

@end

//PushModule.m
 (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSLog(@"%@  PushModule", NSStringFromSelector(_cmd));
    
    [self zxc_configurationAccount:launchOptions];
    
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
  NSLog(@"%@  PushModule", NSStringFromSelector(_cmd));
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
  NSLog(@"%@  PushModule", NSStringFromSelector(_cmd));
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
  NSLog(@"%@  PushModule", NSStringFromSelector(_cmd));
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
  NSLog(@"%@  PushModule", NSStringFromSelector(_cmd));
}

- (void)applicationWillTerminate:(UIApplication *)application
{
  NSLog(@"%@  PushModule", NSStringFromSelector(_cmd));
}

-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
    
    NSLog(@"11111");
    return  [[UMSocialManager defaultManager] handleOpenURL:url];
}

1.4 这样就可以了。具体的请看demo

2.swfit版的UIAppDelehate解耦

swift的解耦也可以使用FRDModuleManager,但是自己觉得不是很好。所以在不停的学习中发现了 Massive App Delegate,使用了以后觉得不错。,下面说说具体的使用吧。给自己记个笔记

2.0 命令设计模式 启动时来初始化各种命令(比如 第三方库的初始化,根视图控制器等)
  var window: UIWindow?

    let mediator = AppLifecycleMediator.makeDefaultMediator()

    let appDelegate = AppDelegateFactory.makeDefault()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        StartupCommandsBuilder()
            .setKeyWindow(window!)
            .build()
            .forEach { $0.execute() }

        _ = appDelegate.application?(application, didFinishLaunchingWithOptions: launchOptions)

        return true
    }

//启动命令builder
//调用构建器来初始化命令然后触发它们。
final class StartupCommandsBuilder {
    private var window: UIWindow!

    func setKeyWindow(_ window: UIWindow) -> StartupCommandsBuilder {
        self.window = window
        return self
    }

    func build() -> [Command] {
        return [
            InitializeThirdPartiesCommand(),
            InitialViewControllerCommand(keyWindow: window),
            InitializeAppearanceCommand(),
            RegisterToRemoteNotificationsCommand()
        ]
    }
}
protocol Command {
    func execute()
}
////第三方在这里初始化
struct InitializeThirdPartiesCommand: Command {
    func execute() {
        // Third parties are initialized here
    }
}
////在这里初始化根视图控制器
struct InitialViewControllerCommand: Command {
    let keyWindow: UIWindow

    func execute() {
        // Pick root view controller here
        keyWindow.rootViewController = ViewController()
    }
}
//设置UIAppearance 全局设置 通过UIAppearance设置一些UI的全局效果,这样就可以很方便的实现UI的自定义效果又能最简单的实现统一界面风格
struct InitializeAppearanceCommand: Command {
    func execute() {
        // Setup UIAppearance
        UINavigationBar.appearance().tintColor = .black
        UISearchBar.appearance().tintColor = .red
    }
}
////在这里注册远程通知
struct RegisterToRemoteNotificationsCommand: Command {
    func execute() {
        // Register for remote notifications here
    }
}
2.1 复合设计模式 让复合和叶子委托每个都有一个责任。类似工厂一样复合了整个的AppDelegate,然后分发给相应的子叶的AppDelegate。(比如推送通知AppDelegate)
var window: UIWindow?

    let mediator = AppLifecycleMediator.makeDefaultMediator()

    let appDelegate = AppDelegateFactory.makeDefault()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        StartupCommandsBuilder()
            .setKeyWindow(window!)
            .build()
            .forEach { $0.execute() }

        _ = appDelegate.application?(application, didFinishLaunchingWithOptions: launchOptions)

        return true
    }
//AppDelegate工厂
//这些对象封装了触发自身所需的所有参数
enum AppDelegateFactory {
    static func makeDefault() -> AppDelegateType {
        return CompositeAppDelegate(appDelegates: [PushNotificationsAppDelegate(), StartupConfiguratorAppDelegate(), ThirdPartiesConfiguratorAppDelegate()])
    }
}

typealias AppDelegateType = UIResponder & UIApplicationDelegate

//复合AppDelegate
class CompositeAppDelegate: AppDelegateType {
    private let appDelegates: [AppDelegateType]

    init(appDelegates: [AppDelegateType]) {
        self.appDelegates = appDelegates
    }
    //将需要的
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        appDelegates.forEach { _ = $0.application?(application, didFinishLaunchingWithOptions: launchOptions) }
        return true
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        appDelegates.forEach { _ = $0.application?(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken) }
    }
}

//推送通知AppDelegate
class PushNotificationsAppDelegate: AppDelegateType {
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        // Registered successfully
        
    }
}

//启动配置AppDelegate
class StartupConfiguratorAppDelegate: AppDelegateType {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Perform startup configurations, e.g. build UI stack, setup UIApperance
        return true
    }
}

//第三方配置程序AppDelegate
class ThirdPartiesConfiguratorAppDelegate: AppDelegateType {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Setup third parties
        return true
    }
}
2.2 中介者模式 将UIApplication的生命周期通知底下的监听者。如定义AppLifecycleMediator将UIApplication的生命周期通知底下的监听者,这些监听者必须遵循AppLifecycleListener协议,如果需要监听者要能扩展新的方法。
// MARK: - AppLifecycleListener
protocol AppLifecycleListener {
    func onAppWillEnterForeground()
    func onAppDidEnterBackground()
    func onAppDidFinishLaunching()
}

extension  AppLifecycleListener {
    func onAppWillEnterForeground() {}
    func onAppDidEnterBackground() {}
    func onAppDidFinishLaunching() {}
}

//相应的通知应该做的事
class VideoListener: AppLifecycleListener {
    func onAppDidEnterBackground() {
        //停止视频播放
    }
}

class SocketListener: AppLifecycleListener {
    func onAppWillEnterForeground() {
        //开启长连接
    }
}

// MARK: - Mediator
//将UIApplication的生命周期通知底下的监听者,这些监听者必须遵循AppLifecycleListener协议,如果需要监听者要能扩展新的方法。
class AppLifecycleMediator: NSObject {
    private let listeners: [AppLifecycleListener]

    init(listeners: [AppLifecycleListener]) {
        self.listeners = listeners
        super.init()
        subscribe()
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    //添加通知
    private func subscribe() {
        NotificationCenter.default.addObserver(self, selector: #selector(onAppWillEnterForeground), name: .UIApplicationWillEnterForeground, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(onAppDidEnterBackground), name: .UIApplicationDidEnterBackground, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(onAppDidFinishLaunching), name: .UIApplicationDidFinishLaunching, object: nil)
    }

    @objc private func onAppWillEnterForeground() {
        listeners.forEach { $0.onAppWillEnterForeground() }
    }

    @objc private func onAppDidEnterBackground() {
        listeners.forEach { $0.onAppDidEnterBackground() }
    }

    @objc private func onAppDidFinishLaunching() {
        listeners.forEach { $0.onAppDidFinishLaunching() }
    }
}


//添加通知者
extension AppLifecycleMediator {
    static func makeDefaultMediator() -> AppLifecycleMediator {
        let listener1 = VideoListener()
        let listener2 = SocketListener()
        return AppLifecycleMediator(listeners: [listener1, listener2])
    }
}

2.3 这样就可以了。具体的请细看这篇文章 Massive App Delegate。我只是一个代码的搬运工。

你可能感兴趣的:(UIAppDelegate解耦)