A Framework for writing SwiftUI preference panes for iOS jailbreak tweaks.
-
Install Orion: https://orion.theos.dev/getting-started.html
-
Clone this repository
git clone https://github.com/ginsudev/Comet && cd Comet- Copy Comet.framework to theos
-
Install Comet from Chariz repo, then copy
/Library/Frameworks/Comet.framework/on device to yourtheos/libdirectory on Mac ($(THEOS)/lib/). -
Or run
make packageto getComet.frameworkand move it totheos/libfolder.
- Copy / Move the
comet-prefsfolder into$THEOS/vendor/templates/ios/with Finder or by command:
cp -r comet-prefs/ $THEOS/vendor/templates/ios/- Run the
build.shscript in$THEOS/vendor/templates/
cd $THEOS/vendor/templates/
./build.sh- Create a new project with NIC and choose
iphone/tweak_swift(Skip if you already have a tweak):
cd ~
$THEOS/bin/nic.pl
Choose a Template (required): 19 (Or whatever number `iphone/tweak_swift` comes in at)
Project Name (required): Some tweak name
Package Name [com.yourcompany.sometweakname]: com.somecompany.sometweakname
Author/Maintainer Name [Ginsu]: Ginsu
[iphone/tweak_swift] MobileSubstrate Bundle filter [com.apple.springboard]: [Press Enter]- Create
comet-prefsas a subproject inside your tweak:
cd ~/sometweakname/
$THEOS/bin/nic.pl
Choose a Template (required): 9 (Or whatever number `comet-prefs` comes in at)
Project Name (required): Some prefs name
Package Name [com.yourcompany.sometweakname]: com.somecompany.someprefsname
Author/Maintainer Name [Ginsu]: Ginsu- Run
make spmin your project:
make spm- Add
com.ginsu.cometas a dependency to your tweak.
Depends: com.ginsu.cometAdditionally, you can edit your Makefiles and changes settings like TARGET and specify different sdk versions. Note: Comet only supports iOS 14+.
That's the simplest part, once you've got everything setup, you can start creating your SwiftUI views and modifying RootView.swift to your liking.
Preferably inside of the PreferenceStorage.swift file, you can add your preferences like so:
@Published(key: "isEnabledSomeFeature", registry: registry) var isEnabledSomeFeature = false- The
registryparamater is the file path to your preference plist file. - The
keyparamater is the key where the value will be read from and written to. isEnabledSomeFeatureis the name of the variable (could be anything, but good to keep it the same as the key name).- The initial value assigned to the property (In this case
false) is the default / fallback value that will be used if there is no value for the key.
Firstly, to add a new page to your preference pane, you would use a NavigationLink in SwiftUI. Example:
struct RootView: View {
@StateObject private var preferenceStorage = PreferenceStorage()
var body: some View {
Form {
NavigationLink("2nd page") {
PageTwo()
.environmentObject(preferenceStorage)
}
}
}
}Firstly, it's good practice to have 1 source of truth for all your preferences. In other words, have all your preferences in the PreferenceStorage.swift file. We can then pass preferenceStorage down the view hierachy so that it can be accessed in subviews. For example:
struct PageTwo: View {
@EnvironmentObject var preferenceStorage: PreferenceStorage
var body: some View {
Form {
Section {
Toggle("Enabled 2", isOn: $preferenceStorage.isEnabledTwo)
} header: {
Text("The best tweak ever")
} footer: {
Text("A footer for the best tweak ever.")
.foregroundColor(preferenceStorage.isEnabledTwo ? .green : .red)
.animation(.default, value: preferenceStorage.isEnabledTwo)
}
}
.navigationTitle("Page 2!")
}
}One of the benefits here is that you can toggle some preferences on/off and then show additional changes on the RootView, like hide/show a row depending if some option is enabled, etc..
- You can't use
.toolbar()or.navigationTitle()SwiftUI modifiers inside ofRootView, but you can in subsequent pages / links. Workaround: add buttons to the nav bar inRootViewController.swiftfile, or don't touch the navigation bar inRootView.