For Feedback or Requests DM Me On Twitter @litteeen
For Feedback or Requests DM Me On Twitter @litteeen
Section 1: Introduction
In section 1.1 I’ll show you how to install and set up theos which we’ll need to make Tweaks
In section 2 I’ll show you how to create your first project with theos
In section 3 I’ll give you some advice about an IDE to use for the coding part
In section 4 I’ll show you what each file does and what needs to be changedSection: 4.1:
Modifying Our Control FileSection 4.2: Modifying The Makefile
In Section 5 I’ll teach you how to create your first little tweak by also explaining every step
In section 6 I’ll talk about layoutSubviews and how you could use them in a tweak
In section 7 we’re going to add more options to our haptics tweak as well as preferences (cephei)
In section 7 we’re going to make a tweak to color the connectivity toggles with a colorpicker
Side Section: Creating Your Own Repo To Host Tweaks And Apps
In the side section I’ll show you how to create your own repo (two ways) where you can upload
tweaks and apps
Sooo.. the big question of everyone who wants to develop their own
tweaks is “How would I go on doing that?” Or “Where can I learn it?”. The
answer is, the internet, there are so many places to learn different kinds
of things like Udemy for Video courses, for example Objective-C which is
needed to develop tweaks. So now that you know you’ll need objective c,
you should also keep in mind to look at open source tweaks, to get to
know the syntax and way they’re built. The things we’re going to make
are also downloadable here: https://github.com/Litteeen/guideTweaks
I AM GOING TO EXPLAIN WHAT YOU’LL NEED THE BEST WAY I CAN, SO LET’S GET INTO IT ^^
YOU CAN ALWAYS ACCESS THIS SITE BUT ALSO FEEL FREE TO DOWNLOAD IT
We will firstly take a look at how to create a tweak template with the theos environment, so just
open your Terminal and type $THEOS/bin/nic.pl
(quick explanation of that command: theos was installed to your home directory and it has also
set up an environment variable to access it quickly, the ‘$’ points to the theos installation directory
and after just the way down to the file called 'nic.pl')
Steps:
2) Make sure your terminal profile is bash and not zsh (find out by typing echo $SHELL in
terminal, and if the current one is zsh type chsh -s /bin/bash to change it to bash)
1) Install homebrew if you haven’t installed it yet (homebrew lets you install all different kinds of
packages that apple didn’t include) by putting in this: /usr/bin/ruby -e "$(curl -fsSL https://
raw.githubusercontent.com/Homebrew/install/master/install)”
Now type echo $THEOS, if the output is a path continue to step 4, but if nothing appears for the
output type echo "export THEOS=~/theos" >> ~/.zprofile (that probably only happen on macOS
10.14 because of the zsh shell)
5) For the last step we need to get some sdks to compile, cd into your theos directory and then
into the sdks directory, then type git clone https://github.com/theos/sdks.git
6) type open sdks/ and drag these three folders to the previous one so that they’re in the main
sdks folder
To get iOS 13 sdks copy the iPhoneOS.sdk folder and the iPhoneOS13.2 shortcut from Xcode/
Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/ to the theos sdks folder
- Secondly it asks us to give the Project (Tweak,..) a name, I’ll call this example
“FeelTheAudio” (maybe you can guess what we’re going to create)
- Thirdly we’ll need to give it a bundle identifier, I’ll call mine sh.litten.feeltheaudio because of my
domain
- The last step is to tell theos what the tweak will target, I will write down com.apple.UIKit but you
can also leave the default in and just press return on your keyboard
Now we’ve set up our tweak directory successfully and it’s located in your home directory but you
can just type open tweakName (for me feeltheaudio) in terminal and it will open a finder window
located at your tweak
Section 3 - Installing Our IDE
If you prefer to use another IDE just jump to Section 4 but we’ll set up VS Code in this section
Optionally you can install the Terminal extension for it to make it easier to open projects
This will give you the ability to just type code . or code Tweak.x in terminal to directly open the
whole project or file with VS Code from Terminal
To do that open Code and press F1 on your keyboard or Touch Bar, and type shell command
Now click on “install code command at PATH” and restart your shell/Terminal to reload the profiles
When you open your terminal again cd into your tweak folder and just type code . and it will
automatically open the Project with Code
At first check and if needed modify your control file, I will also put in my email and add a new
dependency
Here you will also change the description and other things like conflicts
If you add your email like I did the user will be able to directly contact you by email if they tap on
the Author’s name
Section 4.2 - Modifying The Makefile
I recommend you to make your Makefile look like mine
THINGS I ADDED:
ARCHS tells theos to compile for the given architectures like arm64 for non A12 64bit devices and
arm64e for A12 devices
TARGET tells theos which SDK should be used for compiling, I will always use the latest sdk I
have to have the newest features
$(TWEAK_NAME)_FRAMEWORKS defines which frameworks will be used, you will mostly work
with the UIKit so always add it (you don’t need to add it, because it’s being added automatically
but I always do it anyway)
I also changed FeelTheAudio_Files to $(TWEAK_NAME) to not have to always write the name of
the tweak, some basic bash thing
CFLAGS is for
memory
management, don’t
remove it
That doesn’t
mean you're not
allowed to do it
like I do, and I
won’t change my
way of doing it
Section 5 - Creating Our First Tweak
In this section we’re going to make our tweak do something so jump into the tweak.x file to get
started
As we use the UIKit import it by adding #import <UIKit/UIKit.h>, that’s how you import
frameworks, to add local headers of the tweak just do it like this: #import “fileName.h” but I’ll do it
within one file in this guide to keep it simple
The best way to find methods or classes is to use Limneos’s header website to discover iOS
headers and methods https://developer.limneos.net
So now click on the link or open that website because I’ll show you how to find what we’re going
to need
We’re looking for a header so we don’t tick the “Methods Search” box
Put SBVolumeControl in the search bar and it will find the header for you, then click on it
SBVolumeControl is only available on iOS 13 so the tweak won’t work on iOS 12 or lower, to fix
that do the same what we’re doing next but hook VolumeControl as well, VolumeControl uses the
same methods so just copy the next steps (also don’t forget to update the necessary firmware
version if using)
This is how it will look like, here we can view all properties and methods of that specific class but
we will only need these two:
To hook a class means as much as grabbing a basket with apples in it and then adding or
removing some of them
It’s the same with our code, we hook/grab the class and instead of modifying the amount of
apples we’re going to modify the code functionality
Now that we hooked the class, we’re going to change the functionality of the increaseVolume and
decreaseVolume methods
We do it like this:
It’s important to know that when we modify a method we want it to continue executing
the original code by Apple so add %orig; to make it do that
What if we don’t add it? Pretty simple, if we don’t add it do our volume method we won’t be able
to change the volume with our buttons anymore until we update or uninstall the tweak because
Apple’s code doesn’t get executed anymore
At this point we can add our haptic feedback as we got everything else set up
To make use of our Haptic/Taptic Engine we need to import another framework in our tweak.x and
makefile
To actually make out phones vibrate we’ll use the AudioServicesPlaySystemSound method which
is part of the AudioServices.h we just imported
Alternatively you could type make package install to directly install it on your phone, but you’d
need to add a new variable to the makefile to be able to do so
Add this to the makefile to use make package install: THEOS_DEVICE_IP = yourPhonesIP
Now just open the new folder which got generated and airdrop (or send it somehow else like
make package install) to yourself and install it with Filza or Zebra and respring
We will come back to the haptic volume tweak later on to add more reliable haptics as well as
preferences (cephei used), but now we’re looking at some new method with a new tweak we’ll
create ^^
Basically the layout subviews is/are the view or look of something, let me give you an example:
The UISwitch (known for our lovely switches) has of course also a method called layoutSubviews
like every iOS element, if you would modify the layoutSubviews without calling the %orig, the
switch would basically be gone, because the look, view simply doesn't exist so to say
And what we’re going to create now is to color the UISwitch’s on state color (the color when you
turn on a switch)
-———————————————————————————————————————————
First step is to set up a new theos project, as always give it a name, identifier, etc and apply the
same steps we did for the control and makefile (again we are targeting the UIKit so make sure to
have com.apple.UIKit instead of com.apple.springboard in the plist)
If you didn’t know it yet, - (void) is how a method is being declared in objective c, a void returns
nothing
A UISwitch has a method called setOnTintColor, we can easily call it within the layoutSubviews
because the layoutSubviews are being called very often
We will do that for the UISwitch now, [self setOnTintColor] but as the setOnTintColor wants us to
also specify a value well need to do it like this: [self setOnTintColor: [UIColor redColor]];
We use self because we assign the color to the object we’re targeting itself
You can also use RGBA color like this: [UIColor colorWithRed:1.00 green:0.80 blue:1.00
alpha:1.0]; which would a light pink
Another very simple but cool little tweak ^-^
Again, install the deb and respring and you will see the changes 🤗
Section 7 - Extension For Our Haptic Volume Tweak
Coming next
Section 8 - A Tweak To Color The Connectivity Toggles
iOS 13 only
In this section we’re going to make a new tweak that lets you color the connectivity toggles of
your control center with colorpickers
Okey then go ahead and create a new theos project to get started (target is com.apple.UIKit)
Now we’re going to make our tweak’s project folder look a lot better, this is how it’s going to look:
Basically create a folder in the project folder named Tweak (or whatever) and drag the .plist,
makefile and .x/.xm file in there
Then copy the makefile and paste it in the main folder and make it look like this:
The SUBPROJECTS line just tells that theos should look in the Tweak folder (or how you named it)
for another makefile which gives theos new instructions, means it tells to compile and how
Leave the control file in the main directory as dpkg will need it to make a Debian package out of it
Now open your project with code so that we can get started
Now we’re going to create a new file, a header file where we’ll store our interfaces and variables,
we do that because it’s more readable if not everything is put into the .x file
Just right click and then “New File” and call it yourTweakName.h (for me Aestea.h) but you can
call it whatever you want
Now we’re going to import the header file in the .x file so we can use the interfaces and variables
we’ll declare in the header file in the main file
Now make sure to have any Flex tool installed on you jailbroken device so that I can show you
where to find all the things we need
After holding the status bar for a short amount of time you should be able to see the flex toolbar
After opening flex open the control center and tap the select button on the toolbar, after that
select one of the toggles (i tapped the wifi as you can see)
Then tap “views” on the toolbar to get a list of all visible views
If you scroll a little bit up you should see CCUIRoundButton which is exactly what we need
because those toggles are an instance of CCUIRoundButton
Now that we know that we’ll need to hook the CCUIRoundButton to modify it let’s firstly take a
look of all the methods and properties on https://developer.limneos.net
You can directly see that it’s from the framework “ControlCenterUIKit”
We can also see that CCUIRoundButton is an instance of the UIControl class, that’s important to
know because we’ll need to add it as an interface then
Now we’re ready to start with the tweak itself, so open your .x file
And as we want to change the look of it we’ll use the layoutSubviews method (you should also be
able to use the didMoveToWindow method, also don’t forget the %orig)
We also figured out that the selectedStateBackgroundView may be the view we need to modify,
but do modify a property of something we need to create an interface for it (we do that in our
header file)
@end
After the “:” we set the class type, we saw its type earlier on Limneos’s website
to add the property just copy it from the website or type it yourself
@end
I just removed two spaces from the property declaration because it looks better to me like that
Now we can reference to it with self, let me show you what I mean:
As the property is an UIView it has a property called backgroundColor which we can access
without adding an interface, we can freely set it to our color now
If you compile this and install it to your device you’ll see that all toggles will be red when they’re
toggled on
Now there’s the question, how can we color each toggle?
Anyway, if you open flex again and scroll back to the CCUIRoundButton and tap the “i” you will
see a cell that says “View Controller for Ancestor”
Below that you can see <CCUIConnectivityWifiViewController..> of which we want to check the
existence
I figured out a way to do that by adding some mysterious id that we can use as an initialiser for
later
I created the UIViewController (i named it ancestor) in the header file and now we’re going to
initialise it with the ancestor
To do that we make an if statement and verify that the current view is from the class
CCUIConnectivityWifiViewController
Now if the view is kind of CCUIConnectivityWifiViewController we can change the color of only
that view with self.selectedStateBackgroundView.backgroundColor = [UIColor redColor];
Now let’s do this for all toggles (the classes can be found with flex like before)
If you compile that again as well as installing it you will see that all toggles will be colored again
Now we’re going to add preferences so we can change the color individually, first step is to add a
new line to our makefile as we’re going to use cephei for our preferences
$(TWEAK_NAME)_EXTRA_FRAMEWORKS += Cephei
Now we need to import cephei so that we can use it, add #import <Cephei/HBPreferences.h> to
your header file
Also open the makefile in the main directory because we’ll add a new folder for the prefs and we
need to specify the subproject
https:litten.sh/OwO/Prefs.zip
Download and extract the zip file into the main directory of the tweak so it looks like this:
First step is to give the AppearanceSettings.m and RootListController.m/.h a little unique identifier
Rename these to have the same name as you just renamed the files
Optionally you can remove this if you want the large headers:
- (NSUInteger)largeTitleStyle {
return 2;
Same here make these two have the same names as given
There are more things to change in the RootListController.m so let’s start with the same concept
At line 22 replace “TweakName” with your tweak’s name
At line 29 add your unique tweak identifier in front of Prefs.bundle (example: AESPrefs.bundle)
Same at line 63
At line 126 you can change the respring alert including your tweak’s name at line 127
Also if you want to change the colors in the preferences get a HEX number of your choice and
visit https://www.uicolor.xyz/#/hex-to-ui to quickly get the objective-c color and replace the
existing one at line 88 in the RootListController.m and in the AppearanceSettings.m
Change “Prefs” at Line 8 to the same as you had for the .bundle before, for me AESPrefs
Then also make line 12 have the same name as the file again
Make sure to have the iOS 11.2 sdks in your theos sdks folder to be able to compile it, it needs a
patched one because of the PrivateFrameworks
Then open the Resources folder and select the info.plist as this is the last file we have to modify
Line 10 should be the tweak’s bundle identifier (you can find it in the control file at line 1) + the
preferences name you just entered in the makefile, for me sh.litten.aesteapreferences
Line 9 and 10 tell the preferences that this dictionary (dict) is an UISwitch as the cell type is
PSSwitchCell
11 and 12 tell if the switch is toggled on or off by default, <true/> for enabled and <false/> for
disabled
13 and 14 tell the switch where to save the key (where to save the state), the save file is your plist,
but make sure to give it the correct name again
15 and 16 specify the key for the switch, the key is used ti gather information of the element (if the
switch is on or off for example)
19 and 20 reload the preferences in the background, make sure to change the name again
Now we’re getting to the exciting part, registering the enabled switch to detect if the tweak is
enabled or disabled, and if it’s disabled it should not color the toggled
At first we’ll put the %hook to a group, I’ll explain later why we do it, so just type %group with
your tweak’s name above %hook and another %end at the end to close the group
For each switch we need a bool to save the state of course, so add a new bool to your header file,
for the enabled switch I recommend to just call it enabled as it’s easy to remember
The next step is to add this to the bottom of your .x file, just copy and paste it
%ctor {
if (enabled) {
%init(Aestea);
Basically you register your elements in the ctor and if the enabled switch is YES it should initialise
all the code, means the tweak works
Otherwise if the switch returns NO/is disabled the ctor does not initialise the group, means the
tweak doesn’t work
The third line registers the enabled bool and connects it with the Enabled key we set before in the
Root.plist, this is how the bool get the current state of the switch
If the enabled switch is YES (switch is enabled) it should color the toggles, otherwise not
If you compile and install again you’ll see a preference bundle in your settings including one
switch and a preset icon and banner (you’re not allowed to use that)
Now let’s implement the colorpicker, we’re going to use the libsparkcolourpicker by @SparkDev_
You’ll need to install it first if you haven’t yet, just follow the README
https://github.com/SparkDev97/libSparkColourPicker
<dict>
<key>cell</key>
<string>PSLinkCell</string>
<key>cellClass</key>
<string>SparkColourPickerCell</string>
<key>libsparkcolourpicker</key>
<dict>
<key>defaults</key>
<string>sh.litten.preferences</string>
<key>key</key>
<string>color</string>
<key>fallback</key>
<string>#147efb</string>
<key>alpha</key>
<false/>
</dict>
<key>label</key>
<string>Coloring</string>
<key>key</key>
<string>color</string>
<key>PostNotification</key>
<string>sh.litten.preferences/ReloadPrefs</string>
</dict>
There are only a few new things, like the second dictionary in the dictionary
Basically the second dict has the selected color and fallback color, the fallback color is the color
that will be used if the user didn’t change anything
The first and second key can have the same name like mine do
I gave each one its own key with just the name + Color (example: airplaneColor) and the fallback
color is default iOS blue
Now jump to the header file as we’ll need to import the sparkcolorpicker and create some
variables
#import “SparkColourPickerUtils.h"
We need a variables for each picker to store the color HEX value of the picker
Create NSStrings which contain the fallback value (default blue still)
Now register them in the ctor, make sure to write registerObject instead of registerBool as a
NSString isn’t a Bool
Now that we registered everything successfully we can give the toggles their coolers c:
This line directs to the preferences file (change the name again) which we’ll need now
The last step is to create an UIColor, get the color from the colorpicker and apply it
We created some variables before because we need to store the picker values somewhere
Now we can get the color from a specific key, we store it in the colorString variable and pass it
over to the newly created UIColor which gets the color from it and has the fallback color we set
At the very last we apply this UIColor as the backgroundColor for the view
Notice:
If you use cephei for preferences and if your tweak targets UIKit add this to your ctor because it
prevents respring issues (cephei can’t hook system processes and this code block prevents it
from loading before springboard launched)
// https://www.reddit.com/r/jailbreak/comments/4yz5v5/
questionremote_messages_not_enabling/d6rlh88/
if (count != 0) {
if (executablePath) {
|| [processName isEqualToString:@"CoreAuthUI"]
|| [processName isEqualToString:@"InCallService"]
|| [processName isEqualToString:@"MessagesNotificationViewService"]
shouldLoad = YES;
if (!shouldLoad) return;
For the icon (called CydiaIcon.png, it must be named like this) you can use any image, optionally
you can copy paste that image two times so you got it three times, then just rename the second
one to [email protected] and the third one to [email protected], that’s for resizing on different
screen sizes
Just open the release file with any text editor and change the origin, label and description to fit
your information
Now we’re almost done, just drag and drop your Tweak (.deb) into the debs folder
Then open a terminal, cd into your repo directory and type ./scan-packages.sh which will
automatically generate all information and hashes about the deb file and store it in the Packages
file with the provided script Now go ahead, upload your repo (next pt/s) and try it out 🤗
But what if you want to host an app like an IPA? It’s easy:
Get your IPA and rename it to .zip (basically just extract it) and copy .app from it
Now that you got the .app create a new folder with the
name of the app, navigate into it and create two folders, one
called DEBIAN and one called Applications, the .app file
belongs to the Applications folder
Then copy the control file of one of your tweaks and paste it
into the DEBIAN folder and again edit the information in the
control file
It’s easiest to use Github Desktop (install Github Desktop before continuing)
Now if you have your repo ready to be uploaded put the repo files into the GitHub repository
folder and publish it
After publishing to the master branch we need to create a new branch called gh-pages so click on
“Current Branch” at the top and then on “New Branch”
Name it gh-pages and create it, then publish the branch again
After that switch back to the master branch by clicking Current branch again on the top and
navigate to master, optionally refresh once
At this point we’re done with the repo, if you got a new tweak just drag it into the debs folder, run
the script, update the repo by opening GitHub desktop and publish the new things
~Litten 🐱 💗