1.OC版的UIAppDelegate 解耦
oc版本的解耦demo有很多,大家可以google出来很多的方法。这里我推荐使用豆瓣的FRDModuleManager。推荐阅读这篇文章http://www.cocoachina.com/articles/17938。简单的说一下使用方法。
1.1 加载所有模块,文件从 plist中获取,将不同的模块填写到 plist 文件中。
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])
}
}