Files
simplex-chat/apps/ios/spec/api.md
T
spaced4ndy e7678b634c ios: refresh stale line references in spec documents
apps/ios/CODE.md asks that every #Lxx-Lyy reference in an affected
spec document point at the right lines. Most of these were already
stale on master; this corrects them in the documents the online search
change touched. Numbers only: no wording changes. Kept apart from the
feature documentation so it can be reviewed or dropped on its own.

Run: 002-ios-directory-search-ui, review round 1 (R1-7)
2026-10-13 12:55:37 +00:00

47 KiB

SimpleX Chat iOS -- Chat API Reference

Complete specification of the ChatCommand, ChatResponse, ChatEvent, and ChatError types that form the API between the Swift UI layer and the Haskell core.

Related specs: Architecture | State Management | README Related product: Concept Index

Source: AppAPITypes.swift | SimpleXAPI.swift | APITypes.swift | API.swift


Table of Contents

  1. Overview
  2. Command Categories (ChatCommand)
  3. Response Types (ChatResponse)
  4. Event Types (ChatEvent)
  5. Error Types (ChatError)
  6. FFI Bridge Functions
  7. Result Type (APIResult)
  8. Directory Search and Connection Plans

1. Overview

The iOS app communicates with the Haskell core exclusively through a command/response protocol:

  1. Swift constructs a ChatCommand enum value
  2. The command's cmdString property serializes it to a text command
  3. The FFI bridge sends the string to Haskell via chat_send_cmd_retry
  4. Haskell returns a JSON response, decoded as APIResult<ChatResponse>
  5. Async events arrive separately via chat_recv_msg_wait, decoded as ChatEvent

Source files:


2. Command Categories

The ChatCommand enum (AppAPITypes.swift L15) contains all commands the iOS app can send to the Haskell core. Commands are organized below by functional area.

2.1 User Management

Command Parameters Description Source
showActiveUser -- Get current active user L16
createActiveUser profile: Profile?, pastTimestamp: Bool Create new user profile L17
listUsers -- List all user profiles L18
apiSetActiveUser userId: Int64, viewPwd: String? Switch active user L19
apiHideUser userId: Int64, viewPwd: String Hide user behind password L25
apiUnhideUser userId: Int64, viewPwd: String Unhide hidden user L26
apiMuteUser userId: Int64 Mute notifications for user L27
apiUnmuteUser userId: Int64 Unmute notifications for user L28
apiDeleteUser userId: Int64, delSMPQueues: Bool, viewPwd: String? Delete user profile L29
apiUpdateProfile userId: Int64, profile: Profile Update user display name/image L149
setAllContactReceipts enable: Bool Set delivery receipts for all contacts L20
apiSetUserContactReceipts userId: Int64, userMsgReceiptSettings Per-user contact receipt settings L21
apiSetUserGroupReceipts userId: Int64, userMsgReceiptSettings Per-user group receipt settings L22
apiSetUserAutoAcceptMemberContacts userId: Int64, enable: Bool Auto-accept group member contacts L23

2.2 Chat Lifecycle Control

Command Parameters Description Source
startChat mainApp: Bool, enableSndFiles: Bool Start chat engine L30
checkChatRunning -- Check if chat is running L31
apiStopChat -- Stop chat engine L32
apiActivateChat restoreChat: Bool Resume from background L33
apiSuspendChat timeoutMicroseconds: Int Suspend for background L34
apiSetAppFilePaths filesFolder, tempFolder, assetsFolder Set file storage paths L35
apiSetEncryptLocalFiles enable: Bool Toggle local file encryption L36

2.3 Chat & Message Operations

