啄幕鸟:简单高效的iOS开发工具

本项目属阿里巴巴开源项目之一,欢迎大家共建共享。啄木鸟地址:https://github.com/alibaba/youku-sdk-tool-woodpecker

痛点

UI走查效率低

• 截图>传电脑>重叠对比的UI走查方式费时费力,不易于发现问题,而标尺、网格等UI工具,不够精确且需要计算,使用繁琐。
• 现有吸色工具色值不准,不能获取开发设置的颜色,不以Hex显示色值,不便使用。
• 缺少获取圆角、透明度、字体等信息的工具。
• 设计同学想修改一个UI元素,除非是原开发者,其他同学并不知道相关UI类是什么,UI元素如何布局等,定位代码费时费力,效率有待提高。

难以获取App运行时数据

• 线上环境抓包困难。
• 不联调无法查看图片URL,无法导出App中的图片。
• 不联调无法获取关键debug数据,如路由参数,网络请求参数等。
• 对于线上Bug、偶现bug,难以在bug现场从App中获取数据以定位问题,debug过度依赖电脑联调,缺少独立便捷的debug工具。

简介

啄幕鸟,即手机屏幕上的啄木鸟,专抓App里的bug。啄幕鸟集合了UI检查、对象查看、方法监听等多种开发工具,通过拾取UI控件、查看对象属性、监听方法调用、App内抓包等,不依赖电脑联调,直接获取运行时数据,解决以上问题,快速定位bug,提高开发效率。啄幕鸟使用插件化架构,简便易用,零侵入、零依赖、易接入、易扩展。

基础服务

基础服务包括生命周期管理,插件加载、注册、运行,资源管理,本地化等基础能力。

公共模块

分享面板基于系统分享功能,提供了Airdrop、复制、钉钉发送、其他App内打开等方式导出信息,啄幕鸟中的文本、图片皆支持分享面板导出。图文预览用以全屏查看文本、图片。屏幕折线图方便插件直观的显示数据。

屏幕日志

为方便各插件在App内显示日志、接受用户输入,啄幕鸟中添加了屏幕日志模块,插件可直接使用公共的屏幕日志输出信息,也可实例化一个屏幕日志单独使用。

屏幕日志功能

◆ 拖动空白处可调整屏幕日志位置,拖动“◢”按钮可调整界面大小。
◆ 日志颜色可定制,以区分日志类型。
◆ 屏幕日志支持正则表达式和目标字符串过滤不想要的日志,正则表达式过滤只会显示正则匹配到的日志,目标字符串会过滤掉不包含目标字符串的日志。
◆ 屏幕日志支持日志搜索,点击ⓢ按钮可以打开/关闭日志搜索框,搜索支持正则表达式。
◆ 日志可通过分享面板导出。
◆ 屏幕日志支持界面扩展,可在屏幕日志下方添加自定义View,展示自定义功能,自定义View会跟随屏幕日志移动及改变宽度。

屏幕日志Demo:
屏幕日志Demo

主要插件介绍

UI检查工具

UI检查包含控件拾取和测距条两个工具,控件拾取在屏幕上点一点即可获取布局、颜色、字体、圆角、图片URL等信息,对于不能直接拾取到的间距可以使用测距条测量。

UI检查工具Demo

控件拾取

控件拾取根据手指在屏幕上的点击坐标,递归遍历View层级,获取包含触点坐标的最靠前的UI元素,在屏幕上直观显示相关信息,也可帮助了解UI布局、定位UI代码。

控件拾取功能

◆ 单击拾取当前点击的view,双击可跳过当前view,以拾取下层view,以防止view被同级view挡住拾取不到。
◆ 三个手指同时点击可切换拾取模式,只拾取响应链上的view,以防止屏幕上盖了一层view,影响拾取。
◆ 拾取后用线条和标注显示被拾取view的大小、位置,或与之前选中view的间距,简单直观,无需计算。
◆ 控件拾取信息区显示控件的类名、大小、透明度、圆角、hidden、文本、字体、颜色、图片尺寸、图片URL等信息,方便地获取运行时数据。
◆ 信息区提供父层按钮,点击拾取superview,层层拾取,即可了解UI布局,并根据view类名快速定位代码。
◆ 信息区根据选中元素的不同,提供文本、图片等按钮,以复制文本,查看、导出图片。
◆ 单击信息区可打开分享面板导出信息。
◆ 双击信息区可查看对象全部属性、成员变量。

UI检查-控件拾取

测距条

对于某些不能通过控件拾取查看的大小间距,如行间距等,啄幕鸟提供了测距条工具,在屏幕上添加大小、位置可控的view作为标尺测量间距。

测距条功能

