Skip to content

Commit 2b361e6

Browse files
Add readme and photo capability.
1 parent 71c1ad0 commit 2b361e6

File tree

7 files changed

+306
-95
lines changed

7 files changed

+306
-95
lines changed

.swiftpm/xcode/xcshareddata/xcschemes/PowerSync.xcscheme

Lines changed: 0 additions & 79 deletions
This file was deleted.

Demo/PowerSyncExample.xcodeproj/project.pbxproj

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -713,10 +713,11 @@
713713
CODE_SIGN_STYLE = Automatic;
714714
CURRENT_PROJECT_VERSION = 1;
715715
DEVELOPMENT_ASSET_PATHS = "\"PowerSyncExample/Preview Content\"";
716-
DEVELOPMENT_TEAM = 6WA62GTJNA;
716+
DEVELOPMENT_TEAM = ZGT7463CVJ;
717717
ENABLE_PREVIEWS = YES;
718718
ENABLE_USER_SCRIPT_SANDBOXING = NO;
719719
GENERATE_INFOPLIST_FILE = YES;
720+
INFOPLIST_KEY_NSCameraUsageDescription = "Take Photos for Todo Completion";
720721
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
721722
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
722723
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
@@ -729,7 +730,7 @@
729730
MARKETING_VERSION = 1.0;
730731
ONLY_ACTIVE_ARCH = YES;
731732
OTHER_LDFLAGS = "$(inherited)";
732-
PRODUCT_BUNDLE_IDENTIFIER = com.powersync.PowerSyncExample;
733+
PRODUCT_BUNDLE_IDENTIFIER = com.powersync.PowerSyncSwiftExample;
733734
PRODUCT_NAME = "$(TARGET_NAME)";
734735
SWIFT_EMIT_LOC_STRINGS = YES;
735736
SWIFT_OBJC_BRIDGING_HEADER = "PowerSyncExample/PowerSyncExample-Bridging-Header.h";
@@ -750,10 +751,11 @@
750751
CODE_SIGN_STYLE = Automatic;
751752
CURRENT_PROJECT_VERSION = 1;
752753
DEVELOPMENT_ASSET_PATHS = "\"PowerSyncExample/Preview Content\"";
753-
DEVELOPMENT_TEAM = 6WA62GTJNA;
754+
DEVELOPMENT_TEAM = ZGT7463CVJ;
754755
ENABLE_PREVIEWS = YES;
755756
ENABLE_USER_SCRIPT_SANDBOXING = NO;
756757
GENERATE_INFOPLIST_FILE = YES;
758+
INFOPLIST_KEY_NSCameraUsageDescription = "Take Photos for Todo Completion";
757759
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
758760
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
759761
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
@@ -765,7 +767,7 @@
765767
);
766768
MARKETING_VERSION = 1.0;
767769
OTHER_LDFLAGS = "$(inherited)";
768-
PRODUCT_BUNDLE_IDENTIFIER = com.powersync.PowerSyncExample;
770+
PRODUCT_BUNDLE_IDENTIFIER = com.powersync.PowerSyncSwiftExample;
769771
PRODUCT_NAME = "$(TARGET_NAME)";
770772
SWIFT_EMIT_LOC_STRINGS = YES;
771773
SWIFT_OBJC_BRIDGING_HEADER = "PowerSyncExample/PowerSyncExample-Bridging-Header.h";

