diff --git a/Examples/Examples.xcodeproj/project.pbxproj b/Examples/Examples.xcodeproj/project.pbxproj
index a7d7bc4c..dea4283b 100644
--- a/Examples/Examples.xcodeproj/project.pbxproj
+++ b/Examples/Examples.xcodeproj/project.pbxproj
@@ -76,6 +76,7 @@
DCA44CFB2D5D9D21008D4E76 /* Exceptions for "SyncUps" folder in "SyncUps" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
+ Info.plist,
README.md,
);
target = DCBE89CB2D483FB90071F499 /* SyncUps */;
@@ -884,11 +885,14 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_ENTITLEMENTS = SyncUps/SyncUps.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"SyncUps/Preview Content\"";
+ DEVELOPMENT_TEAM = VFRXY8HC3H;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = SyncUps/Info.plist;
INFOPLIST_KEY_NSSpeechRecognitionUsageDescription = "To transcribe meeting notes.";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
@@ -900,7 +904,7 @@
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = co.pointfree.SyncUps;
+ PRODUCT_BUNDLE_IDENTIFIER = co.pointfree.SQLiteData.SyncUps;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -912,11 +916,14 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_ENTITLEMENTS = SyncUps/SyncUps.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"SyncUps/Preview Content\"";
+ DEVELOPMENT_TEAM = VFRXY8HC3H;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = SyncUps/Info.plist;
INFOPLIST_KEY_NSSpeechRecognitionUsageDescription = "To transcribe meeting notes.";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
@@ -928,7 +935,7 @@
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = co.pointfree.SyncUps;
+ PRODUCT_BUNDLE_IDENTIFIER = co.pointfree.SQLiteData.SyncUps;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -1006,7 +1013,7 @@
/* Begin XCLocalSwiftPackageReference section */
DCD9AC892E02176700FB20F8 /* XCLocalSwiftPackageReference ".." */ = {
isa = XCLocalSwiftPackageReference;
- relativePath = "..";
+ relativePath = ..;
};
/* End XCLocalSwiftPackageReference section */
diff --git a/Examples/Examples.xcodeproj/xcshareddata/xcschemes/CloudKitDemo.xcscheme b/Examples/Examples.xcodeproj/xcshareddata/xcschemes/CloudKitDemo.xcscheme
deleted file mode 100644
index 46a630af..00000000
--- a/Examples/Examples.xcodeproj/xcshareddata/xcschemes/CloudKitDemo.xcscheme
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Examples/SyncUpTests/Internal.swift b/Examples/SyncUpTests/Internal.swift
index c3d9251f..4db25057 100644
--- a/Examples/SyncUpTests/Internal.swift
+++ b/Examples/SyncUpTests/Internal.swift
@@ -4,7 +4,7 @@ import SQLiteData
@testable import SyncUps
extension Database {
- func seedSyncUpFormTests() throws {
+ func seed() throws {
try seed {
SyncUp(id: UUID(1), seconds: 60, theme: .appOrange, title: "Design")
SyncUp(id: UUID(2), seconds: 60 * 10, theme: .periwinkle, title: "Engineering")
diff --git a/Examples/SyncUpTests/SyncUpFormTests.swift b/Examples/SyncUpTests/SyncUpFormTests.swift
index a1aa462a..cc383b36 100644
--- a/Examples/SyncUpTests/SyncUpFormTests.swift
+++ b/Examples/SyncUpTests/SyncUpFormTests.swift
@@ -9,8 +9,10 @@ import Testing
@Suite(
.dependencies {
- $0.defaultDatabase = try! SyncUps.appDatabase()
- try! $0.defaultDatabase.write { try $0.seedSyncUpFormTests() }
+ try $0.bootstrapDatabase()
+ try $0.defaultDatabase.write { db in
+ try db.seed()
+ }
$0.uuid = .incrementing
}
)
diff --git a/Examples/SyncUps/App.swift b/Examples/SyncUps/App.swift
index bce63a1c..608046a4 100644
--- a/Examples/SyncUps/App.swift
+++ b/Examples/SyncUps/App.swift
@@ -77,8 +77,6 @@ struct AppView: View {
}
#Preview("Happy path") {
- let _ = try! prepareDependencies {
- $0.defaultDatabase = try SyncUps.appDatabase()
- }
+ let _ = try! prepareDependencies { try $0.bootstrapDatabase() }
AppView(model: AppModel())
}
diff --git a/Examples/SyncUps/Info.plist b/Examples/SyncUps/Info.plist
new file mode 100644
index 00000000..ca9a074a
--- /dev/null
+++ b/Examples/SyncUps/Info.plist
@@ -0,0 +1,10 @@
+
+
+
+
+ UIBackgroundModes
+
+ remote-notification
+
+
+
diff --git a/Examples/SyncUps/Schema.swift b/Examples/SyncUps/Schema.swift
index 8deead50..51a152f1 100644
--- a/Examples/SyncUps/Schema.swift
+++ b/Examples/SyncUps/Schema.swift
@@ -75,73 +75,76 @@ extension Int {
}
}
-func appDatabase() throws -> any DatabaseWriter {
- @Dependency(\.context) var context
- var configuration = Configuration()
- configuration.foreignKeysEnabled = true
- configuration.prepareDatabase { db in
- #if DEBUG
- db.trace(options: .profile) {
- if context == .preview {
- print("\($0.expandedDescription)")
- } else {
- logger.debug("\($0.expandedDescription)")
+extension DependencyValues {
+ mutating func bootstrapDatabase() throws {
+ @Dependency(\.context) var context
+ var configuration = Configuration()
+ configuration.foreignKeysEnabled = true
+ configuration.prepareDatabase { db in
+ #if DEBUG
+ db.trace(options: .profile) {
+ if context == .preview {
+ print("\($0.expandedDescription)")
+ } else {
+ logger.debug("\($0.expandedDescription)")
+ }
}
- }
- #endif
- }
- let database = try SQLiteData.defaultDatabase(configuration: configuration)
- logger.debug(
- """
- App database:
- open "\(database.path)"
- """
- )
- var migrator = DatabaseMigrator()
- #if DEBUG
- migrator.eraseDatabaseOnSchemaChange = true
- #endif
- migrator.registerMigration("Create initial tables") { db in
- try #sql(
+ #endif
+ }
+ let database = try SQLiteData.defaultDatabase(configuration: configuration)
+ logger.debug(
"""
- CREATE TABLE "syncUps" (
- "id" TEXT PRIMARY KEY NOT NULL ON CONFLICT REPLACE DEFAULT (uuid()),
- "seconds" INTEGER NOT NULL DEFAULT 300,
- "theme" TEXT NOT NULL DEFAULT \(raw: Theme.bubblegum.rawValue),
- "title" TEXT NOT NULL
- )
+ App database:
+ open "\(database.path)"
"""
)
- .execute(db)
- try #sql(
- """
- CREATE TABLE "attendees" (
- "id" TEXT PRIMARY KEY NOT NULL ON CONFLICT REPLACE DEFAULT (uuid()),
- "name" TEXT NOT NULL,
- "syncUpID" INTEGER NOT NULL,
-
- FOREIGN KEY("syncUpID") REFERENCES "syncUps"("id") ON DELETE CASCADE
+ var migrator = DatabaseMigrator()
+ #if DEBUG
+ migrator.eraseDatabaseOnSchemaChange = true
+ #endif
+ migrator.registerMigration("Create initial tables") { db in
+ try #sql(
+ """
+ CREATE TABLE "syncUps" (
+ "id" TEXT PRIMARY KEY NOT NULL ON CONFLICT REPLACE DEFAULT (uuid()),
+ "seconds" INTEGER NOT NULL ON CONFLICT REPLACE DEFAULT 300,
+ "theme" TEXT NOT NULL ON CONFLICT REPLACE DEFAULT \(raw: Theme.bubblegum.rawValue),
+ "title" TEXT NOT NULL ON CONFLICT REPLACE DEFAULT ''
+ ) STRICT
+ """
)
- """
- )
- .execute(db)
- try #sql(
- """
- CREATE TABLE "meetings" (
- "id" TEXT PRIMARY KEY NOT NULL ON CONFLICT REPLACE DEFAULT (uuid()),
- "date" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP UNIQUE,
- "syncUpID" INTEGER NOT NULL,
- "transcript" TEXT NOT NULL,
-
- FOREIGN KEY("syncUpID") REFERENCES "syncUps"("id") ON DELETE CASCADE
+ .execute(db)
+ try #sql(
+ """
+ CREATE TABLE "attendees" (
+ "id" TEXT PRIMARY KEY NOT NULL ON CONFLICT REPLACE DEFAULT (uuid()),
+ "name" TEXT NOT NULL ON CONFLICT REPLACE DEFAULT '',
+ "syncUpID" TEXT NOT NULL REFERENCES "syncUps"("id") ON DELETE CASCADE
+ ) STRICT
+ """
)
- """
+ .execute(db)
+ try #sql(
+ """
+ CREATE TABLE "meetings" (
+ "id" TEXT PRIMARY KEY NOT NULL ON CONFLICT REPLACE DEFAULT (uuid()),
+ "date" TEXT NOT NULL ON CONFLICT REPLACE DEFAULT CURRENT_TIMESTAMP,
+ "syncUpID" TEXT NOT NULL REFERENCES "syncUps"("id") ON DELETE CASCADE,
+ "transcript" TEXT NOT NULL ON CONFLICT REPLACE DEFAULT ''
+ ) STRICT
+ """
+ )
+ .execute(db)
+ }
+ try migrator.migrate(database)
+ defaultDatabase = database
+ defaultSyncEngine = try SyncEngine(
+ for: database,
+ tables: SyncUp.self,
+ Attendee.self,
+ Meeting.self
)
- .execute(db)
}
-
- try migrator.migrate(database)
- return database
}
private let logger = Logger(subsystem: "SyncUps", category: "Database")
diff --git a/Examples/SyncUps/SyncUpDetail.swift b/Examples/SyncUps/SyncUpDetail.swift
index f1568169..50accb52 100644
--- a/Examples/SyncUps/SyncUpDetail.swift
+++ b/Examples/SyncUps/SyncUpDetail.swift
@@ -272,7 +272,7 @@ struct MeetingView: View {
#Preview {
let syncUp = try! prepareDependencies {
- $0.defaultDatabase = try SyncUps.appDatabase()
+ try $0.bootstrapDatabase()
return try $0.defaultDatabase.read { db in
try SyncUp.limit(1).fetchOne(db)!
}
diff --git a/Examples/SyncUps/SyncUps.entitlements b/Examples/SyncUps/SyncUps.entitlements
new file mode 100644
index 00000000..c54cf631
--- /dev/null
+++ b/Examples/SyncUps/SyncUps.entitlements
@@ -0,0 +1,16 @@
+
+
+
+
+ aps-environment
+ development
+ com.apple.developer.icloud-container-identifiers
+
+ iCloud.co.pointfree.SQLiteData.SyncUps
+
+ com.apple.developer.icloud-services
+
+ CloudKit
+
+
+
diff --git a/Examples/SyncUps/SyncUpsApp.swift b/Examples/SyncUps/SyncUpsApp.swift
index 97e1cd4c..83abea24 100644
--- a/Examples/SyncUps/SyncUpsApp.swift
+++ b/Examples/SyncUps/SyncUpsApp.swift
@@ -8,7 +8,7 @@ struct SyncUpsApp: App {
init() {
if !isTesting {
try! prepareDependencies {
- $0.defaultDatabase = try SyncUps.appDatabase()
+ try $0.bootstrapDatabase()
}
}
}
diff --git a/Examples/SyncUps/SyncUpsList.swift b/Examples/SyncUps/SyncUpsList.swift
index 8d065080..85d4bf9d 100644
--- a/Examples/SyncUps/SyncUpsList.swift
+++ b/Examples/SyncUps/SyncUpsList.swift
@@ -153,7 +153,7 @@ private struct SeedDatabaseTip: Tip {
#Preview {
let _ = try! prepareDependencies {
- $0.defaultDatabase = try SyncUps.appDatabase()
+ try $0.bootstrapDatabase()
}
NavigationStack {
SyncUpsList(model: SyncUpsListModel())