Skip to content

Commit a64555a

Browse files
cleanup
1 parent 4787b8c commit a64555a

File tree

12 files changed

+71
-61
lines changed

12 files changed

+71
-61
lines changed

Demo/PowerSyncExample.xcodeproj/project.pbxproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
B6B3698A2C64F4B30033C307 /* Navigation.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B369892C64F4B30033C307 /* Navigation.swift */; };
4242
B6FFD5322D06DA8000EEE60F /* PowerSync in Frameworks */ = {isa = PBXBuildFile; productRef = B6FFD5312D06DA8000EEE60F /* PowerSync */; };
4343
BE2F26EC2DA54B2F0080F1AE /* SupabaseRemoteStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE2F26EB2DA54B2A0080F1AE /* SupabaseRemoteStorage.swift */; };
44-
BE2F26EE2DA555E10080F1AE /* PhotoPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE2F26ED2DA555DD0080F1AE /* PhotoPicker.swift */; };
4544
/* End PBXBuildFile section */
4645

4746
/* Begin PBXCopyFilesBuildPhase section */
@@ -109,7 +108,6 @@
109108
B6F4213D2BC42F5B0005D0D0 /* sqlite3.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = sqlite3.c; path = "../powersync-kotlin/core/build/interop/sqlite/sqlite3.c"; sourceTree = "<group>"; };
110109
B6F421402BC430B60005D0D0 /* sqlite3.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = sqlite3.h; path = "../powersync-kotlin/core/build/interop/sqlite/sqlite3.h"; sourceTree = "<group>"; };
111110
BE2F26EB2DA54B2A0080F1AE /* SupabaseRemoteStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupabaseRemoteStorage.swift; sourceTree = "<group>"; };
112-
BE2F26ED2DA555DD0080F1AE /* PhotoPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoPicker.swift; sourceTree = "<group>"; };
113111
/* End PBXFileReference section */
114112

115113
/* Begin PBXFrameworksBuildPhase section */
@@ -197,7 +195,6 @@
197195
B65C4D6B2C60D36700176007 /* Screens */ = {
198196
isa = PBXGroup;
199197
children = (
200-
BE2F26ED2DA555DD0080F1AE /* PhotoPicker.swift */,
201198
6A9669032B9EE6FA00B05DCF /* SignInScreen.swift */,
202199
B65C4D6C2C60D38B00176007 /* HomeScreen.swift */,
203200
B65C4D702C60D7D800176007 /* SignUpScreen.swift */,
@@ -574,7 +571,6 @@
574571
B66658632C621CA700159A81 /* AddTodoListView.swift in Sources */,
575572
B666585D2C620E9E00159A81 /* WifiIcon.swift in Sources */,
576573
6A9669042B9EE6FA00B05DCF /* SignInScreen.swift in Sources */,
577-
BE2F26EE2DA555E10080F1AE /* PhotoPicker.swift in Sources */,
578574
6A7315BB2B98BDD30004CB17 /* SystemManager.swift in Sources */,
579575
);
580576
runOnlyForDeploymentPostprocessing = 0;

Demo/PowerSyncExample/Components/TodoListView.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,11 @@ struct TodoListView: View {
6969
}
7070
.onDelete { indexSet in
7171
Task {
72-
if let toDelete = indexSet.map({ todos[$0] }).first {
73-
await delete(todo: toDelete)
72+
let selectedItems = indexSet.compactMap { index in
73+
todos.indices.contains(index) ? todos[index] : nil
74+
}
75+
for try todo in selectedItems {
76+
await delete(todo: todo)
7477
}
7578
}
7679
}

Demo/PowerSyncExample/PowerSync/Schema.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ let lists = Table(
1010
// ID column is automatically included
1111
.text("name"),
1212
.text("created_at"),
13-
.text("owner_id"),
13+
.text("owner_id")
1414
]
1515
)
1616

@@ -26,13 +26,13 @@ let todos = Table(
2626
Column.text("created_at"),
2727
Column.text("completed_at"),
2828
Column.text("created_by"),
29-
Column.text("completed_by"),
29+
Column.text("completed_by")
3030
],
3131
indexes: [
3232
Index(
3333
name: "list_id",
3434
columns: [IndexedColumn.ascending("list_id")]
35-
),
35+
)
3636
]
3737
)
3838

Demo/PowerSyncExample/PowerSync/SupabaseConnector.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,4 +131,8 @@ class SupabaseConnector: PowerSyncBackendConnector {
131131
throw error
132132
}
133133
}
134+
135+
deinit {
136+
observeAuthStateChangesTask?.cancel()
137+
}
134138
}

