Updating extensions for iOS 11

From iPhone Development Wiki
Revision as of 09:16, 18 June 2018 by PoomSmart (talk | contribs) (→‎Screenshots: "Decompiled")

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.

Screenshots

Since iOS 9.3.3 the SBScreenshotManager has been used. This is no longer the case, it seems. 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:(BOOL)arg1` 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 partly decompiled version (Hopper) of `takeScreenshotAndEdit:` for some guidance.

   void -[SpringBoard takeScreenshotAndEdit:](void * self, void * _cmd, bool edit) {
       ...
       SSScreenCapturerPresentationOptions *options = [SSScreenCapturerPresentationOptions new];
       if ([SSScreenCapturer shouldUseScreenCapturerForScreenshots]) {
               [options setPresentationMode:edit];
               [self->_screenCapturer takeScreenshotWithPresentationOptions:options];
       }
       else {
               [self->_screenshotManager saveScreenshots];
       }
       ...
       return;
   }

Other avenues for screenshots I found while researching were:

- `SBCombinationHardwareButtonActions`s method `-(void)performTakeScreenshotAction` which also did not work with AssistiveTouch.

- `SSScreenCaptureAbilityCheck`s method `-(bool)isAbleToTakeScreenshots` which seems to be always called. I didn't track down exactly from where it was called yet. I didn't need it.

- `SSMainScreenSnapshotter` and `SSOtherScreenSnapshotter` are highly related to taking screenshots, however I did not use these either. But worth looking into if you have multi-screen needs maybe.

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, the tweak (paid but open sourced) 'LittleX' worked _okay_ as a substitute.

https://github.com/ioscreatix/LittleX/blob/master/Tweak.xm

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