客户端可以获取当前屏幕截图并上传到前台显示出来,但前台是如何知道屏幕上哪些元素是可以与用户进行交互的呢?这就需要客户端在上传当前屏幕图像时,将当前屏幕中的可绘制元素的一些关键信息一同上报。客户端可以遍历当前屏幕上所有的可视化元素,然后读取元素对象所有的属性值,组织成一定的格式上报。
那么mixpanel是怎么做的呢?与上面的分析大致相同,不同之处在于mixpanel使用的一个配置文件来定义收集哪些对象的哪些属性信息。这里给出具体的配置文件,供大家参考。在代码中对这些以JSON格式下发的配置文件解析成各自的对象描述类,客户端就可以按照这些描述类配置的信息获取对象的关键信息了。
配置解析
从图中我们大致能领略整个配置的解析过程。不过我觉得如果图中所有的描述类都从MPTypeDescription类中派生的话会更完美一点。
对象序列化
整个过程是由MPApplicationStateSerializer对象发起的,从当前屏幕最底层的元素window开始序列化:
-(NSDictionary*)objectHierarchyForWindowAtIndex:(NSUInteger)index
{
UIWindow* window = [self windowAtIndex:index];
if(window){
return [serializer serializedObjectsWithRootObject:window];
}
}```
整个序列化过程的算法是,将对象加入到末访问队列中,从末访问队列中取一个元素访问并序列化保存到已访问队列中,访问的过程中如果元素存在子元素,则将子元素也加入到末访问队列中等待后续访问,如此递归到所有元素都已访问并序列化。
![序列化流程图](http://upload-images.jianshu.io/upload_images/1910166-d1242aa52ff41167.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
## 屏幕图像的获取
在MPApplicationStateSerializer类中有一下screenshotImageForWindowAtIndex:的方法用来获取屏幕的UIImage对象,然后将image转化成NSData对象后一并通过JSON格式直接上报。同时取NSData对象的MD5值,用于前台判断屏幕图像是否发生变化进而刷新浏览中的显示信息。
## 序列化数据协议格式
使用该协议格式将序列化后的所有数据上报到服务器,由前台负责解析并在浏览器中显示出来,这里给也一个[参考文件](http://ocuwifxvz.bkt.clouddn.com/snapshot.json)。