Files
simplex-chat/apps/ios
Narasimha-sc b32a8cfb10 android, ios: report a network change when the network identity changes
With the simplexmq change this depends on, the core reconnects to the servers
on every online network event, so the event must also be sent when the network
type stays the same but it is a different network or an address was removed
(another Wi-Fi network, a new IP address after internet loss) - the connections
via the previous network are dead, and the OS reports it only after ~15 minutes.
Added addresses do not affect existing connections and are not reported,
unless there were none before. The event is not sent when the core
already has this network info for the network its connections are made via.

- android: track the Network handle and the link addresses in NetworkObserver,
  handle onLinkPropertiesChanged, and do not report online after an offline
  event that was not sent yet.
- android: the observer is serialized, and the removed addresses are counted
  rather than compared - an address removed and assigned again also leaves
  the connections made via it dead, so the count is what the next report is
  deduplicated against.
- android: the loss of a network that is no longer the current one is not
  reported - it is lost after the network that replaced it became the current
  one, and the connections are made via that one.
- ios: compare the local addresses of the interface the path uses and its
  gateways - NWPath has no network identity and no addresses.
- a report that was not accepted is repeated when the next event is received.
- what was reported is reset when the chat controller is created anew, so that
  the network info is reported to it and the reports for the previous one are
  dropped.
- android: the wake lock taken for the report is released when nothing was
  sent or the network is offline, instead of being held for its full timeout -
  the events that report nothing are new, as the info the core already has for
  the network its connections are made via is not sent again.
2026-10-05 09:33:06 +00:00
..
2026-09-02 10:26:52 +01:00
2026-09-02 10:26:52 +01:00
2026-09-02 10:26:52 +01:00
2026-09-02 10:26:52 +01:00
2026-09-02 10:26:52 +01:00
2026-09-21 17:31:29 +04:00
2026-08-20 13:43:59 +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