如何給你的AppDelegate瘦身

上篇如何把業(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的討論潮太。

What are the Dangers of Method Swizzling in Objective C?

總之我們要學會用好這把鋒利的刀,而不是棄用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末铡买,一起剝皮案震驚了整個濱河市更鲁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌奇钞,老刑警劉巖澡为,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異景埃,居然都是意外死亡媒至,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門谷徙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來塘慕,“玉大人,你說我怎么就攤上這事蒂胞⊥寄兀” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵骗随,是天一觀的道長蛤织。 經(jīng)常有香客問我,道長鸿染,這世上最難降的妖魔是什么指蚜? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮涨椒,結(jié)果婚禮上摊鸡,老公的妹妹穿的比我還像新娘。我一直安慰自己蚕冬,他們只是感情好免猾,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著囤热,像睡著了一般猎提。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旁蔼,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天锨苏,我揣著相機與錄音,去河邊找鬼棺聊。 笑死伞租,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的限佩。 我是一名探鬼主播葵诈,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了驯击?” 一聲冷哼從身側(cè)響起烁兰,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎徊都,沒想到半個月后沪斟,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡暇矫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年主之,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片李根。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡槽奕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出房轿,到底是詐尸還是另有隱情粤攒,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布囱持,位于F島的核電站夯接,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏纷妆。R本人自食惡果不足惜盔几,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望掩幢。 院中可真熱鬧逊拍,春花似錦、人聲如沸际邻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽枯怖。三九已至注整,卻和暖如春能曾,著一層夾襖步出監(jiān)牢的瞬間度硝,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工寿冕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蕊程,地道東北人。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓驼唱,卻偏偏與公主長得像藻茂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容