@@ -8,36 +8,46 @@ app without having to relaunch it. This can save a developer a significant
8
8
amount of time tweaking code or iterating over a design.
9
9
10
10
This repo is a refresh of the [ InjectionIII] ( https://github.com/johnno1962/InjectionIII )
11
- app that uses a different technique to determine how to rebuild source files
12
- that should be faster and more reliable for very large projects. Gone is the
13
- involved parsing of Xcode build logs (if you can locate them) and messy
14
- escaping of special characters in filenames. A new app is used to launch Xcode
15
- with a [ SourceKit debugging flag] ( https://www.jpsim.com/uncovering-sourcekit/ )
16
- enabled which provides all the information you need to be able to recompile
17
- files and then the runtime implementation of injection included in the
18
- [ InjectionLite] ( https://github.com/johnno1962/InjectionLite ) package looks after the rest.
11
+ app that uses different techniques to determine how to rebuild source files
12
+ that should be faster and more reliable for very large projects. With versions
13
+ 1.3.0+ the only changes that are required to your project are to add the
14
+ following "Other Linker Flags" to your project's ** Debug** build settings:
19
15
16
+ ![ Icon] ( App/interposable.png )
17
+
18
+ That last flag is to link what were bundles in InjectionIII as a dynamic library:
19
+
20
+ ` /Applications/InjectionNext.app/Contents/Resources/lib$(PLATFORM_NAME)Injection.dylib `
21
+
22
+ If you want to inject on a device you'll also need to add the following
23
+ as a "Run Script/Build Phase" of your main target to copy the required
24
+ libraries into your app bundle (for a Debug build) and toggle "Enable Devices"
25
+ to open a network port for incoming connections from your client app.
26
+
27
+ ```
28
+ export RESOURCES="/Applications/InjectionNext.app/Contents/Resources"
29
+ if [ -f "$RESOURCES/copy_bundle.sh" ]; then
30
+ "$RESOURCES/copy_bundle.sh"
31
+ fi
32
+ ```
20
33
The basic MO is to build the app in the ` App ` directory, or download one of
21
34
the binary releases in this repo, move it /Applications, quit Xcode and run the
22
35
resulting ` InjectionNext.app ` and use that to re-launch Xcode using the menu item
23
- ` Launch Xcode ` from the status bar. You then add this repo as a Swift package
24
- dependency of your project and that should be all that is required for injection
25
- in the simulator, injection on devices and injection of a MacOS app. No more
26
- code changes required to load binary code bundles etc and you can leave
27
- the InjectionNext package configured into your project permanently as
28
- its code is only included for a DEBUG build. Your code changes take effect
36
+ ` Launch Xcode ` from the status bar. No more code changes required to load binary
37
+ code bundles etc. Your code changes take effect
29
38
when you save a source for an app that has this package as a dependency
30
- and has connected to the InjectIonNext app which has launched Xcode.
39
+ and has connected to the InjectionNext app which has launched Xcode.
40
+
41
+ ** Please note:** you can only inject changes to code inside a function body
42
+ and you can not add/remove or rename properties with storage or add or
43
+ reorder methods in a non final class or change function signatures.
31
44
32
- As ever, it is important to add the options ` -Xlinker ` and ` -interposable `
33
- (without double quotes and on separate lines) to the "Other Linker Flags" of
34
- the targets of your project (for the ` Debug ` configuration only) to enable
35
- "interposing". Otherwise, you will only be able to inject non-final class methods.
36
45
To inject SwiftUI sucessfully a couple of minor code changes to each View are
37
46
required. Consult the https://github.com/johnno1962/HotSwiftUI README or you
38
47
can make these changes automatically using the menu item "Prepare SwiftUI/".
39
-
40
- ![ Icon] ( App/interposable.png )
48
+ For SwiftUI you would also generally also integrate either the
49
+ [ Inject] ( https://github.com/krzysztofzablocki/Inject ) or
50
+ [ HotSwiftUI] ( https://github.com/johnno1962/HotSwiftUI ) package into your project.
41
51
42
52
When your app runs it should connect to the ` InjectionNext.app ` and it's icon
43
53
change to orange. After that, by parsing the messages from the "supervised"
@@ -50,67 +60,54 @@ phase of your build logs in the window that pops up. Sometimes a
50
60
device will not connect to the app first time after unlocking it.
51
61
If at first it doesn't succeed, try again.
52
62
53
- If you'd rather not be adding a SPM dependency to your project, the app's
54
- resources contains pre-built bundles which you can copy into your app during
55
- the build by using a "Run Script/Build Phase" (while disabling the "user
56
- script sandboxing" build setting) such as the following:
63
+ The colours of the menu bar icon bar correspond to:
57
64
58
- ```
59
- export RESOURCES="/Applications/InjectionNext.app/Contents/Resources"
60
- if [ -f "$RESOURCES/copy_bundle.sh" ]; then
61
- "$RESOURCES/copy_bundle.sh"
62
- fi
63
- ```
64
- These bundles should load automatically if you've integrated the
65
- [ Inject] ( https://github.com/krzysztofzablocki/Inject ) or
66
- [ HotSwiftUI] ( https://github.com/johnno1962/HotSwiftUI ) packages into your project.
67
- Otherwise, you can add the following code to run on startup of your app:
65
+ * Blue when you first run the InjectionNext app.
66
+ * Purple when you have launched Xcode using the app.
67
+ * Orange when your client app has connected to it.
68
+ * Green while it is recompiling a saved source.
69
+ * Yellow if the source has failed to compile.
68
70
69
- ```
70
- #if DEBUG
71
- if let path = Bundle.main.path(forResource:
72
- "iOSInjection", ofType: "bundle") ??
73
- Bundle.main.path(forResource:
74
- "macOSInjection", ofType: "bundle") {
75
- Bundle(path: path)!.load()
76
- }
77
- #endif
78
- ```
79
- The binary bundles also integrate [ Nimble] ( https://github.com/Quick/Nimble )
71
+ The binary dylibs also integrate [ Nimble] ( https://github.com/Quick/Nimble )
80
72
and a slightly modified version of the [ Quick] ( https://github.com/Quick/Quick )
81
73
testing framework to inhibit spec caching under their respective Apache licences.
82
74
83
- To inject tests on a device: use these bundles and, when enabling the
84
- "Enable Devices" menu item select "Enable testing on device" which
85
- will add the parameters shown to the link of each dynamic library.
86
- As you do this, the above command will be inserted into the clipboard
75
+ To inject tests on a device: when enabling the
76
+ "Enable Devices" menu item, select "Enable testing on device" which
77
+ will add the arguments shown to the link of each dynamic library.
78
+ As you do this, the command above will be inserted into the clipboard
87
79
which you should add to your project as a "Run Script" "Build Phase"
88
- to copy the required libraries into the app bundle.
80
+ of the main target to copy the required libraries into the app bundle.
89
81
90
82
### Cursor/VSCode mode.
91
83
92
84
If you would like to use InjectionNext with the Cursor code editor,
93
85
you can have it fall back to InjectionIII-style log parsing using
94
86
the "...or Watch Project" menu item to select the project root
95
- you will be working under. In this case you shouldn't launch
87
+ you will be working under (or use the new "Proxy" mode below
88
+ for Swift projects.) In this case, you shouldn't launch
96
89
Xcode from inside the InjectionNext.app but you'll need to have
97
90
built your app in Xcode at some point in the past for the logs
98
91
to be available. You should build using the same version as that
99
92
selected by ` xcode-select ` .
100
93
101
- ### Compiler "proxy" mode.
94
+ ### New compiler "proxy" mode.
102
95
103
- It is also possible to intercept swift compilation commands as a proof of
104
- concept in case at some point in the future these are no longer captured in
96
+ It is also possible to intercept swift compilation commands as a new proof of
97
+ concept for when at some point in the future these are no longer captured in
105
98
the Xcode logs (as was the case with Xcode 16.3 beta1). In this case, select
106
99
"Intercept compiler" to patch the current toolchain slightly to capture all
107
100
compilations using a script and send them to the InjectionNext.app. Once this
108
101
patch has been applied you don't need to launch Xcode from the app and you can
109
- inject by starting a file watcher using the "...or Watch Project" menu item.
102
+ inject by starting a file watcher using the "...or Watch Project" menu item
103
+ (though this should happen automatically when you recompile Swift sources).
110
104
105
+ So, InjectionNext has three ways in which it can operate of which the newest and
106
+ the simplest one if you're prepared to patch your toolchain is the "proxy" mode.
111
107
The original mode of operation launching Xcode inside the app takes preference
112
- otherwise, if you have selected a file watcher and are intercepting the compiler
113
- commands that is next in line followed by the log parsing fallback which
108
+ and, if you have selected a file watcher and are intercepting the compiler
109
+ commands that is the next preference followed by the log parsing fallback using
110
+ the [ InjectionLite] ( https://github.com/johnno1962/InjectionLite ) package which
114
111
essentially works as InjectionIII did when the logs are available.
115
112
116
113
For more information consult the [ original InjectionIII README] ( https://github.com/johnno1962/InjectionIII )
@@ -124,16 +121,4 @@ your project in Xcode automatically using the -projectPath option.
124
121
Set a user default with the same name if you want to always open
125
122
this project inside the selected Xcode on launching the app.
126
123
127
- The colours of the menu bar icon bar correspond to:
128
-
129
- * Blue when you first run the InjectionNext app.
130
- * Purple when you have launched Xcode using the app.
131
- * Orange when your client app has connected to it.
132
- * Green while it is recompiling a saved source.
133
- * Yellow if the source has failed to compile.
134
-
135
- Please note: you can only inject changes to code inside a function body
136
- and you can not add/remove or rename properties with storage or add or
137
- reorder methods in a non final class or change function signatures.
138
-
139
124
The fabulous app icon is thanks to Katya of [ pixel-mixer.com] ( http://pixel-mixer.com/ ) .
0 commit comments