Skip to content

Commit 232e43c

Browse files
Additional Strict Concurrency Declarations (#75)
* added more sendable annotations. Update example app to use Swift 6 Strict concurrency checking * Add changelog entry * update sync status sendable status. Update logger usage in tests.
1 parent 67453bb commit 232e43c

28 files changed

+223
-152
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## 1.5.1 (unreleased)
44

55
* Update core extension to 0.4.5 ([changelog](https://github.com/powersync-ja/powersync-sqlite-core/releases/tag/v0.4.5))
6+
* Additional Swift 6 Strict Concurrency Checking declarations added for remaining protocols.
67

78
## 1.5.0
89

Demo/PowerSyncExample.xcodeproj/project.pbxproj

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,7 @@
645645
SDKROOT = iphoneos;
646646
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
647647
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
648+
SWIFT_STRICT_CONCURRENCY = complete;
648649
};
649650
name = Debug;
650651
};
@@ -701,6 +702,7 @@
701702
OTHER_LDFLAGS = "-lsqlite3";
702703
SDKROOT = iphoneos;
703704
SWIFT_COMPILATION_MODE = wholemodule;
705+
SWIFT_STRICT_CONCURRENCY = complete;
704706
VALIDATE_PRODUCT = YES;
705707
};
706708
name = Release;
@@ -742,7 +744,7 @@
742744
SWIFT_OBJC_BRIDGING_HEADER = "PowerSyncExample/PowerSyncExample-Bridging-Header.h";
743745
"SWIFT_OBJC_BRIDGING_HEADER[arch=*]" = "";
744746
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
745-
SWIFT_VERSION = 5.0;
747+
SWIFT_VERSION = 6.0;
746748
TARGETED_DEVICE_FAMILY = "1,2";
747749
};
748750
name = Debug;
@@ -781,7 +783,7 @@
781783
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
782784
SWIFT_EMIT_LOC_STRINGS = YES;
783785
SWIFT_OBJC_BRIDGING_HEADER = "PowerSyncExample/PowerSyncExample-Bridging-Header.h";
784-
SWIFT_VERSION = 5.0;
786+
SWIFT_VERSION = 6.0;
785787
TARGETED_DEVICE_FAMILY = "1,2";
786788
};
787789
name = Release;

