Website Logo.

Bensge's Blog

Programming, iOS, Jailbreaking, the Web.

UIStatusBar Research

The iOS status bar is an interesting construct many jailbreak developers try to avoid messing with. After some research I thought I’d share some of my achievements to help other developers.

Items

Status bars contain so-called items, for example the WiFi item or the battery item, each item has a unique identifier. With some research I found out most items and their corresponding identifier:

Item identifier Name
0 time / clock
1 quite mode / DND
2 Airplane mode
3 signal strength
4 service item (carrier name)
5 data network
7 battery icon + lightning
8 battery percent
9 battery percent, looks same as 8 but isn’t. Maybe the not charging item?
10 bluetooth battery
11 bluetooth
12 TTY
13 alarm
16 location
17 rotation lock
19 AirPlay
20 assistant / Siri
21 VPN
22 call forwarding
23 activity / loading indicator
24 thermal color (?)

What to do with these item identifiers? What about enabling or disabling some items globally? Let’s enable the Siri status bar item:

1
2
[[SBStatusBarStateAggregator sharedInstance ] _setItem:20 enabled:YES]
//Returns a BOOL, YES if the status bar was changed and NO if it was already set

And ta-da, a siri icon in the status bar:


Data distribution

The status bar gets data from the status bar server UIStatusBarServer. The server and the status bar are not directly connected, a status bar state provider is a proxy between the two. A state provider conforms to the UIStatusBarStateProvider protocol, in SpringBoard SBStatusBarStateProvider and its subclasses (SBMainStatusBarStateProvider or SBNotificationCenterStatusBarStateProvider). State providers notify listening status bars about changes and edit the data, shwing or hiding specific items. SBMainStatusBarStateProvider enables and disables the time item dynamically (disabled on the lock screen, enabled otherwise), status bars get data from it by default. Hence to enable or disable the status bar time in (almost) all status bars, call the main state provider:

1
[[objc_getClass("SBMainStatusBarStateProvider") sharedInstance] enableTime:YES]

If you don’t want your status bar to hide the time dynamically, don’t use the main state provider (shown below)!

Styles

The status bar can also have different styles, infulencing the foreground and background color or the status bar height (incomplete list!).

Style Description
0x12F Notification center style
0x132 Big lockscreen style

When to use these styles is shown in the next paragraph.

Creating status bars

Creating a status bar isn’t very hard:

1
2
3
4
5
6
7
8
9
int statusBarStyle = 0x12F; //Normal notification center style
UIInterfaceOrientation orientation = UIApplication.sharedApplication.statusBar.statusBarWindow.orientation;
statusBar = [[UIStatusBar alloc] initWithFrame:CGRectMake(0,0,UIApplication.sharedApplication.statusBar.bounds.size.width,[UIStatusBar.class heightForStyle:statusBarStyle orientation:orientation]) showForegroundView:YES inProcessStateProvider:[[[objc_getClass("SBStatusBarStateProvider") alloc] init] autorelease]];
[statusBar requestStyle:statusBarStyle];
statusBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self addSubview:statusBar];

//After orientation changes
[statusBar setOrientation:UIApplication.sharedApplication.statusBarOrientation];

In this example we provide a custom state provider, the status bar won’t use the main provider and will always show the time item, even on the lock screen. To use the main provider, initialize the status bar with -initWithFrame: instead. Don’t forget to call -setOrientation: after initialization or if the interface orientation of your interface changed.

I hope this will help some other developers. If you have additions, please let me know about them. Happy coding!