◆ 点击“+”添加一个测距条,可添加任意多个测距条。
◆ 双击一个测距条可以将其删除。
◆ 单击一个测距条可将其选中,以改变其位置大小。
◆ 可在输入框按宽高输入测距条大小。
◆ 可通过按钮控制测距条的位置大小,按钮支持长按。
◆ 点击“Dp”可改变控制精度为dp或像素。

UI检查-测距条

In-App-Debug工具

iOS开发主要使用LLDB的断点、指令等进行Debug,依赖电脑联调,In-App-Debug即不依赖电脑,使用App内的debug工具获取运行时数据,帮助定位问题,啄幕鸟提供了三种查看运行时数据的方式:对象查看、方法监听和po命令,帮助在bug现场定位问题,也一并解决了线上环境抓包困难、关键数据无法获取等问题。

对象查看

App中所有的对象通过继承、代理、属性等关系,可以看作一个或多个连通图,从一个对象开始,可以查看到连通图里任一个对象的属性、成员变量,以获取运行时数据,定位问题。

功能

◆ 双击控件拾取的信息区即可打开对象查看,对象查看会显示拾取对象的属性、成员变量列表。
◆ 一个对象的属性、成员变量一般声明在不同的类中,一个列表只显示对象在某一类中声明的属性、成员变量,点击superclass即可查看父类中的声明。
◆ 在属性、成员变量列表中单击查看下一对象,双击打印对象description。
◆ KVC取值:在日志控制台中输入 k key.path 格式即可对最右侧列表对象KVC取值,如输入 k layer.cornerRadius 即可读取圆角大小。
◆ 点击“屏显控件”可将UIView及其子类对象在控件拾取中显示。
◆ 可在对象查看中使用po命令,详见po命令介绍。

对象查看

方法监听

对象查看提供了获取App静态数据的方式,而方法监听提供了获取动态数据的方式,输入监听命令即可监听任意OC方法的调用,输出调用参数和返回值,用以查看代码逻辑是否正常执行,关键方法是否调用,监听网络方法以在App内抓包等。

方法监听
方法监听功能

◆ 使用命令行交互,扩展性强,功能多样。
◆ 命令支持后台配置,方便快速输入命令。
◆ 可监听实例方法、类方法,支持同时监听多个对象、多个方法。
◆ 通过屏幕日志输出监听到的参数、返回值,JSON格式化显示。
◆ 保存监听到的对象、返回值,可使用命令对其KVC取值。
◆ 保存监听到方法的调用栈,可使用相关命令查看。

方法监听命令

方法监听需要输入类名、方法名、keypath等参数,故使用命令行交互,扩展性好,配合命令配置,输入也较方便。

命令简介

◆ 命令使用统一格式,<命令名缩写><空格><命令参数><空格><命令参数>,如监听命令 L className methodName,KVC取值命令 k keyPath,调用栈查看命令k callStack,所有命令详见工程README。
◆ 命令名缩写不区分大小写,方便输入。
◆ 命令可通过后台配置,一键输入,多条命令以分号分隔。
◆ 命令支持扩展,详见工程README。

后台命令配置

后台命令配置会显示在屏幕日志下方,方便命令输入,使用如下格式的JSON提供命令配置。

命令配置JSON格式

可在啄幕鸟初始化时指定配置JSON的获取地址,否则使用默认配置。
推荐在 https://github.com/ZimWoodpecker/WoodpeckerCmdSource 工程中建立配置,方便命令共享。

方法监听、日志过滤、搜索Demo

⚠ 注意方法监听可能会产生风险,例如,同时监听子类和父类的同名方法会导致崩溃,监听基础类的常用方法也可能会导致崩溃,如监听UIView的setFrame:方法时,由于显示日志也需要调用setFrame:方法,会导致循环调用;监听调用频繁的方法可能会显示大量日志,可能造成程序卡死等,应谨慎使用方法监听。

po命令

po命令是iOS开发中最常用debug命令,啄幕鸟让你在App运行时也可以随时随地执行po命令,随时随地debug。

po命令功能

◆ 输入h可查看输入历史记录。
◆ 其他几乎和LLDB po命令一样。

po命令

⚠ 当前po命令仅支持入参为int、long、BOOL、float、double、NSString、NSNumber,返回值为空、int、long、BOOL、float、double、id类型的方法,且参数不超过3个,嵌套不超过两层调用,po命令还在进一步优化中,欢迎共建,敬请期待。

更多功能

随着日常使用,啄幕鸟增加了更多功能:
1.系统信息:查看系统名称、版本、屏幕、UA等信息,支持添加业务方信息。
2.SandBox:查看沙盒文件,导出文件等。
3.Defaults:查看、新增、删除User Defaults。
4.清除数据:清除所有沙盒数据,包括User Default。
5.UI对比:支持将设计图导入到App中进行对比,并可画线、标注需修改的地方,方便UI走查。
6.查看图片资源、Bundle资源:查看App中的图片资源与Bundle目录内容。
7.Crash:查看Crash日志,需先打开Crash插件一次以开启Crash监控。
8.触点显示:显示手指触控,本文中相关动图就是开启了触点显示后录制的。
9.性能插件:查看CPU、内存占用率,帧率,网络流量。