Command Parameters Description Source
apiGetChats userId: Int64 Get all chat previews for user L45
apiGetChat chatId, scope, contentTag, pagination, search Get messages for a chat L46
apiGetChatContentTypes chatId, scope Get content type counts for a chat L47
apiGetChatItemInfo type, id, scope, itemId Get detailed info for a message L48
apiSendMessages type, id, scope, sendAsGroup, live, ttl, composedMessages Send one or more messages; sendAsGroup sends as channel owner L49
apiCreateChatItems noteFolderId, composedMessages Create items in notes folder L55
apiUpdateChatItem type, id, scope, itemId, updatedMessage, live Edit a sent message L57
apiDeleteChatItem type, id, scope, itemIds, mode Delete messages L58
apiDeleteMemberChatItem groupId, itemIds Moderate group messages L59
apiChatItemReaction type, id, scope, itemId, add, reaction Add/remove emoji reaction L62
apiGetReactionMembers userId, groupId, itemId, reaction Get who reacted L63
apiPlanForwardChatItems fromChatType, fromChatId, fromScope, itemIds Plan message forwarding L64
apiForwardChatItems toChatType, toChatId, toScope, sendAsGroup, from..., itemIds, ttl Forward messages; sendAsGroup forwards as channel owner L65
apiReportMessage groupId, chatItemId, reportReason, reportText Report group message L56
apiChatRead type, id, scope Mark entire chat as read L177
apiChatItemsRead type, id, scope, itemIds Mark specific items as read L178
apiChatUnread type, id, unreadChat Toggle unread badge L179

2.4 Contact Management

Command Parameters Description Source
apiAddContact userId, incognito Create invitation link L133
apiConnect userId, incognito, connLink Connect via link L144
apiConnectPlan userId, connLink Plan connection (preview) L136
apiPrepareContact userId, connLink, contactShortLinkData Prepare contact from link L138
apiPrepareGroup userId, connLink, directLink, groupShortLinkData Prepare group from link; directLink (required, no default) indicates whether link is a direct (non-relay) group link L139
apiConnectPreparedContact contactId, incognito, msg Connect prepared contact L142
apiConnectPreparedGroup groupId, incognito, msg Connect to a prepared group/channel; returns (GroupInfo, [RelayConnectionResult])? L143
apiConnectContactViaAddress userId, incognito, contactId Connect via address L145
apiAcceptContact incognito, contactReqId Accept contact request L165
apiRejectContact contactReqId Reject contact request L166
apiDeleteChat type, id, chatDeleteMode Delete conversation L146
apiClearChat type, id Clear conversation history L147
apiListContacts userId List all contacts L148
apiSetContactPrefs contactId, preferences Set contact preferences L150
apiSetContactAlias contactId, localAlias Set local alias L151
apiSetConnectionAlias connId, localAlias Set pending connection alias L153
apiContactInfo contactId Get contact info + connection stats L119
apiSetConnectionIncognito connId, incognito Toggle incognito on pending connection L134

2.5 Group Management

Command Parameters Description Source
apiNewGroup userId, incognito, groupProfile Create new group L75
apiNewPublicGroup userId, incognito, relayIds, groupProfile Create new public group (channel) with chat relays L76
apiGetGroupRelays groupId Get group relay list with status (owner only) L77
apiAddMember groupId, contactId, memberRole Invite contact to group L79
apiJoinGroup groupId Accept group invitation L80
apiAcceptMember groupId, groupMemberId, memberRole Accept member (knocking) L81
apiRemoveMembers groupId, memberIds, withMessages Remove members L85
apiLeaveGroup groupId Leave group L86
apiListMembers groupId List group members L87
apiUpdateGroupProfile groupId, groupProfile Update group name/image/description L88
apiMembersRole groupId, memberIds, memberRole Change member roles L83
apiBlockMembersForAll groupId, memberIds, blocked Block members for all L84
apiCreateGroupLink groupId, memberRole Create shareable group link L90
apiGroupLinkMemberRole groupId, memberRole Change group link default role L91
apiDeleteGroupLink groupId Delete group link L92
apiGetGroupLink groupId Get existing group link L93
apiAddGroupShortLink groupId Add short link to group L94
apiCreateMemberContact groupId, groupMemberId Create direct contact from group member L95
apiSendMemberContactInvitation contactId, msg Send contact invitation to member L96
apiGroupMemberInfo groupId, groupMemberId Get member info + connection stats L120
apiDeleteMemberSupportChat groupId, groupMemberId Delete member support chat L82
apiSetMemberSettings groupId, groupMemberId, memberSettings Set per-member settings L117
apiSetGroupAlias groupId, localAlias Set local group alias L152

2.6 Chat Tags