Demo/PowerSyncExample/PowerSync/SystemManager.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ func getAttachmentsDirectoryPath() throws -> String {
66
for: .documentDirectory,
77
in: .userDomainMask
88
).first else {
9-
throw PowerSyncError.attachmentError("Could not determine attachments directory path")
9+
throw PowerSyncAttachmentError.invalidPath("Could not determine attachments directory path")
1010
}
1111
return documentsURL.appendingPathComponent("attachments").path
1212
}
@@ -112,7 +112,7 @@ class SystemManager {
112112
sql: "DELETE FROM \(LISTS_TABLE) WHERE id = ?",
113113
parameters: [id]
114114
)
115-
115+
116116
// Attachments linked to these will be archived and deleted eventually
117117
// Attachments should be deleted explicitly if required
118118
_ = try transaction.execute(
@@ -184,7 +184,7 @@ class SystemManager {
184184
if let attachments, let photoId = todo.photoId {
185185
try await attachments.deleteFile(
186186
attachmentId: photoId
187-
) { (tx, _) in
187+
) { tx, _ in
188188
try self.deleteTodoInTX(
189189
id: todo.id,
190190
tx: tx
@@ -199,7 +199,7 @@ class SystemManager {
199199
}
200200
}
201201
}
202-
202+
203203
func deleteTodoInTX(id: String, tx: ConnectionContext) throws {
204204
_ = try tx.execute(
205205
sql: "DELETE FROM \(TODOS_TABLE) WHERE id = ?",

Sources/PowerSync/attachments/Attachment.swift

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ public enum AttachmentState: Int {
1010
case synced
1111
/// The attachment is archived
1212
case archived
13+
14+
enum AttachmentStateError: Error {
15+
case invalidState(Int)
16+
}
17+
18+
static func from(_ rawValue: Int) throws -> AttachmentState {
19+
guard let state = AttachmentState(rawValue: rawValue) else {
20+
throw AttachmentStateError.invalidState(rawValue)
21+
}
22+
return state
23+
}
1324
}
1425

1526
/// Struct representing an attachment
@@ -23,8 +34,8 @@ public struct Attachment {
2334
/// Attachment filename, e.g. `[id].jpg`
2435
public let filename: String
2536

26-
/// Current attachment state, represented by the raw value of `AttachmentState`
27-
public let state: Int
37+
/// Current attachment state
38+
public let state: AttachmentState
2839

2940
/// Local URI pointing to the attachment file
3041
public let localUri: String?
@@ -46,7 +57,7 @@ public struct Attachment {
4657
public init(
4758
id: String,
4859
filename: String,
49-
state: Int,
60+
state: AttachmentState,
5061
timestamp: Int = 0,
5162
hasSynced: Int? = 0,
5263
localUri: String? = nil,
@@ -79,7 +90,7 @@ public struct Attachment {
7990
/// - Returns: A new `Attachment` with updated values.
8091
func with(
8192
filename _: String? = nil,
82-
state: Int? = nil,
93+
state: AttachmentState? = nil,
8394
timestamp _: Int = 0,
8495
hasSynced: Int? = 0,
8596
localUri: String? = nil,
@@ -108,7 +119,7 @@ public struct Attachment {
108119
return try Attachment(
109120
id: cursor.getString(name: "id"),
110121
filename: cursor.getString(name: "filename"),
111-
state: cursor.getLong(name: "state"),
122+
state: AttachmentState.from(cursor.getLong(name: "state")),
112123
timestamp: cursor.getLong(name: "timestamp"),
113124
hasSynced: cursor.getLongOptional(name: "has_synced"),
114125
localUri: cursor.getStringOptional(name: "local_uri"),

Sources/PowerSync/attachments/AttachmentContext.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ public class AttachmentContext {
205205
updatedRecord.localUri as Any,
206206
updatedRecord.mediaType ?? NSNull(),
207207
updatedRecord.size ?? NSNull(),
208-
updatedRecord.state,
208+
updatedRecord.state.rawValue,
209209
updatedRecord.hasSynced ?? 0
210210
]
211211
)

Sources/PowerSync/attachments/AttachmentQueue.swift

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ public actor AttachmentQueue {
152152
/// Starts the attachment sync process
153153
public func startSync() async throws {
154154
if closed {
155-
throw NSError(domain: "AttachmentError", code: 4, userInfo: [NSLocalizedDescriptionKey: "Attachment queue has been closed"])
155+
throw PowerSyncAttachmentError.closed("Cannot start syncing on closed attachment queue")
156156
}
157157

158158
// Ensure the directory where attachments are downloaded exists
@@ -251,24 +251,24 @@ public actor AttachmentQueue {
251251
Attachment(
252252
id: item.id,
253253
filename: filename,
254-
state: AttachmentState.queuedDownload.rawValue
254+
state: AttachmentState.queuedDownload
255255
)
256256
)
257-
} else if existingQueueItem!.state == AttachmentState.archived.rawValue {
257+
} else if existingQueueItem!.state == AttachmentState.archived {
258258
// The attachment is present again. Need to queue it for sync.
259259
// We might be able to optimize this in future
260260
if existingQueueItem!.hasSynced == 1 {
261261
// No remote action required, we can restore the record (avoids deletion)
262262
attachmentUpdates.append(
263-
existingQueueItem!.with(state: AttachmentState.synced.rawValue)
263+
existingQueueItem!.with(state: AttachmentState.synced)
264264
)
265265
} else {
266266
// The localURI should be set if the record was meant to be downloaded
267267
// and has been synced. If it's missing and hasSynced is false then
268268
// it must be an upload operation
269269
let newState = existingQueueItem!.localUri == nil ?
270-
AttachmentState.queuedDownload.rawValue :
271-
AttachmentState.queuedUpload.rawValue
270+
AttachmentState.queuedDownload :
271+
AttachmentState.queuedUpload
272272

273273
attachmentUpdates.append(
274274
existingQueueItem!.with(state: newState)
@@ -282,10 +282,10 @@ public actor AttachmentQueue {
282282
* Archive any items not specified in the watched items except for items pending delete.
283283
*/
284284
for attachment in currentAttachments {
285-
if attachment.state != AttachmentState.queuedDelete.rawValue &&
285+
if attachment.state != AttachmentState.queuedDelete &&
286286
items.first(where: { $0.id == attachment.id }) == nil {
287287
attachmentUpdates.append(
288-
attachment.with(state: AttachmentState.archived.rawValue)
288+
attachment.with(state: AttachmentState.archived)
289289
)
290290
}
291291
}
@@ -327,7 +327,7 @@ public actor AttachmentQueue {
327327
let attachment = Attachment(
328328
id: id,
329329
filename: filename,
330-
state: AttachmentState.queuedUpload.rawValue,
330+
state: AttachmentState.queuedUpload,
331331
localUri: localUri,
332332
mediaType: mediaType,
333333
size: fileSize
@@ -352,12 +352,7 @@ public actor AttachmentQueue {
352352
) async throws -> Attachment {
353353
try await attachmentsService.withLock { context in
354354
guard let attachment = try await context.getAttachment(id: attachmentId) else {
355-
// TODO defined errors
356-
throw NSError(
357-
domain: "AttachmentError",
358-
code: 5,
359-
userInfo: [NSLocalizedDescriptionKey: "Attachment record with id \(attachmentId) was not found."]
360-
)
355+
throw PowerSyncAttachmentError.notFound("Attachment record with id \(attachmentId) was not found.")
361356
}
362357

363358
self.logger.debug("Marking attachment as deleted", tag: nil)
@@ -367,7 +362,7 @@ public actor AttachmentQueue {
367362
let updatedAttachment = Attachment(
368363
id: attachment.id,
369364
filename: attachment.filename,
370-
state: AttachmentState.queuedDelete.rawValue,
365+
state: AttachmentState.queuedDelete,
371366
hasSynced: attachment.hasSynced,
372367
localUri: attachment.localUri,
373368
mediaType: attachment.mediaType,

Sources/PowerSync/attachments/FileManagerLocalStorage.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ public class FileManagerStorageAdapter: LocalStorageAdapter {
2929
let url = URL(fileURLWithPath: filePath)
3030

3131
if !fileManager.fileExists(atPath: filePath) {
32-
throw PowerSyncError.fileNotFound(filePath)
32+
throw PowerSyncAttachmentError.fileNotFound(filePath)
3333
}
3434

3535
// Read data from file
3636
do {
3737
return try Data(contentsOf: url)
3838
} catch {
39-
throw PowerSyncError.ioError(error)
39+
throw PowerSyncAttachmentError.ioError(error)
4040
}
4141
}.value
4242
}
@@ -74,7 +74,7 @@ public class FileManagerStorageAdapter: LocalStorageAdapter {
7474
public func copyFile(sourcePath: String, targetPath: String) async throws {
7575
try await Task {
7676
if !fileManager.fileExists(atPath: sourcePath) {
77-
throw PowerSyncError.fileNotFound(sourcePath)
77+
throw PowerSyncAttachmentError.fileNotFound(sourcePath)
7878
}
7979

8080
// Ensure target directory exists

Sources/PowerSync/attachments/LocalStorage.swift

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import Foundation
22

33
/// Error type for PowerSync operations
4-
public enum PowerSyncError: Error {
4+
public enum PowerSyncAttachmentError: Error {
55
/// A general error with an associated message
66
case generalError(String)
7+
8+
/// Indicates no matching attachment record could be found
9+
case notFound(String)
710

811
/// Indicates that a file was not found at the given path
912
case fileNotFound(String)
@@ -13,9 +16,9 @@ public enum PowerSyncError: Error {
1316

1417
/// The given file or directory path was invalid
1518
case invalidPath(String)
16-
17-
/// An error related to attachment handling
18-
case attachmentError(String)
19+
20+
/// The attachments queue or sub services have been closed
21+
case closed(String)
1922
}
2023

2124
/// Protocol defining an adapter interface for local file storage
@@ -26,7 +29,7 @@ public protocol LocalStorageAdapter {
2629
/// - filePath: The full path where the file should be saved.
2730
/// - data: The binary data to save.
2831
/// - Returns: The byte size of the saved file.
29-
/// - Throws: `PowerSyncError` if saving fails.
32+
/// - Throws: `PowerSyncAttachmentError` if saving fails.
3033
func saveFile(
3134
filePath: String,
3235
data: Data
@@ -38,7 +41,7 @@ public protocol LocalStorageAdapter {
3841
/// - filePath: The full path to the file.
3942
/// - mediaType: An optional media type (MIME type) to help determine how to handle the file.
4043
/// - Returns: The contents of the file as `Data`.
41-
/// - Throws: `PowerSyncError` if reading fails or the file doesn't exist.
44+
/// - Throws: `PowerSyncAttachmentError` if reading fails or the file doesn't exist.
4245
func readFile(
4346
filePath: String,
4447
mediaType: String?
@@ -47,34 +50,34 @@ public protocol LocalStorageAdapter {
4750
/// Deletes a file at the specified path.
4851
///
4952
/// - Parameter filePath: The full path to the file to delete.
50-
/// - Throws: `PowerSyncError` if deletion fails or file doesn't exist.
53+
/// - Throws: `PowerSyncAttachmentError` if deletion fails or file doesn't exist.
5154
func deleteFile(filePath: String) async throws
5255

5356
/// Checks if a file exists at the specified path.
5457
///
5558
/// - Parameter filePath: The path to the file.
5659
/// - Returns: `true` if the file exists, `false` otherwise.
57-
/// - Throws: `PowerSyncError` if checking fails.
60+
/// - Throws: `PowerSyncAttachmentError` if checking fails.
5861
func fileExists(filePath: String) async throws -> Bool
5962

6063
/// Creates a directory at the specified path.
6164
///
6265
/// - Parameter path: The full path to the directory.
63-
/// - Throws: `PowerSyncError` if creation fails.
66+
/// - Throws: `PowerSyncAttachmentError` if creation fails.
6467
func makeDir(path: String) async throws
6568

6669
/// Removes a directory at the specified path.
6770
///
6871
/// - Parameter path: The full path to the directory.
69-
/// - Throws: `PowerSyncError` if removal fails.
72+
/// - Throws: `PowerSyncAttachmentError` if removal fails.
7073
func rmDir(path: String) async throws
7174

7275
/// Copies a file from the source path to the target path.
7376
///
7477
/// - Parameters:
7578
/// - sourcePath: The original file path.
7679
/// - targetPath: The destination file path.
77-
/// - Throws: `PowerSyncError` if the copy operation fails.
80+
/// - Throws: `PowerSyncAttachmentError` if the copy operation fails.
7881
func copyFile(
7982
sourcePath: String,
8083
targetPath: String
@@ -87,7 +90,7 @@ public extension LocalStorageAdapter {
8790
///
8891
/// - Parameter filePath: The full path to the file.
8992
/// - Returns: The contents of the file as `Data`.
90-
/// - Throws: `PowerSyncError` if reading fails.
93+
/// - Throws: `PowerSyncAttachmentError` if reading fails.
9194
func readFile(filePath: String) async throws -> Data {
9295
return try await readFile(filePath: filePath, mediaType: nil)
9396
}

0 commit comments

Comments
 (0)