内容简介:作为iOS整个项目的核心大型项目的是时候该给
作为iOS整个项目的核心 App delegate
,随着项目的逐渐变大,会变得越来越臃肿,一不小心代码就过了千行.
大型项目的 App delegate
体积会大到什么程度呢?我们可以参考下国外2亿多月活的 Telegram
的 App delegate
.是不是吓一跳,4千多行.看到这样的代码是不是很想点击左上角的x.
是时候该给 App delegate
解耦了,目标:
每个功能的配置或者初始化都分开,各自做各自的事情. App delegate
要做到只需要调用就好了.
下面来谈谈如何利用两种 设计模式 实现:
1.命令模式
命令模式: 发送方发送请求,然后接收方接受请求后执行,但发送方可能并不知道接受方是谁,执行的是什么操作,这样做的好处是发送方和接受方完全的松耦合,大大提高程序的灵活性.
1. 定义好协议,把相关初始化配置代码分类
protocol Command { func execute() } struct InitializeThirdPartiesCommand: Command { func execute() { // 第三方库初始化代码 } } struct InitialViewControllerCommand: Command { let keyWindow: UIWindow func execute() { // 根控制器设置代码 } } struct InitializeAppearanceCommand: Command { func execute() { // 全局外观样式配置 } } struct RegisterToRemoteNotificationsCommand: Command { func execute() { // 远程推送配置 } } 复制代码
2. 管理者
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() ] } } 复制代码
3. App delegate
调用
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { StartupCommandsBuilder() .setKeyWindow(window!) .build() .forEach { $0.execute() } return true } 复制代码
使用命令模式的好处是,如果要添加新的配置,设置完后只要加在 StartupCommandsBuilder
中就可以了. App delegate
中不需要添加任何内容.
但这样做只能将 didFinishLaunchingWithOptions
中的代码解耦, App delegate
中的其他方法怎样解耦呢?
2.组合模式
组合模式: 可以将对象组合成树形结构来表现"整体/部分"层次结构. 组合后可以以一致的方法处理个别对象以及组合对象.
这边我们给 App delegate
每个功能模块都设置一个子类,每个子类包含所有 App delegate
的方法.
1. 每个子模块实现各自的功能
// 推送 class PushNotificationsAppDelegate: AppDelegateType { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { print("推送配置") return true } func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { print("推送相关代码...") } // 其余方法 } // 外观样式 class AppearanceAppDelegate: AppDelegateType { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { print("外观样式配置") return true } } // 控制器处理 class ViewControllerAppDelegate: AppDelegateType { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { print("根控制器设置代码") return true } } // 第三方库 class ThirdPartiesConfiguratorAppDelegate: AppDelegateType { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { print("第三方库初始化代码") return true } func applicationDidEnterBackground(_ application: UIApplication) { print("ThirdPartiesConfiguratorAppDelegate - applicationDidEnterBackground") } func applicationDidBecomeActive(_ application: UIApplication) { print("ThirdPartiesConfiguratorAppDelegate - applicationDidBecomeActive") } } 复制代码
2. 管理者
typealias AppDelegateType = UIResponder & UIApplicationDelegate 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) } } func applicationDidEnterBackground(_ application: UIApplication) { appDelegates.forEach { _ = $0.applicationDidEnterBackground?(application) } } func applicationDidBecomeActive(_ application: UIApplication) { appDelegates.forEach { _ = $0.applicationDidBecomeActive?(application) } } } 复制代码
3. App delegate
调用
@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? let appDelegate = AppDelegateFactory.makeDefault() enum AppDelegateFactory { static func makeDefault() -> AppDelegateType { return CompositeAppDelegate(appDelegates: [ PushNotificationsAppDelegate(), AppearanceAppDelegate(), ThirdPartiesConfiguratorAppDelegate(), ViewControllerAppDelegate(), ] ) } } func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { _ = appDelegate.application?(application, didFinishLaunchingWithOptions: launchOptions) return true } func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { appDelegate.application?(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken) } func applicationDidBecomeActive(_ application: UIApplication) { appDelegate.applicationDidBecomeActive?(application) } func applicationDidEnterBackground(_ application: UIApplication) { appDelegate.applicationDidEnterBackground?(application) } } 复制代码
在 App delegate
解耦中相比命令模式,使用组合模式的可自定义程度会更高一点.
本文收录于 SwiftTips
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 解耦并不难 - 单体系统中的解耦
- 解耦并不难:分布式系统中的解耦
- 聊聊AppDelegate解耦
- AppDelegate解耦
- AppDelegate解耦
- 巧用Fragment解耦onActivityResult
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Automate This
Christopher Steiner / Portfolio / 2013-8-9 / USD 25.95
"The rousing story of the last gasp of human agency and how today's best and brightest minds are endeavoring to put an end to it." It used to be that to diagnose an illness, interpret legal docume......一起来看看 《Automate This》 这本书的介绍吧!