Skip to main content

FBSimulatorBridgeProtocol

The contract between the host and SimulatorFrameworkBridge, the helper idb runs inside a booted Simulator to read accessibility and change state no simctl verb reaches. Both sides depend on this library and nothing else of each other, so a request the host sends and the guest reads are defined once.

It is Foundation-only Swift with no other dependencies, and builds for macOS, iphonesimulator and appletvsimulator, because the guest is a Simulator binary for both iOS and tvOS.

What it provides​

  • Commands. BridgeCommand names every service the guest offers (accessibility, contacts, photos, notifications, privacy, DNS and the rest), with its arguments. The same command travels as a command-line argument for a one-shot guest or as a frame on a long-lived guest's socket.
  • Envelopes. BridgeRequest carries a versioned command; BridgeResponse and BridgeResult carry an exit status, the typed answers of every other service (BridgeAnswer), an optional binary property list and, for an accessibility command, the BridgeAXAnswer the guest built, in its own shape, including partial output when a command fails.
  • The accessibility vocabulary. BridgeAXWire spells every key of an accessibility request and response: the element attributes the guest reads, the verbs and actions a request can ask for, the response envelope, error kinds, quiescence signals and timing phases. Its raw values are the bytes on the wire, so they are stable.
  • Requesting clients. BridgeAXClientType is the value of -[AXPTranslatorRequest clientType]: which assistive client a translator request claims to come from, with raw values that are the translator's integers. Inside the Simulator the translator maps it onto a BridgeAXRequestingClient, the client the application answers for. Clients that deservesAutomation (application, xcodeHelper, xctest, scripter, systemEvents) get the application's automation tree; the rest get the flattened tree VoiceOver reads. A client applies only to requests made through the translator: a semantic traversal and a display hit-test. The host sends noClient unless a read names one. The mapping is the same on every iOS runtime from 26.4 to 27.0.
  • Accessibility requests. BridgeAXRequest is every accessibility request the host sends, typed: a read of an application or of whatever is frontmost (with BridgeAXReadOptions for depth, node budget, attributes, traversal, automation mode and requesting client), a hit test, a write with its optional BridgeAXWriteAssertion, device-setting reads and writes, a quiescence stream and the display inventory. BridgeCommand.accessibility carries the typed request, encoded as a JSON object of the BridgeAXWire keys above, so the guest answers the same type the host builds. A payload that does not decode throws a DecodingError whose underlying error is a BridgeAXRequestError naming what is wrong; BridgeRequest.accessibilityRequestError(of:) reads that error from such a frame, so the guest can still answer it with an accessibility error rather than failing the frame. The companion and the guest it launches are built together, so the decoder reads what this revision encodes rather than older shapes. A shared guest, though, serves every host on the machine that finds its socket, so BridgeRequest.currentVersion names the shared socket's directory and is checked on every frame: bump it whenever a request's shape changes, so hosts and guests from either side of the change never meet.
  • Accessibility responses. BridgeAXOutcome is every accessibility answer: ok beside either the verb's own fields or a BridgeAXFailure, decoded as the type the request's verb answers with. BridgeAXTreeResponse carries a tree of BridgeAXNodes, one optional field per BridgeAXWire.Node key, with geometry as BridgeAXRect and BridgeAXPoint (a non-finite coordinate travels as null) and attributes the accessibility server answers loosely as BridgeAXScalar. BridgeAXHitTestResponse, BridgeAXWriteResponse and BridgeAXSettingResponse answer the other verbs, and BridgeAXSettingSnapshot and BridgeAXQuiescenceEvent are the frames of the two streams. Each decodes the frames the guest writes today. BridgeAXDisplayInventory is the guest's answer to a display inventory request (the displays it can address, and which reads and writes it can scope to one), and BridgeAXModal is the fullscreen modal it reports beside a tree. The guest builds both from these types and the host decodes them with them, so neither side spells the keys. BridgeAXWire.ErrorKind.capabilityUnavailable names a request the guest cannot serve on this simulator.

Who depends on it​

On the host, FBSimulatorControl's bridge client spawns guests, connects to their sockets and encodes requests with this library; FBSimulatorAX reads accessibility through that client. In the guest, SimulatorFrameworkBridgeSupport decodes the same requests and answers them. The guest itself lives in SimulatorFrameworkBridge, and how it binds the Simulator's privacy database is described in its privacy notes.