Updating extensions for iOS 11

From iPhone Development Wiki

Let's collect knowledge like we did with 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.

What has changed in iOS 11? (Classes, frameworks, etc.)


Since iOS 9.3.3, the SBScreenshotManager had been used. This is no longer the case on iOS 11. The class still exists, however it doesn't appear to be used anymore. Instead, there is a new framework named "ScreenshotServices" where most of the screenshot abilities have been kicked off to.

However, if the needs are simple, the SpringBoard _class_ has gotten two new methods to kick off screenshots with as well. takeScreenshot will be invoked with the hardware keys, at which point you can do what you need. This method won't work when the user invokes a screenshot in another way, like with AssistiveTouch. takeScreenshot only calls takeScreenshotAndEdit: though, which IS called by AssistiveTouch, so you can use that one instead.

If you have more complex needs, you likely will have to dig into the new services. Here is the decompiled version of takeScreenshotAndEdit: for some guidance.

- (void)takeScreenshotAndEdit:(BOOL)edit {
	SSScreenCapturerPresentationOptions *options = [SSScreenCapturerPresentationOptions new];
	if (![[[SBLockScreenManager sharedInstance] lockScreenViewController] suppressesScreenshots]) {
		if ([SSScreenCapturer shouldUseScreenCapturerForScreenshots]) {
			[options setPresentationMode:edit];
			[self->_screenCapturer takeScreenshotWithPresentationOptions:options];
		else {
			[self->_screenshotManager saveScreenshots];
	[options release];

Other avenues for screenshots:

- -[SBCombinationHardwareButtonActions performTakeScreenshotAction] which also did not work with AssistiveTouch.

- -[SSScreenCaptureAbilityCheck isAbleToTakeScreenshots] that returns false if (1) The user has disabled screenshot ability in Restrictions, (2) The device is multi-user and is at the login window, or (3) The device has not been set up through Buddy.

- SSMainScreenSnapshotter and SSOtherScreenSnapshotter may be worth looking into if you have multi-screen needs.

SBUserAgent changes

SBUserAgent still exists, however it is no longer accessible through the previous shared instance. It has instead been moved into SpringBoard as an ivar and can be accessed through a method. So the change can look like something like this in iOS 11:

Class SpringBoardClass = objc_getClass("SpringBoard");
SpringBoard *springBoardInstance = [SpringBoardClass sharedApplication];
SBUserAgent *userAgent = [springBoardInstance pluginUserAgent];
UIDeviceOrientation orientation = [userAgent activeInterfaceOrientation];

While iOS 10 and below could look like:

UIDeviceOrientation orientation = [[objc_getClass("SBUserAgent") sharedUserAgent] activeInterfaceOrientation];

Disabling CC, NC and Home gestures

In iOS 11 the CC moved to the top right, rather than the bottom. It also added the Home gesture for iPhone X devices. Since the code is pretty large (documentation) I'll make a new page for it with all versions in one.

See Disabling NC, CC and Home gestures for information of all versions.

Handling iPhone X

If you don't have an iPhone X handy, you may use LittleX to emulate iPhone X-specific functionalities on your non-X devices. For an alternative, use simject targeting an iPhone X simulator.

Invoking the app switcher

Pre iOS 11 we can use

SBMainSwitcherViewController *svm = [objc_getClass("SBMainSwitcherViewController") sharedInstance];
[svm toggleSwitcherNoninteractively];

And in iOS 11 it changed to use -toggleSwitcherNoninteractivelyWithSource like this

SBMainSwitcherViewController *svm = [objc_getClass("SBMainSwitcherViewController") sharedInstance];
[svm toggleSwitcherNoninteractivelyWithSource:nil];

Enabling oslog private data logging

This will also apply to iOS 10, wherein sensitive data in logging messages are hidden from the console. Using sudo log config --mode "private_data:on" will not work because it only applies to macOS logging system. To make it work for iOS, you can manually create com.apple.system.logging.plist inside /Library/Preferences/Logging containing the following entries:


You can read more about this finding from here. You may need to reboot or respring your device for changes to take effects globally. To revert, simply remove the plist file you created.

Cydia Substrate and Substitute

In December 2018, saurik released a version of Cydia Substrate that works with iOS 11. Before that, Substitute had been the only Cydia Substrate replacement but with less powerful hooking mechanism. Normally, tweaks that are created using Cydia Substrate will work just fine with Substitute because it includes Cydia Substrate based function calls that link to Substitute itself. Developers do not need to use Substitute directly. However, tweaks that are built specifically for Substitute may or may not work once a user decides to upgrade to the new version of Cydia Substrate.

There is an issue with package dependencies, e.g. "Note: After you install Semperon, you’ll also need to manually install two dependencies from Cydia: 1) libSparkAppList and 2) PrefixUI. Citing the developer, these aren’t installed automatically because of an APT bug present in this version of Cydia on iOS 11." [1]