1. 程式人生 > >XCODE8 API文件解析

XCODE8 API文件解析


31 OCT 2016 . CATEGORY: TECH COMMENTS 
#TUTORIAL

背景

   iOS API的start/deprecated的判斷一個重要基礎是獲取到每個API的具體版本支援資訊。
   在Xcode8之前,
/Applications/Xcode7.app/Contents/Developer/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Tokens/Objective-C
包含了所有的API
參考文件,解析這些xml即可獲取到C:API,OC:Class/ProtocolProperty/Method的對應資訊。 Xcode8出現之後,此處空空如也,該怎麼辦呢?

Xcode7 API文件

XCODE8 API文件去哪了?

思路:
Xcode8從原始碼跳轉Documentation正常,即使斷網也OK,說明Xcode8的文件也在本地。
首先找到Xcode的PID
ps -A 
筆者這裡是23592
打印出所有此pid開啟的檔案
lsof -p 23592

xcode8-opened-files​ 從圖中可以發現疑似文件檔案的map.db和cache.db

DB分析

​ 通過對map.db和cache.db的分析,不難發現,map中儲存的是token/request_key這類資料,再結合request_key隱射到cache.db中的blob中去。結合response表中的uncompressed_size欄位(3876),對比blob匯出的內容大小(1833),可以發現blob應該就是我們的目標資料,且被壓縮過了。

xcode8-document-map-db-preview

xcode8-document-cache-db-preview

xcode8-document-api-compressed-initwithframe-ref

BLOB內容的解壓縮

開啟多個blob內容不難發現他們有同樣的模式
	bvx......bvx$
Google大法搜尋下:

google-bgxd-compress-preview

可以發現git@github.com:lzfse/lzfse.git已經提供了一種對於此類資料的解壓縮方法,呼叫
lzfse -decode -i ~/Desktop/initwithframe.txt -o initwithframe_out.txt
即可得到我們需要的資料:

xcode8-document-api-uncompressed-initwithframe-ref

從BLOB中獲取API支援版本資訊

blob解壓縮之後的內容是json格式的,關於版本的資訊儲存在如下的欄位裡(以-[UIViewController viewDidUnload]為例)
"y"
: [ { "p": "ios",->平臺 "de": "6.0",->deprecated系統號 "ir": "3.0",->起始支援系統號 "cr": "10.0"->當前支援系統號 }

整合

基於以上的分析,採用以下的步驟獲取所有API的版本資訊:
1.基於sqlite提供的C API,遍歷所有的map記錄,並通過request_key獲取到所有的token對應的blob位元組流
2.使用lzfse提供的庫,將blob位元組流解壓縮獲得json檔案
3.分析所有的json檔案,並根據
	"l": "occ"->Objective-C
	"k": "cl"->"intf"->協議
		 "intfp"->協議屬性
		 "instm"->例項方法
		 "instp"->例項屬性
		 "clm"->類方法
		 "cldata"->類屬性
		 "intfdata"->協議屬性
		 "intfm"->協議方法
		 "intfcm"->協議方法
		 "func"->C APi
		 "struct"->結構體
		 "union"->聯合
		 "structp"->結構體屬性
		 "unionp"->聯合屬性
		 "data"/"enum"/"tdef"/"tag"/"econst"->其他常亮
		 "macro"->巨集
	獲取各種型別包含的tokens的對應版本資訊。

問題

	雖然使用上述的方法已經可以獲得所有的token的版本資訊,但是實際中也發現了一個問題,即部分類和協議屬性的版本描述不準確,典型地如:
	+[NSNotificationCenter defaultCenter]

NSNotificationCenter_defaultCenter_DB

NSNotificationCenter_defaultCenter_Doc

NSNotificationCenter_defaultCenter_Web

NSNotificationCenter_defaultCenter_Xcode

對於這種典型的問題,需要在發現後自己再修改下生成的API->版本資訊資料Json,才能正常使用。