Command Parameters Description Source
apiGetChatTags userId Get all user tags L44
apiCreateChatTag tag: ChatTagData Create a new tag L50
apiSetChatTags type, id, tagIds Assign tags to a chat L51
apiDeleteChatTag tagId Delete a tag L52
apiUpdateChatTag tagId, tagData Update tag name/emoji L53
apiReorderChatTags tagIds Reorder tags L54

2.7 File Operations

Command Parameters Description Source
receiveFile fileId, userApprovedRelays, encrypted, inline Accept and download file L180
setFileToReceive fileId, userApprovedRelays, encrypted Mark file for auto-receive L181
cancelFile fileId Cancel file transfer L182
apiUploadStandaloneFile userId, file: CryptoFile Upload file to XFTP (no chat) L192
apiDownloadStandaloneFile userId, url, file: CryptoFile Download from XFTP URL L193
apiStandaloneFileInfo url Get file metadata from XFTP URL L194

2.8 WebRTC Call Operations

Command Parameters Description Source
apiSendCallInvitation contact, callType Initiate call L168
apiRejectCall contact Reject incoming call L169
apiSendCallOffer contact, callOffer: WebRTCCallOffer Send SDP offer L170
apiSendCallAnswer contact, answer: WebRTCSession Send SDP answer L171
apiSendCallExtraInfo contact, extraInfo: WebRTCExtraInfo Send ICE candidates L172
apiEndCall contact End active call L173
apiGetCallInvitations -- Get pending call invitations L174
apiCallStatus contact, callStatus Report call status change L175

2.9 Push Notifications

Command Parameters Description Source
apiGetNtfToken -- Get current notification token L68
apiRegisterToken token, notificationMode Register device token with server L69
apiVerifyToken token, nonce, code Verify token registration L70
apiCheckToken token Check token status L71
apiDeleteToken token Unregister token L72
apiGetNtfConns nonce, encNtfInfo Get notification connections (NSE) L73
apiGetConnNtfMessages connMsgReqs Get notification messages (NSE) L74

2.10 Settings & Configuration

Command Parameters Description Source
apiSaveSettings settings: AppSettings Save app settings to core L42
apiGetSettings settings: AppSettings Get settings from core L43
apiSetChatSettings type, id, chatSettings Per-chat notification settings L116
apiSetChatItemTTL userId, seconds Set global message TTL L108
apiGetChatItemTTL userId Get global message TTL L109
apiSetChatTTL userId, type, id, seconds Per-chat message TTL L110
apiSetNetworkConfig networkConfig: NetCfg Set network configuration L111
apiGetNetworkConfig -- Get network configuration L112
apiSetNetworkInfo networkInfo: UserNetworkInfo Set network type/status L113
reconnectAllServers -- Force reconnect all servers L114
reconnectServer userId, smpServer Reconnect specific server L115

2.11 Database & Storage

Command Parameters Description Source
apiStorageEncryption config: DBEncryptionConfig Set/change database encryption L40
testStorageEncryption key: String Test encryption key L41
apiExportArchive config: ArchiveConfig Export database archive L37
apiImportArchive config: ArchiveConfig Import database archive L38
apiDeleteStorage -- Delete all storage L39

2.12 Server Operations

Command Parameters Description Source
apiGetServerOperators -- Get server operators L100
apiSetServerOperators operators Set server operators L101
apiGetUserServers userId Get user's configured servers L102
apiSetUserServers userId, userServers Set user's servers L103
apiValidateServers userId, userServers Validate server configuration; returns errors and warnings L104
apiGetUsageConditions -- Get usage conditions L105
apiAcceptConditions conditionsId, operatorIds Accept usage conditions L107
apiTestProtoServer userId, server Test server connectivity L98

2.13 Theme & UI

Command Parameters Description Source
apiSetUserUIThemes userId, themes: ThemeModeOverrides? Set per-user theme L154
apiSetChatUIThemes chatId, themes: ThemeModeOverrides? Set per-chat theme L155

2.14 Remote Desktop

Command Parameters Description Source
setLocalDeviceName displayName Set device name for pairing L184
connectRemoteCtrl xrcpInvitation Connect to desktop via QR code L185
findKnownRemoteCtrl -- Find previously paired desktops L186
confirmRemoteCtrl remoteCtrlId Confirm known remote controller L187
verifyRemoteCtrlSession sessionCode Verify session code L188
listRemoteCtrls -- List known remote controllers L189
stopRemoteCtrl -- Stop remote session L190
deleteRemoteCtrl remoteCtrlId Delete known controller L191

