FLEX(Flipboard Explorer)是一套用于 iOS 开发的应用内调试和探索工具。FLEX 以工具栏的形式浮动在应用上方的窗口中。在 FLEX 工具栏中,你可以查看和修改正在运行的应用中的几乎所有的状态
GitHub 地址:https://github.com/FLEXTool/FLEX
查看和修改层级结构中的视图
查看实例对象的属性和成员变量
动态修改实例对象的属性和成员变量
动态调用对象方法和类方法
观察详细的网络请求历史记录,包括时间、报头和完整的响应
添加自定义的模拟器快捷键
查看系统日志消息(例如,来自 NSLog
的输出信息)
通过扫描堆空间访问活动的对象
查看应用沙盒中的文件系统
浏览文件系统中的 SQLite
/Realm
数据库
使用 control
、shift
、command
键在模拟器中触发 3D touch
浏览当前应用和已链接的系统框架中的所有类(包括:公有的 + 私有的)
快速访问有用的对象,例如:[UIApplication sharedApplication]
、AppDelegate
、rootViewController
等等
动态查看和修改 NSUserDefaults
所存储的值
与其它调试工具不同,因为 FLEX 完全运行在你的应用中,所以 FLEX 不需要连接到 LLDB
、Xcode
或者其他远程调试的服务端。FLEX 在模拟器和真机上都能很好地运行
在 iOS 模拟器中,你可以使用键盘快捷键来激活 FLEX:点击 F
键可以切换 FLEX 工具栏,点击 ?
键可以查看完整的快捷键列表。你还可以通过编程的方式来显示 FLEX
简洁版本:
// Objective-C
[[FLEXManager sharedManager] showExplorer];
// Swift
FLEXManager.shared.showExplorer()
完整版本
#if DEBUG
#import "FLEXManager.h"
#endif
...
- (void)handleSixFingerQuadrupleTap:(UITapGestureRecognizer *)tapRecognizer
{
#if DEBUG
if (tapRecognizer.state == UIGestureRecognizerStateRecognized) {
// This could also live in a handler for a keyboard shortcut, debug menu item, etc.
// 这也可以存在于键盘快捷键、调试菜单项等的处理程序中
[[FLEXManager sharedManager] showExplorer];
}
#endif
}
关于 tvOS:
FLEX 本身不支持开箱即用的 tvOS。然而,其他人已经自行将 FLEX 移植到 tvOS 上。如果你需要 tvOS 的支持,请寻找这些分支之一(这是其中的一个分支)
功能示例(Feature Examples)修改视图(Modify Views)
在选择视图后,你可以点击工具栏下方的信息栏以显示有关该视图的更多详细信息。在那里,你可以修改属性和调用方法
网络记录(Network History)
启用后,网络调试允许你查看使用 NSURLConnection
或 NSURLSession
发出的所有请求。并且允许你调整要缓存的响应体的类型,以及响应缓存的最大大小限制。你可以选择在应用启动时自动启用网络调试,此设置会在启动时持久化
查看堆上的所有对象(All Objects on the Heap)
FLEX 查询 malloc 以获取所有已分配的活动内存块,并搜索那些看起来像对象的内存块。你可以从这里看到一切
通过地址访问(Explore-at-address)
如果你获取到了一个地址,则你可以尝试探索该地址所指向的对象。如果 FLEX 可以验证该地址指向有效的对象,则 FLEX 将打开该地址。 如果 FLEX 不确定该地址是否指向有效的对象,则 FLEX 会发出警告并拒绝访问该地址。但是,你仍可以通过 Unsafe Explore
来访问该地址
模拟键盘快捷键(Simulator Keyboard Shortcuts)
默认的键盘快捷键允许你激活 FLEX 工具,使用方向键滚动,以及使用 Esc
键关闭 FLEX 的工具栏
你还可以通过 -[FLEXManager registerSimulatorShortcutWithKey:modifiers:action:description:]
添加自定义的键盘快捷键
文件浏览器(File Browser)
查看应用程序包或沙盒中的文件系统。FLEX 会显示文件大小、图像预览、以友好的方式显示 .json
和 .plist
文件。你可以重命名和删除文件或文件夹。也可以将文本和图片拷贝到剪贴板中,并通过 share
来共享任意文件,以方便你在其他应用中打开这些文件
SQLite 浏览器(SQLite Browser)
SQLite
数据库文件(以 .db
或者 .sqlite
为扩展名的文件)或 Realm
数据库文件都可以使用 FLEX 进行浏览。数据库浏览器允许你查看所有的表,并通过点击每列的表头进行排序
在模拟器中模拟 3D 触摸(3D Touch in the Simulator)
使用 command
control
shift
组合键,你可以在模拟器中模拟不同级别的 3D 触摸压力。每个键贡献最大压力的 1/3
。请注意,你需要稍微移动触摸以获取压力更新
探索已加载的库(Explore Loaded Libraries)
深挖框架中所有公共的和私有的类。如果你需要了解有关类的更多信息,则可以创建该类的实例并研究其默认状态。如果你知道要查找的类是哪个,则还可以输入类名以直接跳转到该类
编辑 NSUserDefaults(NSUserDefaults Editing)
FLEX 允许你修改 NSUserDefaults
中的字符串(string
)、数字(number
)、数组(array
)、字典(dictionary
),以及它们的任意组合。输入将被解析为 JSON
(即,输入格式为 JSON
)。如果为默认键设置了其他类型的对象(例如:NSDate
),则只能查看它们不能编辑它们
探索其他 App(Learning from Other Apps)
代码注入就留给大家去摸索了 😇
FLEX 需要针对 iOS 9 或更高版本的应用
要运行示例项目,请在 Example/
文件夹中打开终端窗口并运行 pod install
,然后打开生成的 workspace
CocoaPods
FLEX 在 CocoaPods 上可用。只需将以下行添加到你的 podfile
中:
pod 'FLEX', :configurations => ['Debug']
Carthage
FLEX 在 Carthage 上可用。只需将以下行添加到你的 Cartfile
中:
github "flipboard/FLEX"
Buck
如果你使用的是 Buck,则你可能希望静默 FLEX 发出的一些警告。你需要将 FLEX 构建为 apple_library
并传递 -Wno-unsupported-availability-guard
标志,以及下面的其他警告标志,以禁用 FLEX 可能具有的任何其他警告
Manual
手动将 Classes/
中的文件添加到 Xcode 项目中,或者直接拖入整个 FLEX/
文件夹。请务必从 Release
版本中排除 FLEX,否则你的应用将被拒绝
静默警告
将以下标志添加到 Build Settings
中的 Other Warnings Flags
:
-Wno-deprecated-declarations
-Wno-strict-prototypes
-Wno-unsupported-availability-guard
Swift Package Manager
在 Package.swift
的 depdendencies
中包含依赖项
dependencies: [
.package(url: "https://github.com/FLEXTool/FLEX.git", .upToNextMajor(from: "4.3.0"))
]
接下来,将 FLEX 库包含到你的 Target 中:
.target(
name: "YourDependency",
dependencies: [
"FLEX"
]
)
避免将 FLEX 编译到 Release 版本(Excluding FLEX from Release (App Store) Builds)
因为 FLEX 可以轻松探索应用程序的内部结构,所以不应该向用户公开这些内容。幸运的是,可以很容易地从 Release
版本中排除 FLEX 文件。这些策略会因为你在项目中集成 FLEX 的方式的不同而不同,如下所述
在代码中将 FLEX 用 #if DEBUG
语句集成的位置包装起来,以确保该工具只能在你的 Debug
版本中访问,并避免在你的 Release
版本中出现错误。有关集成 FLEX 的更多帮助,请参阅示例项目
CocoaPods
如果你在 Podfile
中将 FLEX 的 configurations
指定为 Debug
,则 CocoaPods 会自动从 Release
版本中排除 FLEX:
pod 'FLEX', :configurations => ['Debug']
Carthage
不要将 FLEX.framework
添加到 Target 的 embedded binaries
中,否则 FLEX 将包含在所有构建中(即,也包含在 Release
版本中)
相反地,将 $(PROJECT_DIR)/Carthage/Build/iOS
添加到你 Target 的 Framework Search Paths
中(如果你已经在 Carthage 中包含了其他 Framework,则此设置可能已经存在)。这使得从源文件中导入 FLEX 框架成为可能。为所有配置都添加此设置并没有什么坏处,但至少应该为调试配置添加它
向你的 Target 添加一个 Run Script Phase
(例如,在现有的 Link Binary with Libraries phase
之后将其插入),这仅会将 FLEX.framework
嵌入到调试版本中:
if [ "$CONFIGURATION" == "Debug" ]; then
/usr/local/bin/carthage copy-frameworks
fi
最后,添加 $(SRCROOT)/Carthage/Build/iOS/FLEX.framework
作为此 Run Script Phase
的输入文件
Swift Package Manager
在 Xcode 中,导航到 Build Settings
> Build Options
> Excluded Source File Names
。对于 Release
设置,将其设置为 FLEX.o
以排除所有带有 FLEX 前缀的文件:
FLEX files added manually to a project
在 Xcode 中,导航到 Build Settings
> Build Options
> Excluded Source File Names
。对于 Release
设置,将其设置为 FLEX*
以排除所有带有 FLEX 前缀的文件:
在 NSUserDefaults
中,如果值的类型为 id
,则 FLEX 会尝试将输入的字符串解析为 JSON
。这允许字符串(string
)、数字(number
)、数组(array
)、字典(dictionary
)的任意组合。如果要设置的值为字符串,则必须用引号扩起来。对于显式类型为 NSString
的成员变量或属性,不需要用引号
你可能希望在使用 FLEX 时禁用异常断点。FLEX 使用的某些函数在获取到无法处理的输入时会抛出异常(例如,NSGetSizeAndAlignment()
)。FLEX 会捕获这些异常以避免崩溃,如果 FLEX 的异常捕获处于活动状态而你又开启了异常断点,则你的异常断点将被命中
FLEX 建立在来自它之前的开源工具的想法和灵感之上。以下资源特别有用:
MirrorKit:一个围绕 Objective-C 运行时的 Objective-C 包装器
DCIntrospect:查看 iOS 模拟器的层级结构调试
PonyDebugger:使用 Chrome Developer Tools 界面进行网络(network)、核心数据(core data)、视图层级(view hierarchy)的调试
Mike Ash:关于 obj-c 和更多的内容都写得很好、内容丰富的博客文章。下面的链接对这个项目非常有用:
MAObjCRuntime
Let’s Build Key Value Coding
ARM64 and You
RHObjectiveBeagle:用于扫描堆空间以查找活动对象的工具。需要注意的是,由于许可问题,没有参考 RHObjectiveBeagle
的源代码
heap_find.cpp:枚举 malloc
块以在堆空间上查找对象的示例
来自 @samdmarshall 的 Gist:枚举 malloc
块的另一个示例
Non-pointer isa:对 iOS 上 ARM64 架构的 isa
字段更改的说明,并提及有用的 objc_debug_isa_class_mask
变量
GZIP:使用 libz
在 iOS 上压缩和解压缩数据的库
FMDB:这是一个围绕 SQLite 的 Objective-C 包装器
InAppViewDebugger:FLEX 4 的 3D 视图浏览器的灵感和参考实现,作者:@indragiek
贡献(Contributing)请参阅我们的 投稿指南
待做(TODO)Swift 运行时自省(Swift 类、堆空间上的 Swift 对象、等等)
动态添加新的 NSUserDefault
键值对
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)