For the entirety of this guide we'll assume your project's name is libfoo.
To follow this tutorial exactly, you will need:
- Xcode 11.4 beta (
sudo xcode-select -s /Applications/Xcode-beta.app); - Simject installed according to its readme; and
- an example AutoHook project set up and ready to go in Xcode.
-
Set your project's scheme to libfoo and target an iPhone simulator.
-
Build once with
cmd+B. -
Open Terminal and enter
cd ~/Library/Developer/Xcode/DerivedData. Depending on your shell and its configuration you can either press the TAB key or enter the commandls -lato get a list of directories. Find a directory named something likelibfoo-qwertyuiopasdfghjklandcdinto it. -
Continue down the directory tree by
cding intoBuild/Products/Debug-iphonesimulator. If you don't seeDebug-iphonesimulatorthen you did not complete step 2. If you only seeDebug-iphoneosthen your scheme was targeted to an actual iOS device or the generic iOS device. Either way, go back to step 2. -
Run
lsto list the directory's files and ensure there is a file namedlibfoo.a. -
Run clang:
xcrun --sdk iphonesimulator13.4 clang -arch x86_64 -shared -all_load libfoo.a -o libfoo.dylib -
Run
lsagain and verify that a new file namedlibfoo.dylibhas appeared. -
Copy the dylib to simject with
cp libfoo.dylib /opt/simject. -
Sign the library with
codesign -f -s - /opt/simject/libfoo.dylib -
Next we have to create a bundle plist. Run
/usr/libexec/plistbuddy libfoo.plist. The output should look something like this (where the_indicates your cursor):❯ /usr/libexec/plistbuddy libtestobjagain.plist File Doesn't Exist, Will Create: libtestobjagain.plist Command: _ -
Type
add :Filter dictand hit enter. Check to see if the dictionary was added correctly by typingprintand hitting enter. The output should look like:Command: print Dict { Filter = Dict { } } -
Run
add :Filter:Bundles array, followed byadd :Filter:Bundles: string com.apple.springboard. Finally, runprintagain to check your work:Command: print Dict { Filter = Dict { Bundles = Array { com.apple.springboard } } } -
If you're satisfied, run
saveand thenctrl+cto exit. DON'T FORGET TO SAVE! -
Copy your plist to simject by running
cp libfoo.plist /opt/simject. You should also take this opportunity to copy it to your project directory. -
Run resim! For me, that's
~/git/simject/bin/resim. The exact path depends on where you cloned the simject repository.
Phew, that was a lot, right? Thankfully this process can now be automated. Of course it's possible to automate the steps from the start, but I think it's important to grapple with the nitty-gritty so you better understand what we're doing and why we're doing it.
-
Choose "New Run Script Phase".
-
Copy and paste the following script into the text field. Don't forget to change the path in the first line and the
libfoos to match your project.cd ~/Library/Developer/Xcode/DerivedData/libfoo-qwertyuiop/Build/Products/Debug-iphonesimulator xcrun --sdk iphonesimulator13.4 clang -arch x86_64 -shared -all_load libfoo.a -o libfoo.dylib cp libfoo.dylib /opt/simject codesign -f -s - /opt/simject/libfoo.dylib ~/git/simject/bin/resim -
Now whenever you build with Xcode, this script will take care of all the heavy lifting and respring any active simulators.
Happy devving!



