Updating extensions for iOS 15/16

From iPhone Development Wiki

Let's collect knowledge like we did with iOS 14, iOS 13, iOS 12, iOS 11, iOS 10, iOS 9, iOS 8 and iOS 7 – paste in your notes and share what you've learned, and somebody else will organize it later. :) If you want to ask questions and share tips over chat with other developers, see How to use IRC for how to connect to #theos and #iphonedev.

Hey developer, you can add your knowledge here! Yes, you! Make an account and edit this page!

If you want to see what's been recently updated on this page, you can use the wiki's history feature to compare the revisions (to look at the diff) since the last time you visited this page.

Developing tweaks for the palera1n tethered iOS 15.x JB

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

Procursus: New Signing Requirements

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

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
+ (instancetype)sharedInstance;
- (NSInteger)getPowerMode; // 1 == Low Power Mode active
- (void)setPowerMode:(NSInteger)powerMode fromSource:(id)source; // Source == @"SpringBoard"

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

Wallpaper UI

with iOS 16, Wallpaper UI has been moved to a separate process.

If you are in SpringBoard and need a snapshot of the current wallpaper, you can do

    UIGraphicsBeginImageContext([myPBUIPosterViewController view].frame.size);
    [[myPBUIPosterViewController view].layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();

where PBUIPosterViewController is the PBUIPosterViewController instance.

Framework Changes


Concept: GridSizeClass

A GridSizeClass refers to the size widgets take up, in units of rows/cols.

They are essentially the different options you see when selecting a widget size while adding one (i.e. "small", "medium", etc.)

SBHIconGridSizeClassIconImageInfos (iOS 16)

Added with iOS 16, this struct contains 5 fields, each holding a SBIconImageInfo corresponding to image info for a given grid size class.

typedef struct SBHIconGridSizeClassIconImageInfos {
    SBIconImageInfo icon;
    SBIconImageInfo small;
    SBIconImageInfo medium;
    SBIconImageInfo large;
    SBIconImageInfo newsLargeTall;
    SBIconImageInfo extraLarge;
} SBHIconGridSizeClassIconImageInfos;

SBHIconGridSizeClassSizes (iOS 15)

This struct holds icon grid constraints. It was introduced with iOS 14 for the sake of supporting different layout widths for multi-icon-spanning views.

typedef struct SBHIconGridSizeClassSizes {
    SBHIconGridSize small;
    SBHIconGridSize medium;
    SBHIconGridSize large;
    SBHIconGridSize extraLarge;
} SBHIconGridSizeClassSizes;
Minor modification to appearance in method signatures

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];