2.15 Diagnostics

Command Parameters Description Source
showVersion -- Get core version info L201
getAgentSubsTotal userId Get total SMP subscriptions L202
getAgentServersSummary userId Get server summary stats L203
resetAgentServersStats -- Reset server statistics L204

2.16 Address Management

Command Parameters Description Source
apiCreateMyAddress userId Create SimpleX address L156
apiDeleteMyAddress userId Delete SimpleX address L157
apiShowMyAddress userId Show current address L158
apiAddMyAddressShortLink userId Add short link to address L159
apiSetProfileAddress userId, on: Bool Toggle address in profile L160
apiSetAddressSettings userId, addressSettings Configure address settings L161

2.17 Connection Security

Command Parameters Description Source
apiGetContactCode contactId Get verification code L129
apiGetGroupMemberCode groupId, groupMemberId Get member verification code L130
apiVerifyContact contactId, connectionCode Verify contact identity L131
apiVerifyGroupMember groupId, groupMemberId, connectionCode Verify group member identity L132
apiSwitchContact contactId Switch contact connection (key rotation) L123
apiSwitchGroupMember groupId, groupMemberId Switch group member connection L124
apiAbortSwitchContact contactId Abort contact switch L125
apiAbortSwitchGroupMember groupId, groupMemberId Abort member switch L126
apiSyncContactRatchet contactId, force Sync double-ratchet state L127
apiSyncGroupMemberRatchet groupId, groupMemberId, force Sync member ratchet L128

2.18 Service Requests

Command Parameters Description Source
apiSendServiceRequest userId, target, timeoutSec: Double?, requestJSON Send a JSON request to a service address (e.g. SimpleX Directory) and wait up to the timeout for its response (/_service_request); returns serviceResponse L137

3. Response Types

Responses are split across three enums due to Swift enum size limitations:

ChatResponse0

Synchronous query responses (AppAPITypes.swift L729):

Response Key Fields Description Source
activeUser user: User Current active user L730
usersList users: [UserInfo] All user profiles L731
chatStarted -- Chat engine started L732
chatRunning -- Chat is already running L733
chatStopped -- Chat engine stopped L734
apiChats user, chats: [ChatData] All chat previews L735
apiChat user, chat: ChatData, navInfo Single chat with messages L736
chatTags user, userTags: [ChatTag] User's chat tags L738
chatItemInfo user, chatItem, chatItemInfo Message detail info L739
serverTestResult user, testServer, testFailure Server test result L740
userServersValidation user, serverErrors: [UserServersError], serverWarnings: [UserServersWarning] Server validation result with errors and warnings L744
networkConfig networkConfig: NetCfg Current network config L747
contactInfo user, contact, connectionStats, customUserProfile Contact details L748
groupMemberInfo user, groupInfo, member, connectionStats Member details L750
connectionVerified verified, expectedCode Verification result L760
tagsUpdated user, userTags, chatTags Tags changed L761

ChatResponse1

Contact, message, and profile responses (AppAPITypes.swift L857):

Response Key Fields Description Source
invitation user, connLinkInvitation, connection Created invitation link L858
connectionPlan user, connLink, connectionPlan Connection plan preview L861
serviceResponse user, responseData: JSONValue A service's response to apiSendServiceRequest, left undecoded for the caller L862
newPreparedChat user, chat: ChatData Prepared contact/group L863
startedConnectionToGroup user, groupInfo, relayResults: [RelayConnectionResult] Group/channel join initiated; relay results indicate per-relay connection success/failure L869
contactDeleted user, contact Contact deleted L872
newChatItems user, chatItems: [AChatItem] New messages sent/received L890
chatItemUpdated user, chatItem: AChatItem Message edited L894
chatItemReaction user, added, reaction Reaction change L896
chatItemsDeleted user, chatItemDeletions, byUser Messages deleted L898
contactsList user, contacts: [Contact] All contacts list L899
userProfileUpdated user, fromProfile, toProfile Profile changed L878
userContactLinkCreated user, connLinkContact Address created L886
forwardPlan user, chatItemIds, forwardConfirmation Forward plan result L893
groupChatItemsDeleted user, groupInfo, chatItemIDs, byUser, member_ Group items deleted L892

