I’m attempting to create a solution for an end-to-end testing suite to set user permissions (contacts, photos, notifications, etc.) on the simulator. The reason for doing this is because permission alerts are displayed by SpringBoard, and they interfere with the testing suite.
I’ve tried using the XCUITest suite, but it does not work as expected regarding SpringBoard alerts, and is inconvenient to use in general.
So my idea was to modify system files in order to set permissions on-demand. I found the TCC database, and it seems to be pretty straightforward. I then noticed that notification permissions are saved under a different file, /Library/BulletinBoard/SectionInfo.plist
. This file is cached by a BBServer
object in the SpringBoard process. I managed to change this file, and if SpringBoard is terminated, changes to the file are accepted. But I want this change to happen during the tested app’s process runtime.
After some digging, I noticed that when the Settings app (Preferences) makes a change to notification settings, it uses an XPC connection to notify it has made a change.
I am trying to accomplish the same thing in the tested process. I create a BBSectionInfo
object which contains all the settings for the notifications, and try to notify the BulletinBoard server of this change using a BBSettingsGateway
, which internally uses an XPC connection. This does not work, and I am not sure why not, because I do not get any error.
Perhaps it’s an entitlement issue? What annoys me is that no error is given by the system, just nothing happens.
In debugger, bringing the XPC connection, I get this:
(lldb) po [inv.target valueForKey:@“connection”]
<NSXPCConnection: 0x60000011bcf0> connection to service named com.apple.bulletinboard.settingsconnection
The internal connection also does not disclose any issues:
(lldb) po [[inv.target valueForKey:@"connection"] valueForKey:@"xpcConnection"]
<OS_xpc_connection: connection[0x6000001a6200]: { refcnt = 2, xrefcnt = 1, name = com.apple.bulletinboard.settingsconnection, type = named, state = init-done, error = 0x0 mach = true, privileged = false, bssend = 0x6f07, recv = 0x6d0b, send = 0x7003, pid = 0, euid = 4294967295, egid = 4294967295, asid = 4294967295 } <connection: 0x6000001a6200> { name = com.apple.bulletinboard.settingsconnection, listener = false, pid = 0, euid = 4294967295, egid = 4294967295, asid = 4294967295 }>
So all seems good. The only difference I can find between the connections is that in my process, the state is init-done
, while in the Preferences process, the state is checked in
:
(lldb) po [[[QuietHoursStateController sharedController] bbGateway] valueForKey:@"connection"]
<NSXPCConnection: 0x6180001160b0> connection to service named com.apple.bulletinboard.settingsconnection
(lldb) po [[[[QuietHoursStateController sharedController] bbGateway] valueForKey:@"connection"] valueForKey:@"xpcConnection"]
<OS_xpc_connection: connection[0x6180001a3fe0]: { refcnt = 2, xrefcnt = 1, name = com.apple.bulletinboard.settingsconnection, type = named, state = checked in, error = 0x0 mach = true, privileged = false, bssend = 0x9d03, recv = 0x9817, send = 0x9e03, pid = 17877, euid = 26053515, egid = 20, asid = 100046 } <connection: 0x6180001a3fe0> { name = com.apple.bulletinboard.settingsconnection, listener = false, pid = 17877, euid = 26053515, egid = 20, asid = 100046 }>
I don’t have enough experience with XPC connections, so maybe I am missing something? BBSettingsGateway
seems to manage its own connection, and it does not expose any methods for managing the connection.
I don’t mind other creative solutions, as this solution is only for the simulator. I have added the jailbreak
tag for discoverability, but I am looking for simulator-only solutions.