Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/build_and_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,20 @@ jobs:
xcodebuild test -scheme PowerSync -destination "platform=iOS Simulator,name=iPhone 16"
xcodebuild test -scheme PowerSync -destination "platform=macOS,arch=arm64,name=My Mac"
xcodebuild test -scheme PowerSync -destination "platform=watchOS Simulator,arch=arm64,name=Apple Watch Ultra 2 (49mm)"

buildSwift6:
name: Build and test with Swift 6
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Set up XCode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- name: Use Swift 6
run: |
sed -i '' 's|// swift-tools-version:[0-9.]*|// swift-tools-version:6.1|' Package.swift
- name: Build and Test
run: |
swift build -Xswiftc -strict-concurrency=complete
swift test -Xswiftc -strict-concurrency=complete
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc

.vscode
.sourcekit-lsp

Secrets.swift

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 6 additions & 5 deletions Demo/PowerSyncExample/PowerSync/SystemManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ func getAttachmentsDirectoryPath() throws -> String {

let logTag = "SystemManager"

@MainActor
@Observable
class SystemManager {
let connector = SupabaseConnector()
Expand Down Expand Up @@ -225,23 +226,23 @@ class SystemManager {
if let attachments, let photoId = todo.photoId {
try await attachments.deleteFile(
attachmentId: photoId
) { tx, _ in
) { transaction, _ in
try self.deleteTodoInTX(
id: todo.id,
tx: tx
tx: transaction
)
}
} else {
try await db.writeTransaction { tx in
try await db.writeTransaction { transaction in
try self.deleteTodoInTX(
id: todo.id,
tx: tx
tx: transaction
)
}
}
}

private func deleteTodoInTX(id: String, tx: ConnectionContext) throws {
private nonisolated func deleteTodoInTX(id: String, tx: ConnectionContext) throws {
_ = try tx.execute(
sql: "DELETE FROM \(TODOS_TABLE) WHERE id = ?",
parameters: [id]
Expand Down
9 changes: 9 additions & 0 deletions Demo/StructuredQueriesExample/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Structured Queries Example

This used PowerSync along side the [structured-queries](https://github.com/pointfreeco/swift-structured-queries) library to perform DB operations using a typed query builder syntax.

This demo can be executed with

```bash
swift run StructuredQueriesExample
```
99 changes: 99 additions & 0 deletions Demo/StructuredQueriesExample/Sources/entry.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import Foundation
import PowerSync
import PowerSyncStructuredQueries
import StructuredQueries

@Table("users")
struct User {
var id: String
var name: String
var birthday: Date?
}

@Table("posts")
struct Post {
var id: String
var description: String
@Column("user_id")
var userId: String
}

@Selection
struct JoinedResult {
let postDescription: String
let userName: String
}

@main
struct Main {
static func main() async throws {
// TODO, check if the schema can be shared in some way
let powersync = PowerSyncDatabase(
schema: Schema(
tables: [
Table(
name: "users",
columns: [
.text("name"),
.text("birthday")
]
),
Table(
name: "posts",
columns: [
.text("description"),
.text("user_id")
]
),
],
),
dbFilename: "tests.sqlite"
)

let testUserID = UUID().uuidString

try await User.insert {
($0.id, $0.name, $0.birthday)
} values: {
(testUserID, "Steven", Date())
}.execute(powersync)

try await User.insert {
User(
id: UUID().uuidString,
name: "Nevets"
)
}.execute(powersync)

let users = try await User.all.fetchAll(powersync)
print("The users are:")
for user in users {
print(user)
}

let posts = try await Post.all.fetchAll(powersync)
print("The posts are:")
for post in posts {
print(post)
}

try await Post.insert {
Post(
id: UUID().uuidString, description: "A Post", userId: testUserID
)
}.execute(powersync)

print("Joined posts are:")
let joinedPosts = try await Post.join(User.all) { $0.userId == $1.id }
.select {
JoinedResult.Columns(
postDescription: $0.description,
userName: $1.name
)
}
.fetchAll(powersync)
for joinedResult in joinedPosts {
print(joinedResult)
}
}
}
54 changes: 54 additions & 0 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 31 additions & 7 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let packageName = "PowerSync"

// Set this to the absolute path of your Kotlin SDK checkout if you want to use a local Kotlin
// build. Also see docs/LocalBuild.md for details
let localKotlinSdkOverride: String? = nil
let localKotlinSdkOverride: String? = "/Users/stevenontong/Documents/platform_code/powersync/powersync-kotlin"

// Set this to the absolute path of your powersync-sqlite-core checkout if you want to use a
// local build of the core extension.
Expand Down Expand Up @@ -53,27 +54,50 @@ let package = Package(
platforms: [
.iOS(.v13),
.macOS(.v10_15),
.watchOS(.v9)
.watchOS(.v9),
],
products: [
// Products define the executables and libraries a package produces, making them visible to other packages.
.library(
name: packageName,
targets: ["PowerSync"]),
targets: ["PowerSync"]
),
.library(
name: "PowerSyncStructuredQueries",
targets: ["PowerSyncStructuredQueries"]
),
],
dependencies: conditionalDependencies,
dependencies: [
.package(url: "https://github.com/pointfreeco/swift-structured-queries", from: "0.4.0"),
] + conditionalDependencies,
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies.
.target(
name: packageName,
dependencies: [
kotlinTargetDependency,
.product(name: "PowerSyncSQLiteCore", package: corePackageName)
]),
.product(name: "PowerSyncSQLiteCore", package: corePackageName),
]
),
.testTarget(
name: "PowerSyncTests",
dependencies: ["PowerSync"]
dependencies: ["PowerSync"],
),
.target(
name: "PowerSyncStructuredQueries",
dependencies: [
.byName(name: packageName),
.product(name: "StructuredQueries", package: "swift-structured-queries"),
],
path: "Sources/StructuredQueries"
),
.executableTarget(
name: "StructuredQueriesExample",
dependencies: [
.byName(name: "PowerSyncStructuredQueries"),
],
path: "Demo/StructuredQueriesExample"
),
] + conditionalTargets
)
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,22 @@ This is the PowerSync SDK for Swift clients. The SDK reference is available [her

## Structure: Packages

- [Sources](./Sources/)
- [Sources](./Sources/PowerSync)

- This is the Swift SDK implementation.

- [Sources](./Sources/StructuredQueries)

- A typed query builder using [structured-queries](https://github.com/pointfreeco/swift-structured-queries).

## Demo Apps / Example Projects

The easiest way to test the PowerSync Swift SDK is to run our demo application.

- [Demo/PowerSyncExample](./Demo/README.md): A simple to-do list application demonstrating the use of the PowerSync Swift SDK using a Supabase connector.

- [Demo/StructuredQueriesExample](./Demo/StructuredQueriesExample/README.md): A simple Swift executable which uses the `PowerSyncStructuredQueries` library.

## Installation

Add
Expand Down
Loading
Loading