[iOS]如何封裝第三方庫(Appdelegate啟動)(二)

前言

上一篇文章[iOS]如何封裝第三方庫(非Appdelegate啟動)(一)介紹了如何封裝非Appdelegate啟動的三方庫,這篇文章講述如何抽象化需要Appdelegate啟動的三方庫.其實(shí)封裝這種三方庫的目的是在于減少appdelegate的體積.值得一提的是,這是我們team一位伙伴提出來的服務(wù)化思想,經(jīng)過整體的討論完善,才在項(xiàng)目中有了運(yùn)用.

舉個(gè)例子

我們都集成過微信支付或者微信登錄這個(gè)三方,它需要在appdelegate中進(jìn)行appId的注冊,然后執(zhí)行各種handler和resp回調(diào).如果再加上支付寶或者其他sdk,那么appdelegate中的代碼會越來越多,后期耦合加重,會越來越難以維護(hù).這里以我剛做過的微信登錄為例.

在用服務(wù)化之前代碼只這樣的:

@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions userInfo:(NSDictionary *)userInfo{
    [WXApi registerApp:@"appid"];
    
    return YES;
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
    [WXApi handleOpenURL:url delegate:self];
    return YES;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
    [WXApi handleOpenURL:url delegate:self];
    return YES;
}

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
    [WXApi handleOpenURL:url delegate:self];
    return YES;
}
- (void)onResp:(BaseResp *)resp{
    if (resp.errCode == 0){
        SendAuthResp *rep = (SendAuthResp *)resp;
        [[NSNotificationCenter defaultCenter] postNotificationName:WXDIDLOGINSUCCESS object:nil userInfo:@{WXCode : rep.code}];
    }
}
@end

需要拉起微信的地方也會有如下直接耦合WXApi的代碼:

SendAuthReq *request = [[SendAuthReq alloc] init];
    request.state = state;
    request.scope = scope;
    [WXApi sendReq:request];

服務(wù)化思想

將每個(gè)需要在appdelegate進(jìn)行設(shè)置的sdk功能當(dāng)做一個(gè)服務(wù),通過一個(gè)Services.plist表來對這些服務(wù)進(jìn)行注冊;如果該服務(wù)需要傳入?yún)?shù),那么可以考慮新建一個(gè)ServiceParam.plist表來對這些services提供參數(shù),當(dāng)然你也可以直接在Services.plist直接維護(hù)這些參數(shù),這里采取前者.

具體實(shí)現(xiàn)

1.新建一個(gè)類AppdelegateComponents,同時(shí)聲明AppdelegateComponentsDelegate協(xié)議,同時(shí)提供獲取所有服務(wù),加載plist文件的api,其中協(xié)議方法tp_application: didFinishLaunchingWithOptions: userInfo:,是其他服務(wù)必須實(shí)現(xiàn)的方法.

@protocol ICXAppdelegateComponentsDelegate<UIApplicationDelegate>
- (BOOL)tp_application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions userInfo:(NSDictionary *)userInfo;
@end
@interface ICXAppdelegateComponents : NSObject
/**
 獲取單例
 */
+ (instancetype)shareInstance ;

/**
 根據(jù)plist文件注冊服務(wù)
 
 @param plistFile 文件名
 */
- (void)loadModulesWithPlistFile:(NSString *)plistFile;

/**
 所有注冊的服務(wù)
 
 @return 所有服務(wù)
 */
- (NSMutableArray*)services;
@end

2.新建一個(gè)服務(wù)(WXLoginService),并為上述的兩個(gè)plist文件填充好參數(shù)



這個(gè)微信登錄的服務(wù)實(shí)現(xiàn)如下:

#import "ICXWXLoginModule.h"
#import "ICXAppdelegateComponents.h"
#import "WXApi.h"

NSString * const WXDIDLOGINSUCCESS = @"WXDIDLOGINSUCCESS";
NSString * const WXCode = @"WXCode";
@interface ICXWXLoginModule()<ICXAppdelegateComponentsDelegate,WXApiDelegate>

@end
@implementation ICXWXLoginModule
+ (BOOL)wxInstalled{
    return [WXApi isWXAppInstalled];
}
+ (void)sendWXAuthReqeustWithState:(NSString *)state scope:(NSString *)scope otherParam:(NSString *)other{
    SendAuthReq *request = [[SendAuthReq alloc] init];
    request.state = state;
    request.scope = scope;
    [WXApi sendReq:request];
}
- (BOOL)icx_application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions userInfo:(NSDictionary *)userInfo{
    [WXApi registerApp:[userInfo objectForKey:@"ICXWXLoginModule"]];
    
    return YES;
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
    [WXApi handleOpenURL:url delegate:self];
    return YES;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
    [WXApi handleOpenURL:url delegate:self];
    return YES;
}

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
    [WXApi handleOpenURL:url delegate:self];
    return YES;
}

- (void)onResp:(BaseResp *)resp{
    if (resp.errCode == 0){
        SendAuthResp *rep = (SendAuthResp *)resp;
        [[NSNotificationCenter defaultCenter] postNotificationName:WXDIDLOGINSUCCESS object:nil userInfo:@{WXCode : rep.code}];
    }
}
@end

