Hello,
I've been encountering this issue and after some extensive debugging, suspect it may be related to the Swift SDK.
openPowerSyncWithGRDB() combined with connect() causes the app to permanently freeze (main thread blocked indefinitely), regardless of how many watch() calls are active — even zero. The equivalent setup using PowerSyncDatabase() (Kotlin-managed pool) works correctly with 8 concurrent watches + connect().
The SDK's own test testGRDBUpdatesFromPowerSync uses ValueObservation + openPowerSyncWithGRDB but never calls connect(), so this combination is not covered by the test suite.
Environment
- powersync-swift: 1.13.1
- powersync-sqlite-core-swift: 0.4.12
- GRDB: 7.10.0
- Platform: iOS 18 (iPhone, iPad), macOS 15
Reproduction
import PowerSync
import PowerSyncGRDB
import GRDB
let schema = Schema(
Table(name: "table_a", columns: [.text("name")])
)
// -- GRDB pool path (freezes) --
let appSupport = FileManager.default.urls(
for: .applicationSupportDirectory, in: .userDomainMask
).first!.appendingPathComponent("databases")
try FileManager.default.createDirectory(at: appSupport, withIntermediateDirectories: true)
let dbPath = appSupport.appendingPathComponent("test.sqlite").path
var config = Configuration()
try config.configurePowerSync(schema: schema)
let pool = try DatabasePool(path: dbPath, configuration: config)
let db = openPowerSyncWithGRDB(
pool: pool,
schema: schema,
identifier: "test-db"
)
struct MyConnector: PowerSyncBackendConnectorProtocol {
func fetchCredentials() async throws -> PowerSyncCredentials? {
// Replace with your PowerSync instance credentials
PowerSyncCredentials(
endpoint: "https://YOUR_INSTANCE.powersync.journeyapps.com",
token: "YOUR_JWT_TOKEN"
)
}
func uploadData(database: any PowerSyncDatabaseProtocol) async throws {}
}
// This alone freezes — no watch() calls needed
Task.detached {
try await db.connect(connector: MyConnector())
}
// App freezes after connect() completes its first sync cycle
Configurations tested
| Configuration |
Result |
openPowerSyncWithGRDB + connect() + 0 watches |
Freeze |
openPowerSyncWithGRDB + connect() + GRDB ValueObservation |
Freeze |
openPowerSyncWithGRDB + no connect() + GRDB ValueObservation |
Stable (no sync, no data) |
openPowerSyncWithGRDB + connect() + 8 db.watch() streams |
Freeze |
PowerSyncDatabase() + connect() + 8 db.watch() streams |
Stable |
The freeze occurs after connect() completes its first sync cycle. No crash, no error, no timeout — the app simply hangs. connect() through the GRDB pool is the sole trigger.
Context
This was initially misdiagnosed as a broader Kotlin dispatcher serialization issue. Extensive testing (multiple watches, readTransaction batching, separate GRDB connections, SDK version upgrades) all showed freezes. It was later determined that the multi-watch freeze was specific to powersync-sqlite-core-swift 0.4.11 and was resolved in 0.4.12. The openPowerSyncWithGRDB + connect() freeze persists independently on 0.4.12.
Expected behavior
openPowerSyncWithGRDB should work with connect() the same way PowerSyncDatabase() does. The GRDB pool path is advertised as supporting concurrent readers, but connect() through it freezes regardless of other activity.
Workaround
Use PowerSyncDatabase(schema:, dbFilename:) instead of openPowerSyncWithGRDB(). This uses the Kotlin-managed connection pool and works correctly with connect() + multiple watches.
Hello,
I've been encountering this issue and after some extensive debugging, suspect it may be related to the Swift SDK.
openPowerSyncWithGRDB()combined withconnect()causes the app to permanently freeze (main thread blocked indefinitely), regardless of how manywatch()calls are active — even zero. The equivalent setup usingPowerSyncDatabase()(Kotlin-managed pool) works correctly with 8 concurrent watches +connect().The SDK's own test
testGRDBUpdatesFromPowerSyncusesValueObservation+openPowerSyncWithGRDBbut never callsconnect(), so this combination is not covered by the test suite.Environment
Reproduction
Configurations tested
openPowerSyncWithGRDB+connect()+ 0 watchesopenPowerSyncWithGRDB+connect()+ GRDBValueObservationopenPowerSyncWithGRDB+ noconnect()+ GRDBValueObservationopenPowerSyncWithGRDB+connect()+ 8db.watch()streamsPowerSyncDatabase()+connect()+ 8db.watch()streamsThe freeze occurs after
connect()completes its first sync cycle. No crash, no error, no timeout — the app simply hangs.connect()through the GRDB pool is the sole trigger.Context
This was initially misdiagnosed as a broader Kotlin dispatcher serialization issue. Extensive testing (multiple watches, readTransaction batching, separate GRDB connections, SDK version upgrades) all showed freezes. It was later determined that the multi-watch freeze was specific to powersync-sqlite-core-swift 0.4.11 and was resolved in 0.4.12. The
openPowerSyncWithGRDB+connect()freeze persists independently on 0.4.12.Expected behavior
openPowerSyncWithGRDBshould work withconnect()the same wayPowerSyncDatabase()does. The GRDB pool path is advertised as supporting concurrent readers, butconnect()through it freezes regardless of other activity.Workaround
Use
PowerSyncDatabase(schema:, dbFilename:)instead ofopenPowerSyncWithGRDB(). This uses the Kotlin-managed connection pool and works correctly withconnect()+ multiple watches.