ChatResponse2

Group, file, call, notification, and misc responses (AppAPITypes.swift L1003):

Response Key Fields Description Source
groupCreated user, groupInfo New group created L1005
publicGroupCreated user, groupInfo, groupLink, groupRelays: [GroupRelay] New public group (channel) created with relay info L1006
groupRelays user, groupInfo, groupRelays: [GroupRelay] Group relay list (owner API response) L1008
sentGroupInvitation user, groupInfo, contact, member Group invitation sent L1011
groupMembers user, group: Group Group member list L1015
membersRoleUser user, groupInfo, members, toRole Role changed L1019
groupUpdated user, toGroup: GroupInfo Group profile updated L1021
groupLinkCreated user, groupInfo, groupLink Group link created L1024
rcvFileAccepted user, chatItem File download started L1031
callInvitations callInvitations: [RcvCallInvitation] Pending calls L1040
ntfToken token, status, ntfMode, ntfServer Notification token info L1043
versionInfo versionInfo, chatMigrations, agentMigrations Core version L1051
cmdOk user_ Generic success L1052
archiveExported archiveErrors: [ArchiveError] Export result L1056
archiveImported archiveErrors: [ArchiveError] Import result L1057
appSettings appSettings: AppSettings Retrieved settings L1058

4. Event Types

The ChatEvent enum (AppAPITypes.swift L1179) represents async events from the Haskell core. These arrive via chat_recv_msg_wait polling, not as responses to commands.

Event processing entry point: processReceivedMsg in SimpleXAPI.swift.

Connection Events

Event Key Fields Description Source
contactConnected user, contact, userCustomProfile Contact connection established L1186
contactConnecting user, contact Contact connecting in progress L1187
contactSndReady user, contact Ready to send to contact L1188
contactDeletedByContact user, contact Contact deleted by other party L1185
contactUpdated user, toContact Contact profile updated L1190
receivedContactRequest user, contactRequest, chat_ Incoming contact request L1189
subscriptionStatus subscriptionStatus, connections Connection subscription change L1192

Message Events

Event Key Fields Description Source
newChatItems user, chatItems: [AChatItem] New messages received L1194
chatItemUpdated user, chatItem: AChatItem Message edited remotely L1196
chatItemReaction user, added, reaction: ACIReaction Reaction added/removed L1197
chatItemsDeleted user, chatItemDeletions, byUser Messages deleted L1198
chatItemsStatusesUpdated user, chatItems: [AChatItem] Delivery status changed L1195
groupChatItemsDeleted user, groupInfo, chatItemIDs, byUser, member_ Group items deleted L1200
chatInfoUpdated user, chatInfo Chat metadata changed L1193

Group Events

Event Key Fields Description Source
receivedGroupInvitation user, groupInfo, contact, memberRole Group invitation received L1201
userAcceptedGroupSent user, groupInfo, hostContact Joined group L1203
groupLinkConnecting user, groupInfo, hostMember Connecting via group link L1204
joinedGroupMemberConnecting user, groupInfo, hostMember, member Member joining L1206
memberRole user, groupInfo, byMember, member, fromRole, toRole Role changed L1208
memberBlockedForAll user, groupInfo, byMember, member, blocked Member blocked L1209
deletedMemberUser user, groupInfo, member, withMessages Current user removed L1210
deletedMember user, groupInfo, byMember, deletedMember Member removed L1211
leftMember user, groupInfo, member Member left L1212
groupDeleted user, groupInfo, member Group deleted L1213
userJoinedGroup user, groupInfo, hostMember Successfully joined; hostMember is upserted into group members L1214
joinedGroupMember user, groupInfo, member New member joined L1215
connectedToGroupMember user, groupInfo, member, memberContact E2E session established with member L1216
groupUpdated user, toGroup: GroupInfo Group profile changed L1217
groupLinkRelaysUpdated user, groupInfo, groupLink, groupRelays: [GroupRelay] Channel relay configuration changed L1107
groupMemberUpdated user, groupInfo, fromMember, toMember Member info updated L1191
groupRelayUpdated user, groupInfo, member, groupRelay Owner-side: a relay's relayStatus and/or the member's status changed. Fires on XGrpRelayReject with relayStatus = .rsRejected and member.memberStatus = .memRejected — final until cleared by the relay operator's /group allow <groupId> (no event emitted to the owner for that clear). Controller.hs (CEvtGroupRelayUpdated)

