一、說明
從2019年3月份接手游戲SDK任務以來乡翅,我們完善了 登錄模塊、支付模塊罪郊、事件 統(tǒng)計模塊蠕蚜、分享模塊 等功能 ,隨著游戲發(fā)布的區(qū)域變化悔橄,游戲方也提出了很多個性 化的需求靶累,比如就拿登錄來說,美國地區(qū)的用戶常用的第三方登錄方式是: facebook癣疟、Twitter 挣柬,而日本地區(qū)的用戶常用的第三方登錄方式是:Twitter 、Line 睛挚。剛開始為了快速滿足游戲的需求邪蛔,我們把 所有的登錄方式都集成了一遍,但 是對于有些游戲是不需要那么多登錄方式的扎狱,為了優(yōu)化 SDK 和減少包體積店溢,我們做 了一個動態(tài)的配置,舉例子:如果不需要 line 登錄委乌,游戲方就不需要添加LineSDK 床牧。問題來了:我們給游戲的包中是集成 LineSDK 相關代碼的,如果游戲方 不添加 LineSDK 遭贸,代碼就會報錯戈咳。以下我們會給出幾種解決方案。
二壕吹、預編譯方案
這是我們剛開始給出的第一種方案著蛙,就是在原來的 SDK 進行低成本的改造,首先 通過預編譯的方式 根據 第三方SDK的頭文件是否存在來判斷是否需要執(zhí)行相關代 碼耳贬,代碼如下:
#define lineSDKModule __has_include(<LineSDK/LineSDKLogin.h>)
#if lineSDKModule @import LineSDK;
#endif
這種方式的改造踏堡,在 SDK 運行階段,確實也按照我們期望的方式運行了咒劲,不添加 lineSDK 也不會報錯顷蟆,但是當我們把 SDK 編譯成 SDK.framework 包給到另一個工程 使用的時候就出現(xiàn)問題了。假如我們在導出SDK.framework 的時候項目中有 lineSDK 包腐魂,而另一個添加 SDK 的工程中帐偎,沒有添加 lineSDK,就會報錯蛔屹,提示找不 到 LineSDK削樊。相信看到這里大部分人都知道問題的所在了, __has_include()是一 個宏定義,在編譯階段都已經確定了是否存在值漫贞。也就是在我們導出 SDK.framework 的時候甸箱,就確定了 lineSDKModule 的值,所以迅脐,它不是在另個工 程中動態(tài)的判斷是否存在 lineSDK 芍殖。所以,這種方案并不能達到我們做動態(tài)配置的 需求仪际。
三围小、通過 runtime 方式
這種方式相信大家都會想到,通過蘋果的運行時來判斷類是否存在树碱,進而調用類
內部的方法肯适,從而達到我們的目的。部分代碼如下:
1. 獲取類
Class lineSDkLogin = NSClassFromString(@"LineSDKLogin");
2.通過 performSelector 執(zhí)行第三方 SDK 的方法
if ([self.lineLogin respondsToSelector:@selector(startLoginWithPermissions:)]){
[self.lineLogin performSelector:@selector(startLoginWithPermissions:) withObject:@[@"profile", @"friends", @"groups"]];
}
通過這種方式確實達到了我們期望的需求成榜,但是有一個問題就是如果第三方 SDK 方 法進行升級的時候框舔,維護就會比較困難,而且代碼會比較臃腫赎婚,我們在看看還有沒 有其他的解決方案刘绣。
四、runtime 方式 + 每個第三方 SDKAdapter
這種方式就是我們?yōu)槊總€第三方需要動態(tài)配置的SDK創(chuàng)建一個Adapter.SDK ,
在 Adapter.SDK 內部實現(xiàn) 第三方的 SDK 功能 挣输,比如 Facebook SDK 纬凤,我們可以創(chuàng) 建一個 FBAdapter.SDK ,在這個SDK內部實現(xiàn)我們所需要的Facebook相關的功 能撩嚼,在我們的 SDK.framework 內部 通過 runtime 的方式 判斷工程中是否引用了 FBAdapter.SDK 停士,從而達到 對 Facebook 相關功能模塊的操縱。
優(yōu)點:我們只需要通過 runtime的 方式判斷 第三方Adapter.SDK 是否存在完丽,而 在 Adapter.SDK 內部不需要 runtime 處理第三方 SDK 功能調用恋技,便于后期的 SDK 升級和維護。
缺點:隨著我們要動態(tài)配置的 第三方SDK的數量的增加逻族,我們創(chuàng)建多個 Adapter.SDK 蜻底,會導致要維護的 Adapter.SDK 比較多 。
五聘鳞、Adapter 文件 + 預編譯方案
我們在討論預編譯方案的時候知道薄辅,這種方案是行不通的,這次我們做下變通搁痛, 我們添加一個 橋接的中間層(我們通過這個中間層調用第三方SDK的相關功能) 长搀, 而這個中間層我們 不打成 framework 包給到游戲方,而是以 .h .m的方式給到游戲 方鸡典。而在中間層的內部我們通過 預編譯的方案處理項目工程中是否添加了 第三方 SDK ,因為我們的中間層沒有編譯成 framework 枪芒,所以判斷項目工程中是否存在第 三方 SDK 是在游戲方 在打 IPA 包的時候進行判斷的彻况。
這樣就解決了 我們只是使用 預編譯方案的不足谁尸。
優(yōu)點:便于后期第三方SDK的升級維護
缺點:我們的一部分實現(xiàn)文件會暴露出來
六、總結
在接手 SDK 后纽甘,遇到了很多問題良蛮,也解決了很多問題,以上是我們解決動態(tài)配
置第三方 SDK 時候悍赢,提出的幾個方案决瞳,同時,也歡迎大家討論更多其他解決方案