上篇如何把業(yè)務邏輯從ViewController中拆分出來講了給ViewController瘦身,這篇繼續(xù)講給AppDelegate瘦身。
我見過這樣的代碼
Appdelegate.m
[UMSocialData setAppKey:UMENG_APPKEY];
//打開調(diào)試log的開關(guān)
[UMSocialData openLog:YES];
//向微信注冊
[WXApi registerApp:WXAppId];
//設(shè)置微信AppId,設(shè)置分享url,默認使用友盟的網(wǎng)址
[UMSocialWechatHandler setWXAppId:WXAppId appSecret:WXAppSecret url:UMSocialShareUrl];
[UMSocialQQHandler setQQWithAppId:WXQQId appKey:WXQQKey url:UMSocialShareUrl];
// 新浪微博
[UMSocialSinaHandler openSSOWithRedirectURL:SinaRedirectURL];
//設(shè)置支持沒有客戶端情況下使用SSO授權(quán)
[UMSocialQQHandler setSupportWebView:YES];
基礎(chǔ)數(shù)據(jù)
。。碧查。
。。忠售。
Push
......
......
數(shù)據(jù)庫
....
等等传惠。。稻扬。卦方。
App delegate里面一堆東西,自己看著都頭疼泰佳。
因為剛開始的時候可能只是加了一個友盟分享盼砍,后來公司要加Jpush,然后繼續(xù)在Appdelegate里面加逝她,再后來......
無窮無盡的需求浇坐,然后Appdelegate不忍直視。
通過單例給AppDelegate瘦身
既然ViewController可以通過一個manager類來瘦身黔宛,是否能夠運用到Appdelegate里面呢近刘,當然可以。
類似于友盟的初始化臀晃,我們可以這么做
- (void)launchApp:(UIApplication *)application withOptions:(NSDictionary *)launchOptions {
[UMManager getInstance];
}
然后再寫一個UMManager的單例觉渴,把上面Appdelegate里面的那些友盟統(tǒng)計的代碼在UMManager里面實現(xiàn)。
@implementation UMManager
+ (UMManager *)getInstance{
static UMManager *sharedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
- (id)init{
if (self = [super init]) {
[self setUM];
}
return self;
}
- (void)setUM
{
[UMSocialData setAppKey:UMENG_APPKEY];
//打開調(diào)試log的開關(guān)
[UMSocialData openLog:YES];
//向微信注冊
[WXApi registerApp:WXAppId];
//設(shè)置微信AppId徽惋,設(shè)置分享url案淋,默認使用友盟的網(wǎng)址
[UMSocialWechatHandler setWXAppId:WXAppId appSecret:WXAppSecret url:UMSocialShareUrl];
[UMSocialQQHandler setQQWithAppId:WXQQId appKey:WXQQKey url:UMSocialShareUrl];
// 新浪微博
[UMSocialSinaHandler openSSOWithRedirectURL:SinaRedirectURL];
//設(shè)置支持沒有客戶端情況下使用SSO授權(quán)
[UMSocialQQHandler setSupportWebView:YES];
}
@end
這樣AppDelegate看起來就干凈多了。除此之外還有更重要的寂曹,通過Method Swizzing來給AppDelegate瘦身
通過Method Swizzing給AppDelegate瘦身
關(guān)于MethodSwizzing這里有幾篇文章
Objective-C Runtime 運行時之四:Method Swizzling
Objective-C Method Swizzling 的最佳實踐
@implementation AppDelegate (PushManager)
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
swizzleMethod(class, @selector(application:didFinishLaunchingWithOptions:),
@selector(aop_application:didFinishLaunchingWithOptions:));
swizzleMethod(class, @selector(application:didRegisterForRemoteNotificationsWithDeviceToken:),
@selector(aop_application:didRegisterForRemoteNotificationsWithDeviceToken:));
swizzleMethod(class, @selector(application:didFailToRegisterForRemoteNotificationsWithError:),
@selector(aop_application:didFailToRegisterForRemoteNotificationsWithError:));
swizzleMethod(class, @selector(application:didReceiveRemoteNotification:),
@selector(aop_application:didReceiveRemoteNotification:));
swizzleMethod(class, @selector(application:didReceiveRemoteNotification:fetchCompletionHandler:),
@selector(aop_application:didReceiveRemoteNotification:fetchCompletionHandler:));
});
}
static inline void swizzleMethod(Class class, SEL originalSelector, SEL swizzledSelector) {
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL didAddMethod =
class_addMethod(class,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
- (BOOL)aop_application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self setUpJPushManagerWithOptions:launchOptions];
BOOL result = [self aop_application:application didFinishLaunchingWithOptions:launchOptions];
NSDictionary *userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if(userInfo)
{
//分發(fā)
[self pushDispatch:userInfo];
}
return result;
}
// push注冊成功
- (void)aop_application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[self aop_application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
NSString *tokenStr = [NSString stringWithFormat:@"%@",deviceToken];
[ud setObject:tokenStr forKey:@"deviceToken"];
[ud synchronize];
UI_LOG(@"deviceToken = %@", tokenStr);
// Required
[APService registerDeviceToken:deviceToken];
}
// push注冊失敗
- (void)aop_application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
[self aop_application:application didFailToRegisterForRemoteNotificationsWithError:error];
}
// iOS7
- (void)aop_application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[self aop_application:application didReceiveRemoteNotification:userInfo];
}
// iOS8及以上
- (void)aop_application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
[self aop_application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
......
......
有人說MethodSwzzing用起來爽哎迄,用不好的話會出問題回右,而且很難排查隆圆。我曾經(jīng)在網(wǎng)上看到過這么一段話,覺著很經(jīng)典翔烁。拿來分享給大家:
Method Swzzing就像是一把鋒利的刀渺氧,用鋒利的刀切菜固然很爽,但是容易把手切破蹬屹。你不能因為刀鋒利侣背,就不用吧。相反你用鈍刀風險可能更大慨默。就像單例設(shè)計模式一樣贩耐,飽受爭議,但依然有很多人用它厦取。
這里有一些StackOverFlow關(guān)于Method Swzzing的討論潮太。
總之我們要學會用好這把鋒利的刀,而不是棄用。