Injection是支持OC和Swift的UI热重载工具,采取在模拟器(只支持模拟器)注入的方式实现UI热重载,修改完UI直接com+s,不用重新编译运行就能看到UI效果。
使用方法
-
github下载最新release版本,目前已经支持Xcode13和iOS15系统。
-
安装后,打开InjectionIII,选择Open Project,选择你的项目目录。
-
选择的项目会在OPen Recent中展示,同时保持File Watcher的选项勾选
-
AppDelegate配置,在
didFinishLaunchingWithOptions配置注入。
OC版本
#if DEBUG
// iOS
[[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/iOSInjection.bundle"] load];
#endif
Swift版本
#if DEBUG
do{
let injectionBundle = Bundle.init(path: "/Applications/InjectionIII.app/Contents/Resources/iOSInjection.bundle")
if let bundle = injectionBundle{
try bundle.loadAndReturnError()
}else{
debugPrint("Injection注入失败,未能检测到Injection")
}
}catch{
debugPrint("Injection注入失败(error)")
}
#endif
注意:先打开InjectionIII的Resources路径,确认 iOSInjection.bundle 文件的正确路径。
- 注入页面文件配置
- 在需要热重载的控制器中(可以考虑BaseVC),实现
injected方法,并将操作UI的方法添加到injected即可。修改完UI,直接cmd+s就能看到效果。
- (void)injected {
#if DEBUG
DLog(@"I've been injected: %@", self);
[self viewDidLoad];
#endif
}
- 如果使用以上方式在页面注入没有效果,则可以删除
injected方法,在需要热重载的控制器添加通知INJECTION_BUNDLE_NOTIFICATION即可。
- (instancetype)init {
if (self = [super init]) {
[[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(hotReloadingUI) name:@"INJECTION_BUNDLE_NOTIFICATION" object:nil];
}
return self;
}
- (void)hotReloadingUI {
#if DEBUG
DLog(@"I've been injected: %@", self);
[self viewDidLoad];
#endif
}
-
cmd+s,快速的开发吧!
-
更多项目设置,请参考作者维护的wiki:github.com/johnno1962/…
可能遇到的问题
-
项目路径如果在Desktop或者Documents文件夹中,会报警告,目前不影响使用。
Your project file seems to be in the Desktop or Documents folder and may prevent InjectionIII working as it has special permissions. -
热重载时,
hotReloadingUI方法被调用多次监听
INJECTION_BUNDLE_NOTIFICATION通知的方法不能放在viewDidLoad方法里。原因,在热重载时,viewDidLoad会被调用多次。 -
视图被多次添加问题
- (void)viewDidLoad { [super viewDidLoad]; UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 100, 100, 100)]; view.backgroundColor = UIColor.blueColor; [self.view addSubview:view]; }由于
viewDidLoad方法在热重载时会再次被调用,所以如果不是通过懒加载创建的视图,会导致视图被添加多次。解决方法(个人观点):如果是像首页这样的主页面,可以在添加视图之前做一次判断;如果是子页面,可以不用管,当视图层级过多时,可以返回让控制器出栈再重新push入栈。
注:“Every time the injected function runs, we’re going to remove all the subviews in the main view of the UIViewController. This should clear the screen in most cases.”,这是在文档中看到的作者写的原文,目前发现子视图并没有移除,正在向作者提问。
- 在使用webView的页面闪退,无法复现
- 会员产品发车页使用闪退
更多功能
-
Add Directory
如果项目是跨多个目录的,或者项目文件不在源代码的根目录中,可以使用“添加目录”菜单项添加其他目录来监视文件更改。当选择一个新项目时,此列表将重置。
-
File Watcher
- 启用,通过 cmd+s 进行热重载
- 禁用,可以手动启用热重载,首先 cmd+s,然后 ctrl-=
-
Enable Vaccine
-
Prepare Project
可以配合在SwiftUI中注入时使用
-
Method Tracing
用来做方法跟踪的,会记录每一个方法的调用。具体实现在
Injection.bundle -> Frameworks -> SwiftTrace.framework中 -
Remote Control
可以在开发过程中从 Mac 上的窗口控制 iPhone