3.到這里服務(wù)已經(jīng)生成完畢,接下來是到appdelegate里面調(diào)用:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    ICXLoginViewController *tabVC = [[ICXLoginViewController alloc] init];
    UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:tabVC];
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.rootViewController = navi;
    [self.window makeKeyAndVisible];

    //加載服務(wù)列表
    [[ICXAppdelegateComponents shareInstance] loadModulesWithPlistFile:@"ICXModulesRegister"];
    id<ICXAppdelegateComponentsDelegate> service;
    //獲取參數(shù)列表
    NSString *keyPlistPath = [[NSBundle mainBundle] pathForResource:@"ICXAppKeysInfo" ofType:@"plist"];
    NSDictionary *keysInfo = [NSDictionary dictionaryWithContentsOfFile:keyPlistPath];
    //循環(huán)遍歷列表中的服務(wù),并調(diào)用
    for(service in [[ICXAppdelegateComponents shareInstance] services]){
        if([service respondsToSelector:@selector(icx_application:didFinishLaunchingWithOptions:userInfo:)]){
            [service icx_application:application didFinishLaunchingWithOptions:launchOptions userInfo:keysInfo];
        }
    }
    return YES;
}
//因?yàn)閣x登錄還需要另外幾個(gè)方法輔助,所以還需要添加如下代碼,用來啟動wx的拉取回調(diào)功能
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{

    for(id<ICXAppdelegateComponentsDelegate>service in [[ICXAppdelegateComponents shareInstance] services]){
        if([service respondsToSelector:_cmd]){
#pragma clang diagnostic push
#pragma clang diagnostic ignored"-Wdeprecated-declarations"
            [service application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
#pragma clang diagnostic pop
        }
    }
    return YES;
}

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
    for(id<ICXAppdelegateComponentsDelegate> service in [[ICXAppdelegateComponents shareInstance] services]){
        if([service respondsToSelector:_cmd]){
#pragma clang diagnostic push
#pragma clang diagnostic ignored"-Wdeprecated-declarations"
            [service application:application handleOpenURL:url];
#pragma clang diagnostic pop
        }
    }
    return YES;
}

然后在需要拉取微信的地方如下調(diào)用:

if ([ICXWXLoginModule wxInstalled]){
        [ICXWXLoginModule sendWXAuthReqeustWithState:@"xxxx" scope:@"snsapi_userinfo" otherParam:nil];
    }else{
        
    }

這樣appdelegate就只耦合了AppdelegateComponents這個(gè)類,并沒有包含其他任何sdk,同時(shí)在業(yè)務(wù)需要響應(yīng)的地方也沒有直接耦合sdk,你可以想象一下這種方式帶來的好處.同時(shí)多個(gè)服務(wù)都不需要進(jìn)行額外的操作,最多只是在appdelegate里面處理幾個(gè)協(xié)議方法,其他任何地方都不需要動.

demo暫時(shí)不放出了,因?yàn)橘N的是項(xiàng)目代碼,哈哈自己領(lǐng)悟吧.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末膏燃,一起剝皮案震驚了整個(gè)濱河市杏糙,隨后出現(xiàn)的幾起案子捌朴,更是在濱河造成了極大的恐慌拷肌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件简逮,死亡現(xiàn)場離奇詭異球散,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)散庶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門蕉堰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人悲龟,你說我怎么就攤上這事屋讶。” “怎么了须教?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵皿渗,是天一觀的道長。 經(jīng)常有香客問我轻腺,道長乐疆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任贬养,我火速辦了婚禮挤土,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘误算。我一直安慰自己仰美,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布儿礼。 她就那樣靜靜地躺著咖杂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蚊夫。 梳的紋絲不亂的頭發(fā)上诉字,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼奏窑。 笑死导披,一個(gè)胖子當(dāng)著我的面吹牛屈扎,可吹牛的內(nèi)容都是我干的埃唯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼鹰晨,長吁一口氣:“原來是場噩夢啊……” “哼墨叛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起模蜡,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤漠趁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后忍疾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闯传,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年卤妒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了甥绿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡则披,死狀恐怖共缕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情士复,我是刑警寧澤图谷,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站阱洪,受9級特大地震影響便贵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜冗荸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一嫉沽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧俏竞,春花似錦绸硕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至席楚,卻和暖如春咬崔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工垮斯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留郎仆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓兜蠕,卻偏偏與公主長得像扰肌,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子熊杨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353

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

  • 001失敗之后…… 向好友推薦自己做的事業(yè)曙旭,遭遇失敗之后,萬念俱灰晶府。告訴自己桂躏,這很正常,不忍回顧川陆,也很正常剂习。但是就...
    漁歌子珊閱讀 728評論 0 0
  • 終于要放寒假了,還記得上上個(gè)周日返校時(shí)较沪,孩子對我的種種不舍鳞绕。掀開我的衣服留下一個(gè)個(gè)吻,對我大聲說出:"媽媽...
    秋水無痕Wh閱讀 186評論 0 0
  • 因?yàn)閷懙锰N切、太精彩购对,一個(gè)字都舍不得刪猾昆,直接搬過來了,摘來的這篇講的是有子女的夫妻之間的家務(wù)分擔(dān)及其心理活動骡苞,還...
    f魔夜閱讀 651評論 0 0
  • 小兔子乖乖 大象姐姐 馬上就來 快樂的夏天 有你的陪伴 是說不完的清涼
    賽騰煙閱讀 148評論 5 8
  • 在工作中解幽,你是不是經(jīng)常遇到這樣的問題: 領(lǐng)導(dǎo)安排你為某個(gè)項(xiàng)目/活動寫一份方案贴见,你絞盡腦汁寫好之后滿懷希望的送上去后...
    企劃經(jīng)理之路閱讀 383評論 0 2