May 22, 2015
During the time I've spent developing jailbreak tweaks for iOS, I've come across plenty of small things to make my workflow better and make development easier in general. This post is a collection of those, so other developers can benefit as well. Most are probably familiar to experienced developers, but there are new developers learning every day :) .
iPhoneDevWiki - A great place for information about tweak development. Lots of technical information and guides for things like setting up a basic development environment.
TheiPhoneWiki - More in-depth, technical information than the iPhoneDevWiki, mostly related to the process of jailbreaking.
/r/Jailbreak - The main jailbreak subreddit, probably the best place for general jailbreak news.
/r/JailbreakDevelopers - Subreddit for jailbreak tweak developers, a good place to find help for problems you encounter during development.
SharedInstance - Developer-oriented jailbreak blog
irc.saurik.com
- Saurik's IRC server, lots of developers hang around here and are available to help with problems or questions you may have.
Sublime-Logos - Syntax highlighting for Logos keywords in Sublime Text, by default in files with .x
or .xm
extensions.
SSH over USB - Allows SSHing into a device connected through USB rather than through WiFi. This speeds up the process of deploying a new build to a device and makes development smoother in general. It also eliminates the need to know your device's IP address, which is especially helpful on public WiFi networks. THEOS_DEVICE_IP must be set to localhost and THEOS_DEVICE_PORT must be set to the tunnel port (2222 by default). I have these set in my .bash_profile rather than project makefiles since they're the same for every project.
ssh-copy-id
- This one seems obvious to me now, but wasn't at all when I started developing. Copying the public SSH key from your computer to your phone allows you to log in through SSH without entering your password every time. This is convenient when using SSH normally, but it's a lifesaver when building and running tweaks on your device. Entering your password every single time you build and run gets really, really annoying. More information and instructions can be found here.
These variables can be entered in a project's makefile.
PACKAGE_VERSION - Makes a tweak's package version not show the build number at the end. For example, without this flag present your package version might show up as "1.4-1" in Cydia, for version 1.4 build 1. With PACKAGE_VERSION = 1.4
in your makefile it would instead show up as "1.4". Make sure PACKAGE_VERSION and the version number in your control file always match.
GO_EASY_ON_ME - Setting this flag to 1 will disable Theos treating warnings as errors. This is helpful for quick experimental tweaks or for the beginning of development, but is not recommended for finished tweaks (fix the warnings!).
THEOS_BUILD_DIR - Setting this flag to a folder name will put all of the tweak's intermediate build files and finished deb files in a single folder, instead of all in the main folder of your project.
Automatic Reference Counting (ARC) - If you would like to use ARC in a tweak rather than manual reference counting, you can set ADDITIONAL_OBJCFLAGS = -fobjc-arc
in your makefile. This may or may not be a good idea, iPhoneDevWiki has more information about it here.
class-dump/class-dump-z - Class-dump and class-dump-z are tools that can create pseudo-header files from Objective-C class information in compiled binaries. It's a great starting tool for reverse engineering an app to hook it, and quite often is the only tool needed. Class-dump generated headers for SpringBoard and all of the iOS public and private frameworks can easily be found online, for instance in this GitHub repo.
DumpDecrypted - All App Store apps are encrypted, which means they have to be decrypted for reverse engineering or class-dumping. DumpDecrypted is a quick and easy tool to decrypt encrypted iOS apps.
Deviceconsole - Lets you view the system log of an iOS device connected through USB on your computer. Useful for seeing what's happening on a device, including NSLog statements from your tweak.
Cycript - Cycript allows you to interact with running Objective-C programs using a simple Javascript syntax. It's super useful for exploring an app that you want to create a tweak for, because you can traverse the view hierarchy and test method calls right in the app itself.
Hopper Disassembler - Hopper is invaluable for reverse engineering. If you ever wonder specifically what happens within a SpringBoard method and can't guess from just the name, Hopper can help you find out. Although there are other disassemblers (like IDA) available, I think Hopper is the best looking and easiest to use (and most affordable). Aside from reverse engineering, I've found Hopper useful when getting unsymbolicated crash logs from users since they only list the offset in a tweak's binary that the crash happened at.
GDB/LLDB - I haven't used a debugger for fixing bugs in my tweaks before, but I find them useful for doing research into how different methods work within apps. The version of GDB hosted by Saurik doesn't work for me, although I was able to find an older version online that does. I would recommend setting up LLDB for remote debugging by following iPhoneDevWiki's instructions.
iOS Simulator - You can in fact run jailbreak tweaks in the iOS simulator. It takes a bit of work and probably isn't worth your time if you have a jailbroken device available, but if you don't then it could be very useful. I used it to mess around with tweaking iOS 7 before a public jailbreak was released.
Madrid = iMessage (iOS 5 only, now part of ChatKit) (iPhoneDevWiki)
Castle = iCloud (try running [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=CASTLE"]]
with cycript)
Victoria = Nike + iPod feature (TheiPhoneWiki)
If you want to force another tweak to load before yours, you can use dlopen
to force its dylib to be loaded first. For example, I use the line dlopen("/Library/MobileSubstrate/DynamicLibraries/SubtleLock.dylib", RTLD_NOW);
in Priority Hub's constructor to force SubtleLock to be loaded first, so that Priority Hub can have the final say in the layout of a few views. Normally dlopen
is used to load dynamic libraries so functions within them can be used, but forcing tweaks to load is another side effect/feature.
Message logging in tweaks - It can be useful to log information to the device's system log for debugging purposes. However, it can sometimes be annoying to have the logs in final versions of tweaks because they can fill the system log and make it hard for other developers to find their messages. One way to avoid this is to define a macro with your own log function. In Priority Hub, I named this PHLog, so I can call PHLog(@"Preparing for teardown!");
and it will be logged as PRIORITY HUB [Line 255]: Preparing for teardown!
. PHLog can be called identically to NSLog, including arguments and format specifiers. This is done by using the macro:
Inside in a Prefix.pch file and included in all project files by adding the line PriorityHub_CFLAGS = -include Prefix.pch
to the makefile. Then, I can comment out or uncomment the line DEBUG = 1
in the makefile to instantly enable or disable all print statements in Priority Hub.
Look at code for open source projects! There are tons of open source tweaks that can be found through Google or on iPhoneDevWiki's list of open source projects. If you're stuck on a problem, maybe someone has solved it before. I try to open source as many of my tweaks as possible so others can learn from them, you can check them out here.
Ask for help! There are plenty of good places to ask for help from other developers, like /r/JailbreakDevelopers or Saurik's IRC server or even by contacting other developers directly through Twitter or email. Even if you don't need help, you can learn a lot from hanging around and reading.
I hope this is helpful! Feel free to contact me if you have any questions or other items to add to the list.