Skip to content
Lars Fröder edited this page Jul 14, 2021 · 15 revisions

CCSupport Documentation

In iOS 11 the control center has massively changed and is now pretty much modular. Some Private Frameworks (ControlCenterUI, ControlCenterUIKit, ControlCenterServices) were added that can be used to create custom modules.

CCSupport serves as a support tweak for tweak developers to create their own modules for the Control Center. It mainly disables imposed whitelist restrictions and adds /Library/ControlCenter/Bundles to the directories from which modules are loaded.

Since Version 1.3, CCSupport also allows developers to create module providers, a module provider is a single bundle that can provide any amount of modules. The main advantage over a regular module is an increased flexibility, for example you can give the user an option to specify how many modules should be provided, or you can provide modules based on runtime contraints.

Theos Setup

Because we will be using Private Frameworks that are only available in iOS 11, it is important to use a patched sdk, which can be found here or here.

I have created theos templates to simplify the initial project setup, a script to install them (alongside a few required headers) is available here.

Just clone / download the repo and run the install.sh script (you may need to run chmod +x on it first). Note that if you have installed theos inside a directory that you don't own, you will need to use sudo to execute it.

(The module template is nowadays included inside theos itself, the module provider template is not)

Developing Modules

Project Setup

After completing the Theos Setup above, running nic.pl should give you an option to create a control center module (iphone/control_center_module-11up). Use it to create a new project. I have added comments that should hopefully explain the basics.

Depending on what the goal of your module is, you may want to change the class that your module inherits from, possible classes for that are documented below.

Project Resources

An Info.plist file is required and contains information about the module, see below for keys to utilize.

The SettingsIcon.png file will be displayed next to the name of your module in settings. Other icons can also be added to utilize them inside your module code.

Ideally you should provide two files for every icon you use, <filename>@2x.png and <filename>@3x.png, e.g. you would provide SettingsIcon@2x.png and SettingsIcon@3x.png

Icon Resolutions

Type Recommended @2x Resolution Recommended @3x Resolution
Settings Icon 58 * 58 87 * 87
Module Icon 70 * 96 105 * 144

For further reference, see Apples Guidelines.

Localization

If you want to provide localized module names, you can create lproj directories (like en.lproj, de.lproj, etc.) inside the Resources directory and put InfoPlist.strings files into them. These should contain CFBundleDisplayName as the key and the respective localization as the value.

Info.plist Keys

Keys provided by Apple

Key Description Value Type Class Availability
CFBundleIdentifier Bundle identifier of the module String All
CFBundleName Internal name of the module (will be displayed in settings if CFBundleDisplayName does not exist). String All
CFBundleDisplayName Display name of the module, will be displayed in settings next to the icon. String All
NSPrincipalClass Name of the class that implements the module. String All
SBIconVisibilityDefaultVisible Appears to be related to the mute module being hidden on iPhones. BOOL All
SBIconVisibilitySetByAppPreference Appears to be related to the mute module being hidden on iPhones. BOOL All
CCAssociatedBundleIdentifier Bundle identifier of the app that gets opened when tapping the module. String CCUIAppLauncherModule 
CCLaunchURL Launch argument that the app will be launched with. String CCUIAppLauncherModule
CCSupportsApplicationShortcuts Related to 3D Touch? BOOL ?

NOTE: Only contains important keys, an example Info.plist is provided by the template.

Keys provided by CCSupport

Key Description Value Type Introduced in Version Example
CCSModuleSize Specifies the size of the module. It should contain two dictionaries called Portrait and Landscape which both should contain a Width key and a Height key. These are both integer values that resemble the amount of space used in the Control Center grid. If this key does not exists, a default size of 1x1 will be used. Dictionary 1.1 1 
CCSGetModuleSizeAtRuntime Another way of specifying a custom size for your module. This one will call the - (CCUILayoutSize)moduleSizeForOrientation:(int)orientation method of your principal class after a respring, if it is implemented. If you want to force reload the size without a respring, post a "com.opa334.ccsupport/ReloadSizes" notification on the darwin notification center like this. CCUILayoutSize is a C Struct and you need to #import <ControlCenterUI/ControlCenterUI-Structs.h> to use it. The size for your module is expected to be returned. Orientation will be 0 for Portrait and 1 for Landscape. The CCSModuleSize will be ignored when this is set to true. BOOL 1.1 1, 2, 3
CCSPreferencesRootListController A method to add a preference page directly to your module. Implement a PSListController subclass in your module (similar to PreferenceLoader) and set this key to it's name. If this key and the class exist, pressing your module under Settings -> Control Center -> Customize Controls will open your PSListController. This needs to be a completely unique name (meaning that if another module uses the same name, you will run into issues). String 1.2 Demo Video, 1, 2 

Available Module Classes

Class Description Example
CCUIAppLauncherModule Used for simple app launchers. No implementation is needed, just set this as the NSPrincipalClass and also set CCAssociatedBundleIdentifier and CCLaunchURL (see above). Note that this uses the file AppIcon.png for the module icon. Calculator Module, CydiaLauncher
CCUIToggleModule Used for toggles (Template uses this as default). Orientation Lock Module, Smiley Module
CCUIContentModule Use this as a protocol of NSObject to create a custom module from scratch. Check out the Power Module readme for more detailed instructions. Connectivity Module, Power Module (Thanks to Muirey03)

NOTE: For more classes you can use, have a look at the headers here.

Developing Module Providers

Project Setup

After completing the Theos Setup above, running nic.pl should give you an option to create a CCSupport module provider (iphone/ccsupport_module_provider-11up). Use it to create a new project. I have added comments that should hopefully explain the basics.

A module provider is essentially a class that conforms to the CCSModuleProvider protocol.

- (NSUInteger)numberOfProvidedModules should return the number of modules that your provider provides, after the call to that, - (NSString*)identifierForModuleAtIndex:(NSUInteger)index will be fired for index = 0 ... number-1 and you should provide a unique identifier for each module.

The module instances (objects of a class that conforms to CCUIContentModule, see above) should be returned by the - (id)moduleInstanceForModuleIdentifier:(NSString*)identifier method.

For provided modules, CCSGetModuleSizeAtRuntime is assumed to always be true, so you can just implement - (CCUILayoutSize)moduleSizeForOrientation:(int)orientation inside the module instance if you want the module to have a custom size.

The preferences root controller can be supplied by implementing the - (id)listControllerForModuleIdentifier:(NSString*)identifier method on your module provider.

When the modules provided by your module provider change, you can post a com.opa334.ccsupport/ReloadProviders notification on the darwin notification center, which will cause CCSupport to reload all providers (e.g. numberOfProvidedModules, moduleInstanceForModuleIdentifier, etc. will be called again).

See Smiley Provider for an example.