Skip to content

Commit

Permalink
Merge pull request #1579 from groue/dev/modernize-demo-apps
Browse files Browse the repository at this point in the history
Modernise the demo apps
  • Loading branch information
groue authored Jul 21, 2024
2 parents 1cd6c7c + cdc0131 commit 0454375
Show file tree
Hide file tree
Showing 21 changed files with 126 additions and 170 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
INFOPLIST_FILE = GRDBAsyncDemoTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -373,6 +374,7 @@
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
INFOPLIST_FILE = GRDBAsyncDemoTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -512,7 +514,7 @@
DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = GRDBAsyncDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -534,7 +536,7 @@
DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = GRDBAsyncDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/groue/GRDBQuery",
"state" : {
"revision" : "aefc0d7e7a64e841da33e1c8be7429da1bd9b5d6",
"version" : "0.6.0"
"revision" : "a6c46dd38ecf11a5c37732870dc03a384d582fba",
"version" : "0.9.0"
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,12 @@ import SwiftUI
struct GRDBAsyncDemoApp: App {
var body: some Scene {
WindowGroup {
AppView().environment(\.appDatabase, .shared)
AppView().appDatabase(.shared)
}
}
}

// MARK: - Give SwiftUI access to the database
//
// Define a new environment key that grants access to an AppDatabase.
//
// The technique is documented at
// <https://developer.apple.com/documentation/swiftui/environmentkey>.

private struct AppDatabaseKey: EnvironmentKey {
static var defaultValue: AppDatabase { .empty() }
Expand All @@ -28,13 +23,10 @@ extension EnvironmentValues {
}
}

// In this demo app, views observe the database with the @Query property
// wrapper, defined in the GRDBQuery package. Its documentation recommends to
// define a dedicated initializer for `appDatabase` access, so we comply:

extension Query where Request.DatabaseContext == AppDatabase {
/// Convenience initializer for requests that feed from `AppDatabase`.
init(_ request: Request) {
self.init(request, in: \.appDatabase)
extension View {
func appDatabase(_ appDatabase: AppDatabase) -> some View {
self
.environment(\.appDatabase, appDatabase)
.databaseContext(.readOnly { appDatabase.reader })
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Combine
import GRDB
import GRDBQuery

Expand All @@ -14,37 +13,18 @@ import GRDBQuery
/// List(players) { player in ... )
/// }
/// }
struct PlayerRequest: Queryable {
struct PlayerRequest: ValueObservationQueryable {
enum Ordering {
case byScore
case byName
}

/// The ordering used by the player request.
var ordering: Ordering

// MARK: - Queryable Implementation

static var defaultValue: [Player] { [] }

func publisher(in appDatabase: AppDatabase) -> AnyPublisher<[Player], Error> {
// Build the publisher from the general-purpose read-only access
// granted by `appDatabase.reader`.
// Some apps will prefer to call a dedicated method of `appDatabase`.
ValueObservation
.tracking(fetchValue(_:))
.publisher(
in: appDatabase.reader,
// The `.immediate` scheduling feeds the view right on
// subscription, and avoids an undesired animation when the
// application starts.
scheduling: .immediate)
.eraseToAnyPublisher()
}
/// The ordering used by the player request.
var ordering: Ordering

// This method is not required by Queryable, but it makes it easier
// to test PlayerRequest.
func fetchValue(_ db: Database) throws -> [Player] {
func fetch(_ db: Database) throws -> [Player] {
switch ordering {
case .byScore:
return try Player.all().orderedByScore().fetchAll(db)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ struct AppView: View {
stopEditing()
}))
.toolbar { toolbarContent }
.onChange(of: players) { players in
.onChange(of: players) {
if players.isEmpty {
stopEditing()
}
Expand Down Expand Up @@ -141,14 +141,14 @@ private struct ToggleOrderingButton: View {
}
}

struct AppView_Previews: PreviewProvider {
static var previews: some View {
Group {
// Preview the default, empty database
AppView()
// Preview a database of random players
AppView().environment(\.appDatabase, .random())
}
}
// MARK: - Previews

#Preview("Empty") {
// Preview the default, empty database
AppView()
}

#Preview("Populated") {
// Preview a database of random players
AppView().appDatabase(.random())
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ struct PlayerCreationView: View {
}
}

struct PlayerCreationSheet_Previews: PreviewProvider {
static var previews: some View {
PlayerCreationView()
}
// MARK: - Previews

#Preview {
PlayerCreationView()
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct PlayerEditionView: View {

var body: some View {
PlayerFormView(form: $form)
.onChange(of: isPresented) { isPresented in
.onChange(of: isPresented) {
// Save when back button is pressed
if !isPresented {
Task {
Expand All @@ -30,11 +30,11 @@ struct PlayerEditionView: View {
}
}

struct PlayerEditionView_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
PlayerEditionView(player: Player.makeRandom())
.navigationBarTitle("Player Edition")
}
// MARK: - Previews

#Preview {
NavigationView {
PlayerEditionView(player: Player.makeRandom())
.navigationBarTitle("Player Edition")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,16 @@ extension PlayerForm {
}
}

struct PlayerFormView_Previews: PreviewProvider {
static var previews: some View {
Group {
PlayerFormView(form: .constant(PlayerForm(
name: "",
score: "")))
PlayerFormView(form: .constant(PlayerForm(
name: Player.randomName(),
score: "\(Player.randomScore())")))
}
}
// MARK: - Previews

#Preview("Empty") {
PlayerFormView(form: .constant(PlayerForm(
name: "",
score: "")))
}

#Preview("Prefilled") {
PlayerFormView(form: .constant(PlayerForm(
name: Player.randomName(),
score: "\(Player.randomScore())")))
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@ private struct PlayerRow: View {
}
}

struct PlayerList_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
PlayerList(players: [
Player(id: 1, name: "Arthur", score: 100),
Player(id: 2, name: "Barbara", score: 1000),
])
.navigationTitle("Preview")
}
// MARK: - Previews

#Preview {
NavigationView {
PlayerList(players: [
Player(id: 1, name: "Arthur", score: 100),
Player(id: 2, name: "Barbara", score: 1000),
])
.navigationTitle("Preview")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class PlayerRequestTests: XCTestCase {

// When we fetch players ordered by name
let playerRequest = PlayerRequest(ordering: .byName)
let players = try dbQueue.read(playerRequest.fetchValue)
let players = try dbQueue.read(playerRequest.fetch)

// Then the players are the two players ordered by name
XCTAssertEqual(players, [player1, player2])
Expand All @@ -35,7 +35,7 @@ class PlayerRequestTests: XCTestCase {

// When we fetch players ordered by score
let playerRequest = PlayerRequest(ordering: .byScore)
let players = try dbQueue.read(playerRequest.fetchValue)
let players = try dbQueue.read(playerRequest.fetch)

// Then the players are the two players ordered by score descending
XCTAssertEqual(players, [player2, player1])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
INFOPLIST_FILE = GRDBCombineDemoTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -373,6 +374,7 @@
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
INFOPLIST_FILE = GRDBCombineDemoTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -512,6 +514,7 @@
DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = GRDBCombineDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -533,6 +536,7 @@
DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = GRDBCombineDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/groue/GRDBQuery",
"state" : {
"revision" : "aefc0d7e7a64e841da33e1c8be7429da1bd9b5d6",
"version" : "0.6.0"
"revision" : "a6c46dd38ecf11a5c37732870dc03a384d582fba",
"version" : "0.9.0"
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,12 @@ import SwiftUI
struct GRDBCombineDemoApp: App {
var body: some Scene {
WindowGroup {
AppView().environment(\.appDatabase, .shared)
AppView().appDatabase(.shared)
}
}
}

// MARK: - Give SwiftUI access to the database
//
// Define a new environment key that grants access to an AppDatabase.
//
// The technique is documented at
// <https://developer.apple.com/documentation/swiftui/environmentkey>.

private struct AppDatabaseKey: EnvironmentKey {
static var defaultValue: AppDatabase { .empty() }
Expand All @@ -28,13 +23,10 @@ extension EnvironmentValues {
}
}

// In this demo app, views observe the database with the @Query property
// wrapper, defined in the GRDBQuery package. Its documentation recommends to
// define a dedicated initializer for `appDatabase` access, so we comply:

extension Query where Request.DatabaseContext == AppDatabase {
/// Convenience initializer for requests that feed from `AppDatabase`.
init(_ request: Request) {
self.init(request, in: \.appDatabase)
extension View {
func appDatabase(_ appDatabase: AppDatabase) -> some View {
self
.environment(\.appDatabase, appDatabase)
.databaseContext(.readOnly { appDatabase.reader })
}
}
Loading

0 comments on commit 0454375

Please sign in to comment.