SDK是一種方便常見的開發者工具形式,但愈來愈多的內嵌功能,可能讓SDK服務愈來愈全,可能會出現功能的重複,形成SDK包愈來愈重,給App自身帶來負擔……
爲App減負,MTA踏上了探索的道路。前端
陳翔,騰訊大數據平臺高級開發工程師。
從2009年工做至今,在前端和終端開發領域有着豐富的實戰經驗。
目前爲MTA、騰訊移動推送(信鴿)等項目iOS端研發負責人。編程
隨着移動互聯網的高速發展, 出現了大量的公司以SDK的形式爲App提供服務,例如統計、推送、Crash監控等等領域。接入各類SDK服務作開發,相對App從零開始自研的話,極大的提高了App的開發效率,節約了大量的時間和成本。開發一個爆款軟件再也不是幾年,可能就是幾個月時間。bash
MTA的產品定位是移動統計分析工具,在伴隨着與開發者共同成長的道路上,也在不斷響應用戶的需求,提供更多更豐富的開發者服務,好比最近升級的Crash監控。同時也在提供更多的運營服務,好比最近上線的可視化埋點功能。網絡
在MTA的成長道路上,不斷的提供更多更好的服務,因而乎問題來了,這也是業界廣泛的一個問題:SDK體積愈來愈大。架構
這對許多App來講是個噩夢,由於不僅是增長了流量,可能也會帶來更多的額外計算工做,形成卡頓,用戶的電量也在加速消耗。編程語言
MTA技術總監顧孫炬(Raygu)適時提出:爲App減負,MTA勢在必行。ide
爲了致力於提供最佳的體驗,咱們在思考,怎樣可以保證SDK足夠小,又能提供用戶所需的各類服務,知足各類大小客戶們的需求。截至如今經歷了三個階段。模塊化
在早期MTA有新功能的話, SDK版本就是一個體積一直累加的過程。有一天,忽然有重要客戶提出是不能接受體積大的。因而針對這個客戶,經過溝通的方式,肯定他們須要的核心功能,而後拉代碼分支,作相應的修改。而後又有相似的第二個客戶、第三個客戶…… 看着分支愈來愈多,不管是新特性的增長或者bug的修復,對於終端來講,維護的成本很是高。不由要打個冷顫,再這樣發展下去,維護的工做量不可估量。函數
圖1. 苦逼的各類歷史定製版本工具
針對第一階段的問題,作了這樣的設計,將SDK分紅三種大版本。
超級精簡版: 提供給各類二次封裝SDK使用,或者對SDK體積有超級嚴格要求的App。
適度精簡版: 提供最經常使用的功能。
完整版: 全部功能的集合版本。 備註:二次封裝SDK是指各類聚合SDK,也就是包含了不少SDK服務的大SDK。
從上看出,經過對需求功能和客戶分組的方式,三個版本可做爲絕大多數客戶的基線版本。在相對穩定的基線的基礎上作不大的調整,相對第一階段維護成本小了很多。
圖2. 3種版本應對種種需求
在推廣的過程當中,由於知足了二次封裝SDK的標準,可是超級精簡版的功能不夠徹底,有的客戶有獨立接入MTA的需求。這樣當App同時接入超級精簡版和其餘版本的時候,會產生許多」 duplicate symbols」的錯誤。
經過短期的實踐,後來發現徹底不可維護,由於有N家二次封裝SDK的客戶,這樣只是超級精簡版就要修改出N個項目,而一份代碼有N個類和N個字符串,工做量大且容易出錯。
回到初衷,咱們想盡可能下降維護的成本,在Objective-C命名空間上,咱們作出了以下的設計:
在預編譯文件(.pch)中,作一個相似這樣的宏定義
#define symbol prefix##symbol複製代碼
經過對prefix作一次修改,則能夠全局修改符號的前綴。舉個例子:
#define MTA QQ##MTA複製代碼
這樣就實現了開發時,在XCode項目中是MTA,編譯後生成的符號是QQMTA,字符串也能夠作相似的處理,給不一樣客戶配置不一樣的前綴。由於解決了符號重名問題,這樣的話,超級精簡版就能夠輕鬆的給各個二次封裝SDK提供服務,同時和其餘版本(適度精簡版或完整版衍生的版本)共同生存。
僞代碼示例:
Prefix.pch文件
//處理類名
#define ARK(symbol) prefix##symbol
//處理字符串
#define ARKNSSTR (symbol) @ #prefix #symbol
#define MTA ARK(MTA)
#define MTAConfig ARK(MTAConfig)
某個.m文件
static NSString *const BUSINESS_ID = ARKNSSTR(MTA);複製代碼
作到第二階段時,較少人力已經足夠維護好MTA項目了。可是在最近一年,需求愈來愈多,人力的匹配速度卻沒有跟上,這樣形成MTA的多版本維護變得有些吃力。這樣就須要思考是否能進一步減小維護的成本。
經過從新梳理,以及在MTA技術總監顧孫炬(Raygu)的支持下,根據特色MTA被分紅幾大部分: 必需模塊,重要模塊,獨立模塊。
必需模塊: MTA運行必需的模塊,屬於核心中的核心。
重要模塊: 依賴必需模塊,功能很是重要,客戶也能夠不須要使用的功能。
獨立模塊: 輕度依賴必需模塊,大部分邏輯都是獨立運行。
在此劃分的構想上,提出插件和組件機制。架構圖以下:
圖4. 清晰可拆解的模塊化構建
首先,最底層是core,對應必需模塊,包含上報模塊和基礎功能,這二者表明是MTA最基礎的核心功能,做爲一切組件和插件的基礎。同時是一個Service Provider的角色,把最基礎的上報、網絡、存儲、通用函數等基礎能力暴露出來複用。
往上是組件層,對應重要模塊,這裏是一些MTA重點服務的功能,依賴core層的功能。在本來組件都打包在一塊兒的時候,MTA須要用到組件就直接使用。這裏作了個代理的設計。把須要用到組件的功能作個對應的protocol定義,在MTA工做流程中一個組件對應一個delegate,delegate鏈接了對應的組件,組件實現了對應的protocol。這樣在MTA工做流程中經過對delegate的判斷,若是鏈接了組件,就可使用對應模塊,反之缺失對應組件的功能。即便沒有組件,而增長這個邏輯帶來體積的增長几乎能夠忽略。
再往上是MTA的插件層,對應獨立模塊,這一層的模塊基本都是能夠獨立運行或者和MTA主流程耦合很小。MTA核心狀態的變動,會發出響應的通知,插件會訂閱這些通知,也就是觀察者模式。好比初始化完成後的狀態通知,插件收到通知後纔會進行自身的初始化,這樣能夠保證MTA核心功能的完整服務可用,使插件運行的更加穩定。
至此,MTA只須要維護一份代碼,便可實現靈活的功能拼接,知足各個用戶的需求,而且不會出現」 duplicate symbols」的衝突問題。實現了一套代碼N個版本。
編譯和打包
MTA的架構,若是用XCode來打包,會很是複雜,不可控。實際上從第二階段開始,咱們已經進行腳本化打包,基於Xcode command line tools。經過靈活的參數傳遞,能夠快速的生成各類binary和fat binary文件,很是方便。
最後,附上MTA官方版本的物理結構圖, 下載地址請到MTA官網SDK下載頁進行下載,或點擊文末下載連接。
圖5. 靈活可選的各個模塊
用戶須要什麼功能,引用相應的.a文件便可,實現了用戶本身靈活組裝MTA功能。其中有部分組件打包在libmtasdk.a裏,若是有特殊需求,也能夠聯繫咱們分離出來。
MTA是一款爲開發者提供服務的工具產品,核心是圍繞開發者的需求,對外輸出咱們的能力與服務。
因此,若是你們在MTA使用過程當中有任何問題,均可以隨時聯繫咱們哦~咱們一直都在努力,請協助咱們共建更棒的數據工具產品!
若是您但願試用或者體驗 MTA Crash分析,請訪問MTA官網接入試用。
若是您對該功能有疑問、或者在使用中遇到了困難,歡迎您聯繫mta官網在線客服,或者發送您的問題郵件至:dtsupport@tencent.com
商務合做或業務諮詢,請聯繫如下郵箱:mta@tencent.com