Dev:Updating extensions for iOS 15/16

From The Apple Wiki

Let's collect knowledge like we've done in the past. Feel free to paste in your notes and share what you've learned, even if they're a bit messy - somebody else can clean them up if needed. If you want to ask questions and share tips over chat with other developers, see Getting Help.


The big change with iOS 15/16 is a transition to rootless jailbreaks. Due to the introduction of Signed System Volume in iOS 15, it is no longer feasible to continue installing packages to the system volume, located at /. Starting with palera1n 2.0, packages are now expected to be installed with a prefix of /var/jb on all file paths. This also critically comes with a change to the deb Architecture field, from iphoneos-arm to iphoneos-arm64, to differentiate "rootful" and "rootless" packages. (The architecture name is misleading - this does not change anything relating to arm64 packages prior to iOS 15.) If your package needs to support both, you can keep your existing package identifier. APT knows to install the latest version of your package that matches the device's architecture. Rootful packages will not install on rootless, and vice versa.

Current versions of Sileo and Zebra fully support installing rootless packages. Cydia will display duplicates of packages that are available in both architectures. However, installation will work as expected with either duplicate.

Community support for rootless is still actively in progress. Theos has been updated with support; a rootless package can be built by setting THEOS_PACKAGE_SCHEME=rootless. Chariz, Havoc and BigBoss repos support uploading rootless packages.

Developing tweaks for the palera1n tethered iOS 15.x JB[edit]

This jailbreak is primarily a developer jailbreak and has certain restrictions.

Procursus: New Signing Requirements[edit]

iOS 15.0+ requires DER encoding of the entitlements, as such it is required that all tweaks are signed with an updated ldid. iOS 15.1+ adds a requirement on hash agility, added in ldid version 2.1.5-procursus3 which can be found here.

Low Power Mode[edit]

iOS 15.0+ introduced a new framework for handling Low Power Mode called LowPowerMode.framework. Toggling Low Power Mode can be done via the _PMLowPowerMode class.

@interface _PMLowPowerMode : NSObject
+ (id)sharedInstance;
- (NSInteger)getPowerMode; // 1 == Low Power Mode active
- (void)setPowerMode:(NSInteger)arg0 fromSource:(id)arg1; // Source == @"SpringBoard"

%hook ClassName
- (void)toggleLowPower {
    _PMLowPowerMode *lowPowerMode = [%c(_PMLowPowerMode) sharedInstance];
    BOOL active = [lowPowerMode getPowerMode] == 1;
    [lowPowerMode setPowerMode:!active fromSource:@"SpringBoard"];

Framework Changes[edit]



This class is responsible for icon grid constraints.

SBHIconGridSizeClassSizes in all arguments of methods and functions is now passed via pointer, instead of being passed as a raw struct.

You can write code that supports both versions like so:

@interface SBIconListGridLayoutConfiguration : NSObject

@interface i15SBIconListGridLayoutConfiguration : NSObject
-(void)setIconGridSizeClassSizes:(SBHIconGridSizeClassSizes *)sizes;


SBHIconGridSizeClassSizes sizes = { .small = { .columns = (short)widgetWidth(2, loadoutValueColumns), .rows = 2 },
                                    .medium = { .columns = (short)widgetWidth(4, loadoutValueColumns), .rows = 2 },
                                    .large = { .columns = (short)widgetWidth(4, loadoutValueColumns), .rows = 6 },
                                    .extralarge = { .columns = (short)widgetWidth(4, loadoutValueColumns), .rows = 6 } };

if (@available(iOS 15, *))
    // Cast to the iOS 15 Interface so ARC allows us to compile this
    // I need to double-check whether this actually needs to be allocated or whether passing it a stack pointer works fine.
    [(i15SBIconListGridLayoutConfiguration *)config setIconGridSizeClassSizes:&sizes];
    [config setIconGridSizeClassSizes:sizes];