From 81951e1398b2bbe4551319a48e059bdaf4a92237 Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Tue, 30 Jun 2026 12:05:13 +0200 Subject: [PATCH 1/4] Document changes for upcoming 1.15 Swift SDK --- client-sdks/reference/swift.mdx | 27 +++++++++++++++++++++++++++ client-sdks/usage-examples.mdx | 10 ++-------- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/client-sdks/reference/swift.mdx b/client-sdks/reference/swift.mdx index 64216339..4261ca27 100644 --- a/client-sdks/reference/swift.mdx +++ b/client-sdks/reference/swift.mdx @@ -277,6 +277,33 @@ let db = PowerSyncDatabase( The `DefaultLogger` supports the following severity levels: `.debug`, `.info`, `.warn`, `.error`. +## App Groups and App Extensions + +By default, the Swift SDK stores databases in `applicationSupportDirectory`. If you want to share local databases +between multiple apps in an app group, provide an absolute path (starting with `/`) as `dbFilename` when calling +`PowerSyncDatabase`. +The path should point towards a file in the app group's [shared container](https://developer.apple.com/documentation/xcode/configuring-app-groups#Access-an-app-groups-shared-container). + +Support for app groups and extensions was added in version 1.15, and is experimental. + +With app groups and extensions, multiple processes might access the database at the same time. SQLite uses shared memory +and file locking to make this safe, but there are still concerns that aren't relevant when the database is only accessed +from a single context: + +1. Concurrent writes to the database are not allowed. Within a process, the PowerSync SDK uses Swift actors to schedule + writes. Outside of SQLite using file locks, there is no additional coordination for multi-process access. + - Consider using [`PRAGMA busy_timeout`](https://sqlite.org/pragma.html#pragma_busy_timeout) to make SQLite wait longer. + - Be ready to handle `SQLITE_BUSY` errors if multiple processes attempt to write to the database. +2. Do not call `connect()` in more than one process! If two processes attempt to connect to the PowerSync service for + the same database, this wastes resources and can also lead to concurrency issues. If you share databases with extensions + or app groups, ensure there is only context responsible for connecting. +3. Avoid multiple versions of the Swift SDK: While the SQLite file format is stable and databases can safely be accessed + from multiple processes using their own SQLite version, the PowerSync SDK is not designed with this in mind. + In particular, opening the same database file from multiple processes can cause PowerSync-internal migrations to get + reverted. + This is not a concern for app extensions released as part of the same bundle, but something to be aware of for + app groups. + ## Additional Usage Examples For more usage examples including accessing connection status, monitoring sync progress, and waiting for initial sync, see the [Usage Examples](/client-sdks/usage-examples) page. diff --git a/client-sdks/usage-examples.mdx b/client-sdks/usage-examples.mdx index 09c4863b..feb0ea4f 100644 --- a/client-sdks/usage-examples.mdx +++ b/client-sdks/usage-examples.mdx @@ -1391,12 +1391,11 @@ import JavaScriptCallbackWatch from '/snippets/basic-watch-query-javascript-call ```swift struct SyncProgressIndicator: View { - private let powersync: any PowerSyncDatabaseProtocol + private let status: ObservableSyncStatus private let priority: BucketPriority? - @State private var status: SyncStatusData? = nil init(powersync: any PowerSyncDatabaseProtocol, priority: BucketPriority? = nil) { - self.powersync = powersync + self.status = powersync.currentStatus.observable self.priority = priority } @@ -1417,11 +1416,6 @@ import JavaScriptCallbackWatch from '/snippets/basic-watch-query-javascript-call Text("Downloaded \(progress.downloadedOperations) out of \(progress.totalOperations)") } } - }.task { - status = powersync.currentStatus - for await status in powersync.currentStatus.asFlow() { - self.status = status - } } } } From 246ba7f81db26d7ef086bf8d7bad9b871e6329da Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Tue, 30 Jun 2026 14:23:10 +0200 Subject: [PATCH 2/4] Also update `PowerSyncConnectionIndicator` snippet --- client-sdks/usage-examples.mdx | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/client-sdks/usage-examples.mdx b/client-sdks/usage-examples.mdx index feb0ea4f..8f67f3b5 100644 --- a/client-sdks/usage-examples.mdx +++ b/client-sdks/usage-examples.mdx @@ -879,26 +879,19 @@ import JavaScriptCallbackWatch from '/snippets/basic-watch-query-javascript-call import PowerSync struct PowerSyncConnectionIndicator: View { - private let powersync: any PowerSyncDatabaseProtocol - @State private var connected: Bool = false + private let status: ObservableSyncStatus init(powersync: any PowerSyncDatabaseProtocol) { - self.powersync = powersync + self.status = powersync.currentStatus.observable } var body: some View { + let connected = status.connected let iconName = connected ? "wifi" : "wifi.slash" let description = connected ? "Online" : "Offline" Image(systemName: iconName) .accessibility(label: Text(description)) - .task { - self.connected = powersync.currentStatus.connected - - for await status in powersync.currentStatus.asFlow() { - self.connected = status.connected - } - } } } ``` From 58a6e9e1254ecd33a4fd7a1c456977a16f0880c5 Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Mon, 20 Jul 2026 14:51:57 +0200 Subject: [PATCH 3/4] AI feedback --- client-sdks/reference/swift.mdx | 8 ++++---- client-sdks/usage-examples.mdx | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client-sdks/reference/swift.mdx b/client-sdks/reference/swift.mdx index 4261ca27..644c7309 100644 --- a/client-sdks/reference/swift.mdx +++ b/client-sdks/reference/swift.mdx @@ -292,11 +292,11 @@ from a single context: 1. Concurrent writes to the database are not allowed. Within a process, the PowerSync SDK uses Swift actors to schedule writes. Outside of SQLite using file locks, there is no additional coordination for multi-process access. - - Consider using [`PRAGMA busy_timeout`](https://sqlite.org/pragma.html#pragma_busy_timeout) to make SQLite wait longer. - - Be ready to handle `SQLITE_BUSY` errors if multiple processes attempt to write to the database. -2. Do not call `connect()` in more than one process! If two processes attempt to connect to the PowerSync service for + - Consider using [`PRAGMA busy_timeout`](https://sqlite.org/pragma.html#pragma_busy_timeout) to make SQLite wait longer. + - Be ready to handle `SQLITE_BUSY` errors if multiple processes attempt to write to the database. +2. Do not call `connect()` in more than one process: If two processes attempt to connect to the PowerSync service for the same database, this wastes resources and can also lead to concurrency issues. If you share databases with extensions - or app groups, ensure there is only context responsible for connecting. + or app groups, ensure there is only one context responsible for connecting. 3. Avoid multiple versions of the Swift SDK: While the SQLite file format is stable and databases can safely be accessed from multiple processes using their own SQLite version, the PowerSync SDK is not designed with this in mind. In particular, opening the same database file from multiple processes can cause PowerSync-internal migrations to get diff --git a/client-sdks/usage-examples.mdx b/client-sdks/usage-examples.mdx index 8f67f3b5..04fb7d21 100644 --- a/client-sdks/usage-examples.mdx +++ b/client-sdks/usage-examples.mdx @@ -1394,7 +1394,7 @@ import JavaScriptCallbackWatch from '/snippets/basic-watch-query-javascript-call var body: some View { VStack { - if let totalProgress = status?.downloadProgress { + if let totalProgress = status.downloadProgress { let progress = if let priority = self.priority { totalProgress.untilPriority(priority: priority) } else { From 2e54fd141639077d762b5e2d36eb7a2e2a4270cc Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Mon, 20 Jul 2026 15:29:53 +0200 Subject: [PATCH 4/4] More AI review --- client-sdks/reference/swift.mdx | 4 +++- client-sdks/usage-examples.mdx | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/client-sdks/reference/swift.mdx b/client-sdks/reference/swift.mdx index 644c7309..87628703 100644 --- a/client-sdks/reference/swift.mdx +++ b/client-sdks/reference/swift.mdx @@ -284,7 +284,9 @@ between multiple apps in an app group, provide an absolute path (starting with ` `PowerSyncDatabase`. The path should point towards a file in the app group's [shared container](https://developer.apple.com/documentation/xcode/configuring-app-groups#Access-an-app-groups-shared-container). -Support for app groups and extensions was added in version 1.15, and is experimental. + + Support for app groups and extensions was added in version 1.15, and is experimental. + With app groups and extensions, multiple processes might access the database at the same time. SQLite uses shared memory and file locking to make this safe, but there are still concerns that aren't relevant when the database is only accessed diff --git a/client-sdks/usage-examples.mdx b/client-sdks/usage-examples.mdx index 04fb7d21..88be0b65 100644 --- a/client-sdks/usage-examples.mdx +++ b/client-sdks/usage-examples.mdx @@ -886,7 +886,7 @@ import JavaScriptCallbackWatch from '/snippets/basic-watch-query-javascript-call } var body: some View { - let connected = status.connected + let connected = status.connected let iconName = connected ? "wifi" : "wifi.slash" let description = connected ? "Online" : "Offline"