接入

支持iOS 8.0及以上。
Pod接入:

pod  'YKWoodpecker'  

打开啄幕鸟:

 #import "YKWoodpecker.h"

 // 显示啄幕鸟,启动默认打开UI检查插件
 [[YKWoodpeckerManager shareInstance] show];

更多参见工程README,Github地址:https://github.com/alibaba/youku-sdk-tool-woodpecker

安全说明

啄幕鸟不依赖任何第三方库或数据。啄幕鸟代码中没有使用任何+load、+initialize等方法,啄幕鸟入口不显示则不会执行任何代码。如需线上使用啄幕鸟,应保护好开启入口,啄幕鸟支持安全模式,可在Release下开启安全模式,只支持打开安全插件,现有安全插件:UI检查、系统信息、触点显示。扩展插件注册时设置isSafePlugin=YES即可声明为安全插件,详见插件开发。

    // Release 下可开启安全模式,只支持打开安全插件
#ifndef DEBUG
    [YKWoodpeckerManager sharedInstance].safePluginMode = YES;
#endif

扩展开发

啄幕鸟使用插件化架构,新插件扩展方便,部分插件也支持功能扩展。

新插件扩展

一个类只需实现插件协议方法即可注册为插件,可定制插件分组、分组显示位置、插件名称、icon、插件显示位置等,简单方便,高可定制。

插件须实现YKWPluginProtocol协议:

#import "YKWPluginProtocol.h"

@protocol YKWPluginProtocol <NSObject>
/**
 Run the plugin.
@param paraDic 注册插件时设置的参数.
 */
- (void)runWithParameters:(NSDictionary *)paraDic;

@end

使用如下方法注册插件:

#import "YKWoodpecker.h"

/**
注册插件
@param parasDic 详见 YKWPluginModel
@{
@"isSafePlugin" : @(NO),
@"pluginName" : @"",
@"pluginIconName" : @"",
@"pluginCharIconText" : @"",
@"pluginCharIconColorHex" : @"",
@"pluginCategoryName" : @"",
@"pluginClassName" : @"",
@"pluginParameters" : @{}
}
@param position 插件显示位置,0...N-1, -1显示在最后。
*/
- (void)registerPluginWithParameters:(NSDictionary *)parasDic atIndex:(NSInteger)position;
- (void)registerPluginWithParameters:(NSDictionary *)parasDic;
- (void)registerPluginCategory:(NSString *)pluginCategoryName atIndex:(NSInteger)index;

推荐使用pluginCharIconText指定一个字符作为插件图标,以节省包大小。可以使用registerPluginCategory:atIndex:方法添加一个工具类别,并定制显示位置。
安全插件需注册时时设置isSafePlugin=YES。

插件功能扩展

部分插件支持以系统通知的方式与业务方交互,轻便无依赖,方便扩展已有插件功能。

控件拾取插件功能扩展

当一个控件被拾取时会发送一个通知,通知中包含被拾取的控件,业务方可以通过通知接收此控件,如果需要显示相关信息,可以发送特定格式的通知,控件拾取信息区即会显示通知中的信息,以实现功能扩展。

系统信息插件功能扩展

系统信息插件支持同样方式的功能扩展,通知格式如下:

#import "YKWoodpecker.h"

extern NSString *const YKWPluginSendMessageNotification;       /**< 插件发送信息通知 = @"YKWPluginSendMessageNotification" > */
extern NSString *const YKWPluginReceiveMessageNotification;    /**< 插件接收信息通知 = @"YKWPluginReceiveMessageNotification" > */
/*
 UI检查插件-控件拾取:
   发送格式:
   notification.object = @"ProbePluginNotification";
   notification.userInfo[@"view"] = 被拾取的控件;
   接收格式:
   notification.object = @"ProbePluginNotification";
   notification.userInfo[@"msg"] = 附加显示信息;

系统信息插件:
   发送格式:
   notification.object = @"SysInfoNotification";
   接收格式:
   notification.object = @"SysInfoNotification";
   notification.userInfo[@"msg"] = 需要显示的信息;
*/

最后

啄幕鸟项目现已开源,欢迎大家共建共享。
项目地址:https://github.com/alibaba/youku-sdk-tool-woodpecker

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,039评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,426评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,417评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,868评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,892评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,692评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,416评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,326评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,782评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,957评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,102评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,790评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,442评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,996评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,113评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,332评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,044评论 2 355