Skip to content
Merged
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
7 changes: 2 additions & 5 deletions Examples/CloudKitDemo/CloudKitDemoApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,8 @@ struct CloudKitDemoApp: App {
try! prepareDependencies {
$0.defaultDatabase = try appDatabase()
$0.defaultSyncEngine = try SyncEngine(
container: CKContainer(identifier: "iCloud.co.pointfree.SQLiteData.demos.CloudKitDemo"),
database: $0.defaultDatabase,
tables: [
Counter.self
]
for: $0.defaultDatabase,
tables: Counter.self
)
}
return true
Expand Down
7 changes: 2 additions & 5 deletions Examples/CloudKitPlayground/CloudKitPlaygroundApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,8 @@ struct CloudKitPlaygroundApp: App {
prepareDependencies {
$0.defaultDatabase = try! appDatabase()
$0.defaultSyncEngine = try! SyncEngine(
container: CKContainer(
identifier: "iCloud.co.pointfree.SQLiteData.demos.CloudKitPlayground"
),
database: $0.defaultDatabase,
tables: [ModelA.self, ModelB.self, ModelC.self]
for: $0.defaultDatabase,
tables: ModelA.self, ModelB.self, ModelC.self
)
}
}
Expand Down
4 changes: 1 addition & 3 deletions Examples/CloudKitPlayground/Schema.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ func appDatabase() throws -> any DatabaseWriter {
let database: any DatabaseWriter
var configuration = Configuration()
configuration.prepareDatabase { db in
try db.attachMetadatabase(
containerIdentifier: "iCloud.co.pointfree.SQLiteData.demos.CloudKitPlayground"
)
try db.attachMetadatabase()
#if DEBUG
db.trace(options: .profile) {
if context == .live {
Expand Down

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

21 changes: 7 additions & 14 deletions Examples/Reminders/RemindersApp.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import CloudKit
import SharingGRDB
import SwiftUI
import UIKit

@main
struct RemindersApp: App {
Expand All @@ -13,17 +14,12 @@ struct RemindersApp: App {
try! prepareDependencies {
$0.defaultDatabase = try Reminders.appDatabase()
$0.defaultSyncEngine = try SyncEngine(
container: CKContainer(
identifier: "iCloud.co.pointfree.SQLiteData.demos.field-timestamps-2.Reminders"
),
database: $0.defaultDatabase,
tables: [
RemindersList.self,
RemindersListAsset.self,
Reminder.self,
Tag.self,
ReminderTag.self,
]
for: $0.defaultDatabase,
tables: RemindersList.self,
RemindersListAsset.self,
Reminder.self,
Tag.self,
ReminderTag.self
)
}
}
Expand All @@ -40,9 +36,6 @@ struct RemindersApp: App {
}
}


import UIKit

class AppDelegate: UIResponder, UIApplicationDelegate, ObservableObject {
func application(
_ application: UIApplication,
Expand Down
4 changes: 1 addition & 3 deletions Examples/Reminders/Schema.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,7 @@ func appDatabase() throws -> any DatabaseWriter {
let database: any DatabaseWriter
var configuration = Configuration()
configuration.prepareDatabase { db in
try db.attachMetadatabase(
containerIdentifier: "iCloud.co.pointfree.SQLiteData.demos.field-timestamps-2.Reminders"
)
try db.attachMetadatabase()
#if DEBUG
db.trace(options: .profile) {
if context == .live {
Expand Down
9 changes: 2 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,13 +260,8 @@ struct MyApp: App {
prepareDependencies {
$0.defaultDatabase = try! appDatabase()
$0.defaultSyncEngine = SyncEngine(
container: CKContainer(
identifier: "iCloud.co.mycompany.MyApp"
),
database: $0.defaultDatabase,
tables: [
Item.self,
]
for: $0.defaultDatabase,
tables: Item.self
)
}
}
Expand Down
28 changes: 14 additions & 14 deletions Sources/SharingGRDBCore/CloudKit/DefaultSyncEngine.swift
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
#if canImport(CloudKit)
import CloudKit
import Dependencies
import GRDB
import CloudKit
import Dependencies
import GRDB

@available(iOS 17, macOS 14, tvOS 17, watchOS 10, *)
extension DependencyValues {
public var defaultSyncEngine: SyncEngine {
get { self[SyncEngine.self] }
set { self[SyncEngine.self] = newValue }
@available(iOS 17, macOS 14, tvOS 17, watchOS 10, *)
extension DependencyValues {
public var defaultSyncEngine: SyncEngine {
get { self[SyncEngine.self] }
set { self[SyncEngine.self] = newValue }
}
}
}

@available(iOS 17, macOS 14, tvOS 17, watchOS 10, *)
extension SyncEngine: TestDependencyKey {
public static var testValue: SyncEngine {
try! SyncEngine(container: .default(), database: DatabaseQueue(), tables: [])
@available(iOS 17, macOS 14, tvOS 17, watchOS 10, *)
extension SyncEngine: TestDependencyKey {
public static var testValue: SyncEngine {
try! SyncEngine(for: DatabaseQueue())
}
}
}
#endif
65 changes: 54 additions & 11 deletions Sources/SharingGRDBCore/CloudKit/SyncEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import CustomDump
import OrderedCollections
import OSLog
import StructuredQueriesCore
import SwiftData

@available(iOS 17, macOS 14, tvOS 17, watchOS 10, *)
public final class SyncEngine: Sendable {
Expand All @@ -24,14 +26,41 @@

let dataManager = Dependency(\.dataManager)

public convenience init(
container: CKContainer,
public convenience init<each T1: PrimaryKeyedTable, each T2: PrimaryKeyedTable>(
for database: any DatabaseWriter,
tables: repeat (each T1).Type,
privateTables: repeat (each T2).Type,
containerIdentifier: String? = nil,
defaultZone: CKRecordZone = CKRecordZone(zoneName: "co.pointfree.SQLiteData.defaultZone"),
database: any DatabaseWriter,
logger: Logger = Logger(subsystem: "SQLiteData", category: "CloudKit"),
tables: [any PrimaryKeyedTable.Type],
privateTables: [any PrimaryKeyedTable.Type] = []
) throws {
logger: Logger = Logger(subsystem: "SQLiteData", category: "CloudKit")
) throws
where
repeat (each T1).PrimaryKey.QueryOutput: IdentifierStringConvertible,
repeat (each T2).PrimaryKey.QueryOutput: IdentifierStringConvertible
{
let containerIdentifier = containerIdentifier
?? ModelConfiguration(groupContainer: .automatic).cloudKitContainerIdentifier

guard let containerIdentifier else {
throw SchemaError(
reason: .noCloudKitContainer,
debugDescription: """
No default CloudKit container found. Please add a container identifier to your app's \
entitlements.
"""
)
}

let container = CKContainer(identifier: containerIdentifier)
var allTables: [any PrimaryKeyedTable.Type] = []
var allPrivateTables: [any PrimaryKeyedTable.Type] = []
for table in repeat each tables {
allTables.append(table)
}
for privateTable in repeat each privateTables {
allPrivateTables.append(privateTable)
}

let userDatabase = UserDatabase(database: database)
try self.init(
container: container,
Expand Down Expand Up @@ -66,8 +95,8 @@
},
userDatabase: userDatabase,
logger: logger,
tables: tables,
privateTables: privateTables
tables: allTables,
privateTables: allPrivateTables
)
_ = try setUpSyncEngine(
userDatabase: userDatabase,
Expand Down Expand Up @@ -1483,7 +1512,7 @@
/// func appDatabase() -> any DatabaseWriter {
/// var configuration = Configuration()
/// configuration.prepareDatabase = { db in
/// db.attachMetadatabase(containerIdentifier: "iCloud.my.company.MyApp")
/// db.attachMetadatabase()
/// …
/// }
/// }
Expand All @@ -1493,7 +1522,20 @@
///
/// - Parameter containerIdentifier: The identifier of the CloudKit container used to synchronize
/// data.
public func attachMetadatabase(containerIdentifier: String) throws {
public func attachMetadatabase(containerIdentifier: String? = nil) throws {
let containerIdentifier = containerIdentifier
?? ModelConfiguration(groupContainer: .automatic).cloudKitContainerIdentifier

guard let containerIdentifier else {
throw SyncEngine.SchemaError(
reason: .noCloudKitContainer,
debugDescription: """
No default CloudKit container found. Please add a container identifier to your app's \
entitlements.
"""
)
}

let databasePath = try SQLQueryExpression(
"""
SELECT "file" FROM pragma_database_list()
Expand Down Expand Up @@ -1539,6 +1581,7 @@
case invalidForeignKeyAction(ForeignKey)
case invalidTableName(String)
case metadatabaseMismatch(attachedPath: String, syncEngineConfiguredPath: String)
case noCloudKitContainer
case nonNullColumnsWithoutDefault(tableName: String, columnNames: [String])
case triggersWithoutSynchronizationCheck([String])
case unknown
Expand Down
Loading
Loading