客戶端可以獲取當(dāng)前屏幕截圖并上傳到前臺(tái)顯示出來(lái),但前臺(tái)是如何知道屏幕上哪些元素是可以與用戶進(jìn)行交互的呢铅檩?這就需要客戶端在上傳當(dāng)前屏幕圖像時(shí),將當(dāng)前屏幕中的可繪制元素的一些關(guān)鍵信息一同上報(bào)莽鸿∶林迹客戶端可以遍歷當(dāng)前屏幕上所有的可視化元素,然后讀取元素對(duì)象所有的屬性值祥得,組織成一定的格式上報(bào)兔沃。
那么mixpanel是怎么做的呢?與上面的分析大致相同级及,不同之處在于mixpanel使用的一個(gè)配置文件來(lái)定義收集哪些對(duì)象的哪些屬性信息乒疏。這里給出具體的配置文件,供大家參考饮焦。在代碼中對(duì)這些以JSON格式下發(fā)的配置文件解析成各自的對(duì)象描述類怕吴,客戶端就可以按照這些描述類配置的信息獲取對(duì)象的關(guān)鍵信息了窍侧。
配置解析
從圖中我們大致能領(lǐng)略整個(gè)配置的解析過(guò)程。不過(guò)我覺(jué)得如果圖中所有的描述類都從MPTypeDescription類中派生的話會(huì)更完美一點(diǎn)转绷。
對(duì)象序列化
整個(gè)過(guò)程是由MPApplicationStateSerializer對(duì)象發(fā)起的伟件,從當(dāng)前屏幕最底層的元素window開始序列化:
-(NSDictionary*)objectHierarchyForWindowAtIndex:(NSUInteger)index
{
UIWindow* window = [self windowAtIndex:index];
if(window){
return [serializer serializedObjectsWithRootObject:window];
}
}```
整個(gè)序列化過(guò)程的算法是,將對(duì)象加入到末訪問(wèn)隊(duì)列中暇咆,從末訪問(wèn)隊(duì)列中取一個(gè)元素訪問(wèn)并序列化保存到已訪問(wèn)隊(duì)列中锋爪,訪問(wèn)的過(guò)程中如果元素存在子元素,則將子元素也加入到末訪問(wèn)隊(duì)列中等待后續(xù)訪問(wèn)爸业,如此遞歸到所有元素都已訪問(wèn)并序列化其骄。
![序列化流程圖](http://upload-images.jianshu.io/upload_images/1910166-d1242aa52ff41167.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
## 屏幕圖像的獲取
在MPApplicationStateSerializer類中有一下screenshotImageForWindowAtIndex:的方法用來(lái)獲取屏幕的UIImage對(duì)象,然后將image轉(zhuǎn)化成NSData對(duì)象后一并通過(guò)JSON格式直接上報(bào)扯旷。同時(shí)取NSData對(duì)象的MD5值拯爽,用于前臺(tái)判斷屏幕圖像是否發(fā)生變化進(jìn)而刷新瀏覽中的顯示信息。
## 序列化數(shù)據(jù)協(xié)議格式
使用該協(xié)議格式將序列化后的所有數(shù)據(jù)上報(bào)到服務(wù)器钧忽,由前臺(tái)負(fù)責(zé)解析并在瀏覽器中顯示出來(lái)毯炮,這里給也一個(gè)[參考文件](http://ocuwifxvz.bkt.clouddn.com/snapshot.json)。