File Transfer Events

Event Key Fields Description Source
rcvFileStart user, chatItem Download started L1224
rcvFileProgressXFTP user, chatItem_, receivedSize, totalSize Download progress L1225
rcvFileComplete user, chatItem Download complete L1226
rcvFileSndCancelled user, chatItem, rcvFileTransfer Sender cancelled L1228
rcvFileError user, chatItem_, agentError, rcvFileTransfer Download error L1229
sndFileStart user, chatItem, sndFileTransfer Upload started L1232
sndFileComplete user, chatItem, sndFileTransfer Upload complete (inline) L1233
sndFileProgressXFTP user, chatItem_, fileTransferMeta, sentSize, totalSize Upload progress L1235
sndFileCompleteXFTP user, chatItem, fileTransferMeta XFTP upload complete L1237
sndFileError user, chatItem_, fileTransferMeta, errorMessage Upload error L1239

Call Events

Event Key Fields Description Source
callInvitation callInvitation: RcvCallInvitation Incoming call L1242
callOffer user, contact, callType, offer, sharedKey, askConfirmation SDP offer received L1243
callAnswer user, contact, answer SDP answer received L1244
callExtraInfo user, contact, extraInfo ICE candidates received L1245
callEnded user, contact Call ended by remote L1246

Connection Security Events

Event Key Fields Description Source
contactSwitch user, contact, switchProgress Key rotation progress L1181
groupMemberSwitch user, groupInfo, member, switchProgress Member key rotation L1182
contactRatchetSync user, contact, ratchetSyncProgress Ratchet sync progress L1183
groupMemberRatchetSync user, groupInfo, member, ratchetSyncProgress Member ratchet sync L1184

System Events

Event Key Fields Description Source
chatSuspended -- Core suspended L1180

5. Error Types

Defined in SimpleXChat/APITypes.swift L765:

public enum ChatError: Decodable, Hashable, Error {
    case error(errorType: ChatErrorType)
    case errorAgent(agentError: AgentErrorType)
    case errorStore(storeError: StoreError)
    case errorDatabase(databaseError: DatabaseError)
    case errorRemoteCtrl(remoteCtrlError: RemoteCtrlError)
    case invalidJSON(json: Data?)
    case unexpectedResult(type: String)
}

Error Categories

Category Enum Description Source
Chat logic ChatErrorType Business logic errors (e.g., invalid state, permission denied, chatRelayExists) APITypes.swift L788
SMP Agent AgentErrorType Protocol/network errors from the SMP agent layer APITypes.swift L1046
Database store StoreError SQLite query/constraint errors (includes relay-related: relayUserNotFound, duplicateMemberId, userChatRelayNotFound, groupRelayNotFound, groupRelayNotFoundByMemberId) APITypes.swift L964
Database engine DatabaseError DB open/migration/encryption errors APITypes.swift L1033
Remote control RemoteCtrlError Remote desktop session errors APITypes.swift L1234
Parse failure invalidJSON Failed to decode response JSON APITypes.swift L765
Unexpected unexpectedResult Response type does not match expected APITypes.swift L765

6. FFI Bridge Functions

Defined in Shared/Model/SimpleXAPI.swift:

Synchronous (blocking current thread)

// Throws on error, returns typed result
func chatSendCmdSync<R: ChatAPIResult>(           // SimpleXAPI.swift L93
    _ cmd: ChatCommand,
    bgTask: Bool = true,
    bgDelay: Double? = nil,
    ctrl: chat_ctrl? = nil,
    log: Bool = true
) throws -> R

// Returns APIResult (caller handles error)
func chatApiSendCmdSync<R: ChatAPIResult>(         // SimpleXAPI.swift L99
    _ cmd: ChatCommand,
    bgTask: Bool = true,
    bgDelay: Double? = nil,
    ctrl: chat_ctrl? = nil,
    retryNum: Int32 = 0,
    log: Bool = true
) -> APIResult<R>

Asynchronous (Swift concurrency)

