YourView源码研究与学习
YourView 研究
项目地址
https://github.com/TalkingData/YourView
由于项目比较老,运行起来时有个地方会报错,需要修改如下,在_snapWithSublayer
的最前面增加判断widt
h或height
是否为0
,为0的直接返回为空,否则会崩溃
1
2
3
4
5
6
7
8
9
# UIView+YVNodeInfo.m
-(NSString*)_snapWithSublayer:(BOOL)containSublayer
{
CGRect frameX = self.frame;
if (frameX.size.width <= 0 || frameX.size.height <= 0) {
return @"";
}
....
}
代码调用流程
1、启动Web服务器
1、利用项目启动时,所有类都会执行load
方法, ,启动GCDWebServer
服务器: TalkingDataSDKDemo/libyourview/main/Main.m
-> +(void)load
-> +(void)_main
-> GCDWebServer
GET
: -> Main._excuteCmd
2、请求App信息
GET url http://127.0.0.1:8080/?cmd=appinfo
-> Main._excuteCmd
-> 返回App相关信息
3、获取最新的view及相关信息
GET url: http://127.0.0.1:8080/?cmd=viewtree
-> Main._excuteCmd
-> 同步主流程 rootViewTreeDictionary
-> 递归查下view及子节点view的信息 [keyWindow traversal:stepIn context:context]
-> nodeInfo
-> 每个view的信息 frame
、相对于window的frame
、_snapWithSublayer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// "YVTraversalStepin.h"
// 层级信息
(lldb) po [stepined stepinfo]
{
"assign_to_viewcontroller" = "";
"index_row" = "-1";
"index_section" = "-1";
"is_in_collectionview" = 0;
"is_in_tableview" = 0;
"view_deepth" = 0;
"view_level" = "/0";
}
// "NSObject+YVNodeInfo.h"
// 类,地址、继承关系
po superinfo
{
address = 0x10361cfc0; // [NSString stringWithFormat:@"%p",self]
class = UIWindow; // NSStringFromClass(self.class)
inherit = "UIWindow:UIView:UIResponder:NSObject"; // 不断递归找到superClass
}
// "UIView+YVNodeInfo.h"
// layer的截图的base64、frame
po selfinfo
{
isoffscreen = 0;
localframe = "{0, 0, 393, 852}";
snapshot = "iVBORw0KGgoAA...";
windowframe = "{0, 0, 393, 852}";
}
// "UIView+YVTraversal.h"
// 记录每个view及subview的address,以及记录总view数量
po extraInfo
{
screeninfo = "{0, 0, 393, 852}";
totalcount = 55;
}
// respons 返回的内容:
{
"viewtree": stepinfo + nodeInfo=(superInfo+selfInfo),
"extraInfo": extraInfo
}
+
4、点击Here,摇动选择的view
GET url: http://127.0.0.1:8080/?cmd=shake&address=0x1036181b0
-> Main._excuteCmd
-> 根据address找到缓存的view[[YVObjectManager sharedInstance].context.viewMap objectForKey:addresss]
-> shake2
-> 执行layer的transform.translation.x
动画
5、跟新选中view的frame
POST url: http://127.0.0.1:8080/?cmd=setframe&address=0x10368b9f0
-> 根据address找到缓存的view[[YVObjectManager sharedInstance].context.viewMap objectForKey:addresss]
-> setFrame
-> 执行
Mac端软件展示逻辑
1、填写ip并点击按钮
buttonPressed
-> "http://%@:8080?cmd=appinfo"
-> onAppInfoSuccess
-> requestViewTree
-> http://"http://%@:8080?cmd=viewtree"
-> [windowController updateViewTree:dict]
-> notifyDataSuccess
-> 通知YVViewTreeDidLoadNotificationName
2、点击刷新按钮
onRefreshButtonEvent
-> "http://%@:8080?cmd=viewtree"
-> notifyDataSuccess
-> 通知YVViewTreeDidLoadNotificationName
左侧树形结构 YVLeftViewController
-> YVViewTreeDidLoadNotificationName
-> dataOK
-> viewTree
-> dataSource
-> reloadData
-> NSOutlineView
中间UI展示 YVMiddleViewController
-> YVViewTreeDidLoadNotificationName
-> dataOK
-> viewTree
-> dataSource
-> createView
-> NSNode
+ snapshot