Files
simplex-chat/apps/ios
Narasimha-sc 58aee54ad6 android, desktop, ios: do not offer to accept or join twice
An invitation being accepted is a fact about the invitation, not about the
view that shows it, but each view kept its own flag. The chat list row, the
long-press menu, the accept alert, the composer banner, the chat item
"tap to join" and the notification action therefore disagreed: accepting
from one left the others fully enabled, and the second accept reached the
core with an invitation the first one had already used.

ChatModel now records which contact requests are being accepted and which
groups are being joined. The shared acceptContactRequest and the new
joinGroup maintain it, so every caller participates without changing its
call site, and every view derives from it instead of owning a flag. The
record is taken before the request is sent, so a second tap in the same
view is blocked as well.

The connect composer no longer renders in a group's support scope: on
desktop that is a second view of the same group next to the main one, and
it offered its own Join button.
2026-08-20 11:43:11 +00:00
..
2026-07-25 16:07:00 +01:00
2026-07-18 20:33:10 +01:00
2026-07-18 20:33:10 +01:00
2026-07-25 16:07:00 +01:00
2026-07-25 16:07:00 +01:00
2026-07-18 20:33:10 +01:00
2026-07-18 20:33:10 +01:00
2026-07-18 20:33:10 +01:00
2026-07-06 22:04:50 +01:00
2026-07-06 22:04:50 +01:00
2026-07-25 17:17:39 +01:00
2026-07-18 20:33:10 +01:00
2026-07-18 20:33:10 +01:00
2026-07-18 20:33:10 +01:00

SimpleX Chat iOS app

This file provides guidance when working with code in this repository.

iOS App Overview

The iOS app is a SwiftUI application that interfaces with the Haskell core library via FFI. It shares the SimpleXChat framework with two extensions: Notification Service Extension (NSE) for push notifications and Share Extension (SE) for sharing content from other apps.

Build & Development

Open SimpleX.xcodeproj in Xcode. The project has five targets:

  • SimpleX (iOS) - Main app (Bundle ID: chat.simplex.app)
  • SimpleXChat - Framework containing FFI bridge and shared types
  • SimpleX NSE - Notification Service Extension
  • SimpleX SE - Share Extension
  • Tests iOS - UI tests

Build and run via Xcode (Product > Build/Run). Tests run via Product > Test or:

xcodebuild test -scheme "SimpleX (iOS)" -destination 'platform=iOS Simulator,name=iPhone 15'

Deployment target: iOS 15.0+, Swift 5.0.

Architecture

Haskell Core Integration

The app calls the Haskell core library through C FFI defined in SimpleXChat/SimpleX.h:

  • chat_migrate_init_key() - Initialize/migrate database
  • chat_send_cmd_retry() - Send command to chat controller
  • chat_recv_msg_wait() - Receive messages from controller

Swift wrappers in SimpleXChat/API.swift:

  • chatMigrateInit() - Initialize chat controller
  • sendSimpleXCmd<R>() - Send typed commands and parse responses
  • recvSimpleXMsg<R>() - Receive typed messages

Haskell runtime initialization (SimpleXChat/hs_init.c) uses different memory configurations:

  • Main app: 64MB heap
  • NSE: 512KB heap (minimal footprint for background processing)
  • SE: 1MB heap

Pre-compiled Haskell libraries are in Libraries/{ios,mac,sim}/.

State Management

  • ChatModel (Shared/Model/ChatModel.swift) - Main singleton ObservableObject for app-wide state (chat list, active chat, users)
  • ItemsModel - Manages chat items within a selected chat (similar to Kotlin's ChatsContext)
  • AppTheme - Theme management and customization

App Structure

Entry point: Shared/SimpleXApp.swift

Key directories in Shared/:

  • Model/ - Data models and API layer (ChatModel.swift, SimpleXAPI.swift)
  • Views/ - SwiftUI views organized by feature:
    • ChatList/ - Chat list and user picker
    • Chat/ - Message display and composition
    • Call/ - VoIP call UI
    • UserSettings/ - App settings
    • LocalAuth/ - Passcode and biometric authentication
    • Database/ - Database initialization and migration

Shared Data Between Targets

All three targets share data via App Group (group.chat.simplex.app):

  • SimpleXChat/AppGroup.swift - GroupDefaults wrapper for typed shared preferences
  • Keychain for sensitive data: kcDatabasePassword, kcAppPassword, kcSelfDestructPassword

Key Types

Types are defined in SimpleXChat/:

  • ChatTypes.swift - User, Chat, Message, Group types
  • APITypes.swift - API request/response types

Commands follow ChatCmdProtocol (has cmdString property), sent as JSON through FFI.

Localization

31 languages supported. Localization files in SimpleX Localizations/.

Workflow:

  • Product > Export Localizations - Export XLIFF files
  • Product > Import Localizations - Import updated translations

SimpleX Assets

The app includes optional assets behind the SIMPLEX_ASSETS Swift compilation flag. Without setup, the app builds normally without them.

Setup

Create Local.xcconfig (gitignored) in the apps/ios/ directory:

SIMPLEX_ASSETS_DIR = /path/to/assets
SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) SIMPLEX_ASSETS

The copy script (scripts/ios/copy-assets.sh) runs as a build phase on each build but exits immediately if SIMPLEX_ASSETS is not set.

Updating assets

When source images change, regenerate resized images (requires ImageMagick):

cd path/to/assets && ./resize.sh

Background Capabilities

Configured in Info.plist:

  • Background modes: audio, fetch, remote-notification, voip
  • URL scheme: simplex:// for deep linking
  • BGTaskScheduler: chat.simplex.app.receive