// Throws on error, returns typed result
func chatSendCmd<R: ChatAPIResult>(                // SimpleXAPI.swift L121
    _ cmd: ChatCommand,
    bgTask: Bool = true,
    bgDelay: Double? = nil,
    ctrl: chat_ctrl? = nil,
    log: Bool = true
) async throws -> R

// Returns APIResult with optional retry on network errors
func chatApiSendCmdWithRetry<R: ChatAPIResult>(    // SimpleXAPI.swift L127
    _ cmd: ChatCommand,
    bgTask: Bool = true,
    bgDelay: Double? = nil,
    inProgress: BoxedValue<Bool>? = nil,
    retryNum: Int32 = 0,
    log: Bool = true
) async -> APIResult<R>?

Low-Level FFI

// Direct C FFI call -- serializes cmd.cmdString, calls chat_send_cmd_retry, decodes response
public func sendSimpleXCmd<R: ChatAPIResult>(      // API.swift L115
    _ cmd: ChatCmdProtocol,
    _ ctrl: chat_ctrl?,
    retryNum: Int32 = 0
) -> APIResult<R>

Event Receiver

// Polls for async events from the Haskell core
func chatRecvMsg(                                  // SimpleXAPI.swift L241
    _ ctrl: chat_ctrl? = nil
) async -> APIResult<ChatEvent>?

// Processes a received event and updates app state
func processReceivedMsg(                           // SimpleXAPI.swift L2555
    _ res: ChatEvent
) async

7. Result Type

Defined in SimpleXChat/APITypes.swift L27:

public enum APIResult<R>: Decodable where R: Decodable, R: ChatAPIResult {
    case result(R)           // Successful response
    case error(ChatError)    // Error response from core
    case invalid(type: String, json: Data)  // Undecodable response

    public var responseType: String { ... }
    public var unexpected: ChatError { ... }
}

public protocol ChatAPIResult: Decodable {         // APITypes.swift L65
    var responseType: String { get }
    var details: String { get }
    static func fallbackResult(_ type: String, _ json: NSDictionary) -> Self?
}

The decodeAPIResult<R> function (APITypes.swift L86) handles JSON decoding with fallback logic:

  1. Try standard JSONDecoder.decode(APIResult<R>.self, from: data)
  2. If that fails, try manual JSON parsing via JSONSerialization
  3. Check for "error" key -- return .error
  4. Check for "result" key -- try R.fallbackResult or return .invalid
  5. Last resort: return .invalid(type: "invalid", json: ...)

8. Directory Search and Connection Plans

Wrappers in Shared/Model/SimpleXAPI.swift used by the online search (see Chat List, Online Search):

Function Description Source
apiSearchDirectory(_ text:, cursor:) Sends apiSendServiceRequest to DIRECTORY_SERVICE_LINK with DIRECTORY_SEARCH_TIMEOUT_SEC and the search request; returns parseDirectorySearchResponse(responseData), or nil on any error (logged). Blocks for up to the timeout L1044
apiConnectPlan(connLink:, resolveMode:, linkOwnerSig:, inProgress:, onFailure:) Plans a connection; returns ConnectionPlanResult?. notResolvedLocally (a .never lookup that matched nothing) returns nil silently; any other failure is handled by onFailure L1064
ConnectPlanFailure .alert (default, every existing caller): apiConnectResponseAlert; .log: debug log only, used by the online search so name resolution and per-entry lookups never raise alerts L1060

A service response is carried as JSONValue (any JSON), so the framework does not depend on a service's own types; callers decode it with decodeJSONValue.


Source Files

File Path
ChatCommand enum Shared/Model/AppAPITypes.swift L15
ChatResponse0/1/2 enums Shared/Model/AppAPITypes.swift L729, L857, L1003
ChatEvent enum Shared/Model/AppAPITypes.swift L1179
APIResult, ChatError SimpleXChat/APITypes.swift L27, L765
FFI bridge functions Shared/Model/SimpleXAPI.swift
Service response JSON SimpleXChat/APITypes.swift L722
Low-level FFI SimpleXChat/API.swift
Data types SimpleXChat/ChatTypes.swift
C header SimpleXChat/SimpleX.h
Haskell controller ../../src/Simplex/Chat/Controller.hs