From e8f893597ce6884b385c7edb83677adb4f4bd9fb Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Fri, 2 May 2025 16:33:21 +0200 Subject: [PATCH 1/3] Enable macOS support for demo --- .../project.pbxproj | 12 +++++++-- .../Components/TodoListRow.swift | 8 ++++++ .../Components/TodoListView.swift | 25 +++++++++++++++++++ .../Screens/SignInScreen.swift | 8 ++++-- .../Screens/SignUpScreen.swift | 6 ++++- 5 files changed, 54 insertions(+), 5 deletions(-) diff --git a/Demo/PowerSyncExample.xcodeproj/project.pbxproj b/Demo/PowerSyncExample.xcodeproj/project.pbxproj index e814d01..4f881e4 100644 --- a/Demo/PowerSyncExample.xcodeproj/project.pbxproj +++ b/Demo/PowerSyncExample.xcodeproj/project.pbxproj @@ -709,7 +709,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"PowerSyncExample/Preview Content\""; - DEVELOPMENT_TEAM = ZGT7463CVJ; + DEVELOPMENT_TEAM = W284TED275; ENABLE_PREVIEWS = YES; ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; @@ -728,6 +728,10 @@ OTHER_LDFLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.powersync.PowerSyncSwiftExample; PRODUCT_NAME = "$(TARGET_NAME)"; + REGISTER_APP_GROUPS = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = "PowerSyncExample/PowerSyncExample-Bridging-Header.h"; "SWIFT_OBJC_BRIDGING_HEADER[arch=*]" = ""; @@ -747,7 +751,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"PowerSyncExample/Preview Content\""; - DEVELOPMENT_TEAM = ZGT7463CVJ; + DEVELOPMENT_TEAM = W284TED275; ENABLE_PREVIEWS = YES; ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; @@ -765,6 +769,10 @@ OTHER_LDFLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = com.powersync.PowerSyncSwiftExample; PRODUCT_NAME = "$(TARGET_NAME)"; + REGISTER_APP_GROUPS = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = "PowerSyncExample/PowerSyncExample-Bridging-Header.h"; SWIFT_VERSION = 5.0; diff --git a/Demo/PowerSyncExample/Components/TodoListRow.swift b/Demo/PowerSyncExample/Components/TodoListRow.swift index f3c3be7..9b841ef 100644 --- a/Demo/PowerSyncExample/Components/TodoListRow.swift +++ b/Demo/PowerSyncExample/Components/TodoListRow.swift @@ -8,11 +8,14 @@ struct TodoListRow: View { let capturePhotoTapped: () -> Void let selectPhotoTapped: () -> Void +#if os(iOS) @State private var image: UIImage? = nil +#endif var body: some View { HStack { Text(todo.description) +#if os(iOS) Group { if let image = image { Image(uiImage: image) @@ -34,6 +37,7 @@ struct TodoListRow: View { EmptyView() } } +#endif Spacer() VStack { if todo.photoId == nil { @@ -69,14 +73,17 @@ struct TodoListRow: View { } .buttonStyle(.plain) }.onChange(of: todo.photoId) { _, newPhotoId in +#if os(iOS) if newPhotoId == nil { // Clear the image when photoId becomes nil image = nil } +#endif } } } +#if os(iOS) private func loadImage() async { guard let urlString = todo.photoUri else { return } let url = URL(fileURLWithPath: urlString) @@ -92,6 +99,7 @@ struct TodoListRow: View { print("Error loading image from disk:", error) } } +#endif } #Preview { diff --git a/Demo/PowerSyncExample/Components/TodoListView.swift b/Demo/PowerSyncExample/Components/TodoListView.swift index ea7d4f7..973bc6a 100644 --- a/Demo/PowerSyncExample/Components/TodoListView.swift +++ b/Demo/PowerSyncExample/Components/TodoListView.swift @@ -12,11 +12,13 @@ struct TodoListView: View { @State private var newTodo: NewTodo? @State private var editing: Bool = false +#if os(iOS) // Called when a photo has been captured. Individual widgets should register the listener @State private var onMediaSelect: ((_: Data) async throws -> Void)? @State private var pickMediaType: UIImagePickerController.SourceType = .camera @State private var showMediaPicker = false @State private var isCameraAvailable: Bool = false +#endif var body: some View { List { @@ -33,6 +35,7 @@ struct TodoListView: View { } ForEach(todos) { todo in +#if os(iOS) TodoListRow( todo: todo, isCameraAvailable: isCameraAvailable, @@ -68,6 +71,20 @@ struct TodoListView: View { pickMediaType = .photoLibrary showMediaPicker = true } +#else + TodoListRow( + todo: todo, + isCameraAvailable: false, + completeTapped: { + Task { + await toggleCompletion(of: todo) + } + }, + deletePhotoTapped: {}, + capturePhotoTapped: {}, + selectPhotoTapped: {}, + ) +#endif } .onDelete { indexSet in Task { @@ -80,12 +97,14 @@ struct TodoListView: View { } } } +#if os(iOS) .sheet(isPresented: $showMediaPicker) { CameraView( onMediaSelect: $onMediaSelect, mediaType: $pickMediaType ) } +#endif .animation(.default, value: todos) .navigationTitle("Todos") .toolbar { @@ -111,9 +130,11 @@ struct TodoListView: View { } } } +#if os(iOS) .onAppear { checkCameraAvailability() } +#endif .task { await system.watchTodos(listId) { tds in withAnimation { @@ -144,6 +165,7 @@ struct TodoListView: View { } } +#if os(iOS) /// Registers a callback which saves a photo for the specified Todo item if media is sucessfully loaded. func registerMediaCallback(todo: Todo) { // Register a callback for successful image capture @@ -181,6 +203,7 @@ struct TodoListView: View { isCameraAvailable = UIImagePickerController.isSourceTypeAvailable(.camera) #endif } +#endif } #Preview { @@ -191,6 +214,7 @@ struct TodoListView: View { } } +#if os(iOS) struct CameraView: UIViewControllerRepresentable { @Binding var onMediaSelect: ((_: Data) async throws -> Void)? @Binding var mediaType: UIImagePickerController.SourceType @@ -244,3 +268,4 @@ struct CameraView: UIViewControllerRepresentable { } } } +#endif diff --git a/Demo/PowerSyncExample/Screens/SignInScreen.swift b/Demo/PowerSyncExample/Screens/SignInScreen.swift index 40e7c95..ce9d67e 100644 --- a/Demo/PowerSyncExample/Screens/SignInScreen.swift +++ b/Demo/PowerSyncExample/Screens/SignInScreen.swift @@ -19,15 +19,19 @@ struct SignInScreen: View { Form { Section { TextField("Email", text: $email) - .keyboardType(.emailAddress) .textContentType(.emailAddress) .autocorrectionDisabled() +#if os(iOS) + .keyboardType(.emailAddress) .textInputAutocapitalization(.never) - +#endif + SecureField("Password", text: $password) .textContentType(.password) .autocorrectionDisabled() +#if os(iOS) .textInputAutocapitalization(.never) +#endif } Section { diff --git a/Demo/PowerSyncExample/Screens/SignUpScreen.swift b/Demo/PowerSyncExample/Screens/SignUpScreen.swift index bf9bb5e..0d2693a 100644 --- a/Demo/PowerSyncExample/Screens/SignUpScreen.swift +++ b/Demo/PowerSyncExample/Screens/SignUpScreen.swift @@ -20,15 +20,19 @@ struct SignUpScreen: View { Form { Section { TextField("Email", text: $email) - .keyboardType(.emailAddress) .textContentType(.emailAddress) .autocorrectionDisabled() +#if os(ios) + .autocorrectionDisabled() .textInputAutocapitalization(.never) +#endif SecureField("Password", text: $password) .textContentType(.password) .autocorrectionDisabled() +#if os(ios) .textInputAutocapitalization(.never) +#endif } Section { From e83724b3787fce49a6c3cd1d110491f4fe2cdc37 Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Wed, 7 May 2025 15:27:38 +0200 Subject: [PATCH 2/3] Update package URL to point to releasee --- Package.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Package.swift b/Package.swift index 79058b9..8311db2 100644 --- a/Package.swift +++ b/Package.swift @@ -27,8 +27,7 @@ if let kotlinSdkPath = localKotlinSdkOverride { // Not using a local build, so download from releases conditionalTargets.append(.binaryTarget( name: "PowerSyncKotlin", - // TODO: Use GitHub release once https://github.com/powersync-ja/powersync-kotlin/releases/tag/untagged-fde4386dec502ec27067 is published - url: "https://fsn1.your-objectstorage.com/simon-public/powersync.zip", + url: "https://github.com/powersync-ja/powersync-kotlin/releases/download/1.1.0/PowersyncKotlinRelease.zip", checksum: "b6770dc22ae31315adc599e653fea99614226312fe861dbd8764e922a5a83b09" )) } From 84498d280966423c91eb5b8ed7287099df33e8e2 Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Wed, 7 May 2025 15:30:40 +0200 Subject: [PATCH 3/3] Prepare release --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 279d898..68b5b87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## unreleased +## 1.1.0 * Add sync progress information through `SyncStatusData.downloadProgress`. * Add `trackPreviousValues` option on `Table` which sets `CrudEntry.previousValues` to previous values on updates.