Demo/PowerSyncExample/Components/TodoListView.swift

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ struct TodoListView: View {
1010
@State private var error: Error?
1111
@State private var newTodo: NewTodo?
1212
@State private var editing: Bool = false
13-
13+
1414
@State private var selectedImage: UIImage?
15-
@State private var imageData: Data?
15+
// Called when a photo has been captured. Individual widgets should register the listener
16+
@State private var onPhotoCapture: ((_: Data) async throws -> Void)?
1617
@State private var showCamera = false
1718

1819
var body: some View {
@@ -45,7 +46,7 @@ struct TodoListView: View {
4546
}
4647
Task {
4748
do {
48-
_ = try await attachments.deleteFile(attachmentId: attachmentID) { tx, _ in
49+
try await attachments.deleteFile(attachmentId: attachmentID) { tx, _ in
4950
_ = try tx.execute(sql: "UPDATE \(TODOS_TABLE) SET photo_id = NULL WHERE id = ?", parameters: [todo.id])
5051
}
5152
} catch {
@@ -56,6 +57,24 @@ struct TodoListView: View {
5657
},
5758
capturePhotoTapped: {
5859
showCamera = true
60+
// Register a callback for successful image capture
61+
onPhotoCapture = { (_ fileData: Data) in
62+
guard let attachments = system.attachments
63+
else {
64+
return
65+
}
66+
67+
try await attachments.saveFile(
68+
data: fileData,
69+
mediaType: "image/jpeg",
70+
fileExtension: "jpg"
71+
) { tx, record in
72+
_ = try tx.execute(
73+
sql: "UPDATE \(TODOS_TABLE) SET photo_id = ? WHERE id = ?",
74+
parameters: [record.id, todo.id]
75+
)
76+
}
77+
}
5978
}
6079
)
6180
}
@@ -66,7 +85,7 @@ struct TodoListView: View {
6685
}
6786
}
6887
.sheet(isPresented: $showCamera) {
69-
CameraView(imageData: $imageData)
88+
CameraView(onPhotoCapture: $onPhotoCapture)
7089
}
7190
.animation(.default, value: todos)
7291
.navigationTitle("Todos")
@@ -134,9 +153,8 @@ struct TodoListView: View {
134153
}
135154
}
136155

137-
138156
struct CameraView: UIViewControllerRepresentable {
139-
@Binding var imageData: Data?
157+
@Binding var onPhotoCapture: ((_: Data) async throws -> Void)?
140158
@Environment(\.presentationMode) var presentationMode
141159

142160
func makeUIViewController(context: Context) -> UIImagePickerController {
@@ -163,7 +181,15 @@ struct CameraView: UIViewControllerRepresentable {
163181
if let image = info[.originalImage] as? UIImage {
164182
// Convert UIImage to Data
165183
if let jpegData = image.jpegData(compressionQuality: 0.8) {
166-
parent.imageData = jpegData
184+
if let photoCapture = parent.onPhotoCapture {
185+
Task {
186+
do {
187+
try await photoCapture(jpegData)
188+
} catch {
189+
print("Error saving photo: \(error)")
190+
}
191+
}
192+
}
167193
}
168194
}
169195

Demo/PowerSyncExample/PowerSync/SystemManager.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ func getAttachmentsDirectoryPath() throws -> String {
88
).first else {
99
throw PowerSyncError.attachmentError("Could not determine attachments directory path")
1010
}
11-
let r = documentsURL.appendingPathComponent("attachments").path
12-
13-
return r
11+
return documentsURL.appendingPathComponent("attachments").path
1412
}
1513

1614
@Observable

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,7 @@ The PowerSync Swift SDK currently makes use of the [PowerSync Kotlin Multiplatfo
8383
## Migration from Alpha to Beta
8484

8585
See these [developer notes](https://docs.powersync.com/client-sdk-references/swift#migrating-from-the-alpha-to-the-beta-sdk) if you are migrating from the alpha to the beta version of the Swift SDK.
86+
87+
## Attachments
88+
89+
See the attachments [README](./Sources/PowerSync/attachments/README.md) for more information.

Sources/PowerSync/attachments/AttachmentQueue.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public struct WatchedAttachmentItem {
4646
public actor AttachmentQueue {
4747
/// Default name of the attachments table
4848
public static let DEFAULT_TABLE_NAME = "attachments"
49-
49+
5050
let logTag = "AttachmentQueue"
5151

5252
/// PowerSync database client
@@ -304,6 +304,7 @@ public actor AttachmentQueue {
304304
/// - fileExtension: File extension
305305
/// - updateHook: Hook to assign attachment relationships in the same transaction
306306
/// - Returns: The created attachment
307+
@discardableResult
307308
public func saveFile(
308309
data: Data,
309310
mediaType: String,
@@ -343,6 +344,7 @@ public actor AttachmentQueue {
343344
/// - Parameters:
344345
/// - attachmentId: ID of the attachment to delete
345346
/// - updateHook: Hook to perform additional DB updates in the same transaction
347+
@discardableResult
346348
public func deleteFile(
347349
attachmentId: String,
348350
updateHook: @escaping (ConnectionContext, Attachment) throws -> Void
@@ -361,7 +363,7 @@ public actor AttachmentQueue {
361363
hasSynced: attachment.hasSynced,
362364
localUri: attachment.localUri,
363365
mediaType: attachment.mediaType,
364-
size: attachment.size,
366+
size: attachment.size
365367
)
366368

367369
return try self.attachmentsService.upsertAttachment(updatedAttachment, context: tx)

0 commit comments

Comments
 (0)