Demo/PowerSyncExample/Components/AddListView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ struct AddListView: View {
1313
Task {
1414
do {
1515
try await system.insertList(newList)
16-
await completion(.success(true))
16+
completion(.success(true))
1717
} catch {
18-
await completion(.failure(error))
18+
completion(.failure(error))
1919
throw error
2020
}
2121
}

Demo/PowerSyncExample/Components/AddTodoListView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ struct AddTodoListView: View {
1515
Task{
1616
do {
1717
try await system.insertTodo(newTodo, listId)
18-
await completion(.success(true))
18+
completion(.success(true))
1919
} catch {
20-
await completion(.failure(error))
20+
completion(.failure(error))
2121
throw error
2222
}
2323
}

Demo/PowerSyncExample/PowerSync/SupabaseConnector.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,14 @@ private enum PostgresFatalCodes {
3838
}
3939

4040
@Observable
41+
@MainActor // _session is mutable, limiting to the MainActor satisfies Sendable constraints
4142
final class SupabaseConnector: PowerSyncBackendConnectorProtocol {
4243
let powerSyncEndpoint: String = Secrets.powerSyncEndpoint
4344
let client: SupabaseClient = .init(
4445
supabaseURL: Secrets.supabaseURL,
4546
supabaseKey: Secrets.supabaseAnonKey,
4647
)
47-
var session: Session?
48+
private(set) var session: Session?
4849
private var errorCode: String?
4950

5051
@ObservationIgnored

Demo/PowerSyncExample/PowerSync/SupabaseRemoteStorage.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Foundation
22
import PowerSync
33
import Supabase
44

5-
class SupabaseRemoteStorage: RemoteStorageAdapter {
5+
final class SupabaseRemoteStorage: RemoteStorageAdapter {
66
let storage: Supabase.StorageFileApi
77

88
init(storage: Supabase.StorageFileApi) {

Demo/PowerSyncExample/PowerSync/SystemManager.swift

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@ func getAttachmentsDirectoryPath() throws -> String {
1313

1414
let logTag = "SystemManager"
1515

16+
/// We use the MainActor SupabaseConnector synchronously here, this requires specifying that SystemManager runs on the MainActor
17+
/// We don't actually block the MainActor with anything
1618
@Observable
17-
class SystemManager {
19+
@MainActor
20+
final class SystemManager {
1821
let connector = SupabaseConnector()
1922
let schema = AppSchema
2023
let db: PowerSyncDatabaseProtocol
2124

22-
var attachments: AttachmentQueue?
25+
let attachments: AttachmentQueue?
2326

2427
init() {
2528
db = PowerSyncDatabase(
@@ -226,25 +229,18 @@ class SystemManager {
226229
try await attachments.deleteFile(
227230
attachmentId: photoId
228231
) { transaction, _ in
229-
try self.deleteTodoInTX(
230-
id: todo.id,
231-
tx: transaction
232+
try transaction.execute(
233+
sql: "DELETE FROM \(TODOS_TABLE) WHERE id = ?",
234+
parameters: [todo.id]
232235
)
233236
}
234237
} else {
235-
try await db.writeTransaction { transaction in
236-
try self.deleteTodoInTX(
237-
id: todo.id,
238-
tx: transaction
238+
_ = try await db.writeTransaction { transaction in
239+
try transaction.execute(
240+
sql: "DELETE FROM \(TODOS_TABLE) WHERE id = ?",
241+
parameters: [todo.id]
239242
)
240243
}
241244
}
242245
}
243-
244-
private func deleteTodoInTX(id: String, tx: ConnectionContext) throws {
245-
_ = try tx.execute(
246-
sql: "DELETE FROM \(TODOS_TABLE) WHERE id = ?",
247-
parameters: [id]
248-
)
249-
}
250246
}

Sources/PowerSync/Kotlin/KotlinTypes.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,7 @@ extension KotlinPowerSyncBackendConnector: @retroactive @unchecked Sendable {}
88
extension KotlinPowerSyncCredentials: @retroactive @unchecked Sendable {}
99
extension PowerSyncKotlin.KermitLogger: @retroactive @unchecked Sendable {}
1010
extension PowerSyncKotlin.SyncStatus: @retroactive @unchecked Sendable {}
11+
12+
extension PowerSyncKotlin.CrudEntry: @retroactive @unchecked Sendable {}
13+
extension PowerSyncKotlin.CrudBatch: @retroactive @unchecked Sendable {}
14+
extension PowerSyncKotlin.CrudTransaction: @retroactive @unchecked Sendable {}

Sources/PowerSync/Kotlin/sync/KotlinSyncStatusData.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,17 @@ extension KotlinProgressWithOperationsProtocol {
103103
}
104104
}
105105

106-
struct KotlinProgressWithOperations: KotlinProgressWithOperationsProtocol {
106+
struct KotlinProgressWithOperations: KotlinProgressWithOperationsProtocol,
107+
// We can't mark PowerSyncKotlin.ProgressWithOperations as Sendable
108+
@unchecked Sendable
109+
{
107110
let base: PowerSyncKotlin.ProgressWithOperations
108111
}
109112

110-
struct KotlinSyncDownloadProgress: KotlinProgressWithOperationsProtocol, SyncDownloadProgress {
113+
struct KotlinSyncDownloadProgress: KotlinProgressWithOperationsProtocol, SyncDownloadProgress,
114+
// We can't mark PowerSyncKotlin.SyncDownloadProgress as Sendable
115+
@unchecked Sendable
116+
{
111117
let progress: PowerSyncKotlin.SyncDownloadProgress
112118

113119
var base: any PowerSyncKotlin.ProgressWithOperations {

Sources/PowerSync/Logger.swift

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,10 @@ import OSLog
33
/// A log writer which prints to the standard output
44
///
55
/// This writer uses `os.Logger` on iOS/macOS/tvOS/watchOS 14+ and falls back to `print` for earlier versions.
6-
public class PrintLogWriter: LogWriterProtocol {
6+
public final class PrintLogWriter: LogWriterProtocol {
77
private let subsystem: String
88
private let category: String
9-
private lazy var logger: Any? = {
10-
if #available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) {
11-
return Logger(subsystem: subsystem, category: category)
12-
}
13-
return nil
14-
}()
9+
private let logger: Sendable?
1510

1611
/// Creates a new PrintLogWriter
1712
/// - Parameters:
@@ -22,6 +17,12 @@ public class PrintLogWriter: LogWriterProtocol {
2217
{
2318
self.subsystem = subsystem
2419
self.category = category
20+
21+
if #available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) {
22+
logger = Logger(subsystem: subsystem, category: category)
23+
} else {
24+
logger = nil
25+
}
2526
}
2627

2728
/// Logs a message with a given severity and optional tag.

0 commit comments

Comments
 (0)