When we debug iOS native code, each modification requires Command + R to re-compile and run. When the project is very large amount of code, compile time will be very long. So for development, if able to speed up the compilation speed, can greatly improve production efficiency. If we can be like Swift Playground, applets can modify the code or pages that come out like real-time feedback on the interface. However, geese, really have such Xcode plug-in, so you can modify the code immediately see the change in the simulator or a real machine, it is Injection for Xcode, which is the official demonstration effect:
installation
Alcatraz can, directly or GitHub clone the down and build InjectionPluginLite / InjectionPlugin.xcodeproj. The simplest is to the App Store to download and install. (First exit Note install Xcode, after the installation is complete, open Xcode, Xcode to ensure a smooth load plugins)
Instructions
- Run Injection, then make sure you check File Watcher
2. If you are using Xcode10.2 and above, directly open the project AppDelegate.m in didFinishLaunchingWithOptions: Add code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
#if DEBUG
// for iOS
[[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/iOSInjection10.bundle"] load];
// for tvOS
[[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/tvOSInjection10.bundle"] load];
// for masOS
[[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/macOSInjection10.bundle"] load];
#endif
return YES;
}
If it is swift:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
#if DEBUG
Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/iOSInjection10.bundle")?.load()
//for tvOS:
Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/tvOSInjection10.bundle")?.load()
//Or for macOS:
Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/macOSInjection10.bundle")?.load()
#endif
return true
}
- The last method to rewrite injected where needed to modify real-time monitoring, such as in the home of ViewController.m in:
- (void)injected{
NSLog(@“I’ve been injected: %@”, self);
}
effect
Now run the program, and adjust the UI related code, simulator, or the real machine will be displayed above the corresponding immediate effect. I recently did an iPad project, involving UI debugging more, this time the project will be able to efficiently debug it.
For example: The original picture is yaun.png:
I hit a breakpoint injected overridden method, and then the original yuan.png into yi.png:
[yuan setImage:[UIImage imageFileName:@"main_section_button_yuan.png"] forState:0];
Changed
[yuan setImage:[UIImage imageFileName:@"main_section_button_yi.png"] forState:0];
After modification and Command + s save, this time we will stop to the top of the breakpoint:
Skip breakpoints, we see the interface has been updated:
principle
Changes in Xcode end, Injection monitor source code, if there are changes, the corresponding category will Injection packaged into recompiling a dynamic library, i.e. .dylib file and notifies App through Socket. App after receiving the message, the dynamic loading, this time there will be change the class of the old and new versions of two, and then use the runtime dynamic replacement method, replacing the old with the new class type, so as to achieve without having to recompile and run the update App.
reference
- injectionforxcode official: https://github.com/johnno1962/injectionforxcode
- https://www.cnblogs.com/li-wei203/p/9851860.html
- Dai Ming's iOS development master class "How to achieve App Speed compiled by injecting a DLL tune the way
the test? "