From 0d02f22bccee1c8b2373af7cf6c4f32f4dc4a9cb Mon Sep 17 00:00:00 2001 From: Siarhei Yakushevich Date: Thu, 24 Apr 2025 11:59:46 +0200 Subject: [PATCH 1/2] struct QueryPublisherPrintConfiguration for printing publisher state in query was added. Query's constructor methods were changed. GRDBQuery/Query.swift: the configuration is used in publisher's print method. --- .../QueryDemo/QueryDemo/Views/AppView.swift | 2 +- Sources/GRDBQuery/Query+DatabaseContext.swift | 21 +++++-- Sources/GRDBQuery/Query+VoidContext.swift | 21 +++++-- Sources/GRDBQuery/Query.swift | 58 +++++++++++++++---- 4 files changed, 79 insertions(+), 23 deletions(-) diff --git a/Documentation/QueryDemo/QueryDemo/Views/AppView.swift b/Documentation/QueryDemo/QueryDemo/Views/AppView.swift index 841b3b2..a4c8235 100644 --- a/Documentation/QueryDemo/QueryDemo/Views/AppView.swift +++ b/Documentation/QueryDemo/QueryDemo/Views/AppView.swift @@ -10,7 +10,7 @@ struct AppView: View { var id: Int64 } - @Query(AnyPlayerRequest()) + @Query(AnyPlayerRequest(), printPublisherConfiguration: .init(prefix: "\(#function)")) private var player: Player? @State private var editedPlayer: EditedPlayer? diff --git a/Sources/GRDBQuery/Query+DatabaseContext.swift b/Sources/GRDBQuery/Query+DatabaseContext.swift index 39cefbb..eb95f9b 100644 --- a/Sources/GRDBQuery/Query+DatabaseContext.swift +++ b/Sources/GRDBQuery/Query+DatabaseContext.swift @@ -21,9 +21,12 @@ extension Query where Request.Context == DatabaseContext { /// /// - parameter request: An initial ``Queryable`` request. public init( - _ request: Request + _ request: Request, + printPublisherConfiguration: QueryPublisherPrintConfiguration? = nil ) { - self.init(request, in: \.databaseContext) + self.init(request, + in: \.databaseContext, + printPublisherConfiguration: printPublisherConfiguration) } /// Creates a `Query` that feeds from the `databaseContext` @@ -50,9 +53,12 @@ extension Query where Request.Context == DatabaseContext { /// /// - parameter request: A ``Queryable`` request. public init( - constant request: Request + constant request: Request, + printPublisherConfiguration: QueryPublisherPrintConfiguration? = nil ) { - self.init(constant: request, in: \.databaseContext) + self.init(constant: request, + in: \.databaseContext, + printPublisherConfiguration: printPublisherConfiguration) } /// Creates a `Query` that feeds from the `databaseContext` @@ -88,8 +94,11 @@ extension Query where Request.Context == DatabaseContext { /// /// - parameter request: A SwiftUI binding to a ``Queryable`` request. public init( - _ request: Binding + _ request: Binding, + printPublisherConfiguration: QueryPublisherPrintConfiguration? = nil ) { - self.init(request, in: \.databaseContext) + self.init(request, + in: \.databaseContext, + printPublisherConfiguration: printPublisherConfiguration) } } diff --git a/Sources/GRDBQuery/Query+VoidContext.swift b/Sources/GRDBQuery/Query+VoidContext.swift index 4dfd0e5..7ccd503 100644 --- a/Sources/GRDBQuery/Query+VoidContext.swift +++ b/Sources/GRDBQuery/Query+VoidContext.swift @@ -29,8 +29,11 @@ extension Query where Request.Context == Void { /// ``` /// /// - parameter request: An initial ``Queryable`` request. - public init(_ request: Request) { - self.init(request, in: \.void) + public init(_ request: Request, + printPublisherConfiguration: QueryPublisherPrintConfiguration? = nil) { + self.init(request, + in: \.void, + printPublisherConfiguration: printPublisherConfiguration) } /// Creates a `Query`, given a SwiftUI binding to a ``Queryable`` @@ -73,8 +76,11 @@ extension Query where Request.Context == Void { /// ``` /// /// - parameter request: A SwiftUI binding to a ``Queryable`` request. - public init(_ request: Binding) { - self.init(request, in: \.void) + public init(_ request: Binding, + printPublisherConfiguration: QueryPublisherPrintConfiguration? = nil) { + self.init(request, + in: \.void, + printPublisherConfiguration: printPublisherConfiguration) } /// Creates a `Query`, given a ``Queryable`` request that uses @@ -109,8 +115,11 @@ extension Query where Request.Context == Void { /// ``` /// /// - parameter request: A ``Queryable`` request. - public init(constant request: Request) { - self.init(constant:request, in: \.void) + public init(constant request: Request, + printPublisherConfiguration: QueryPublisherPrintConfiguration? = nil) { + self.init(constant:request, + in: \.void, + printPublisherConfiguration: printPublisherConfiguration) } } diff --git a/Sources/GRDBQuery/Query.swift b/Sources/GRDBQuery/Query.swift index 9da43d8..db4a971 100644 --- a/Sources/GRDBQuery/Query.swift +++ b/Sources/GRDBQuery/Query.swift @@ -1,6 +1,16 @@ import Combine import SwiftUI +public struct QueryPublisherPrintConfiguration { + public let prefix: String + public let outputStream: (any TextOutputStream)? + + public init(prefix: String = "", outputStream: (any TextOutputStream)? = nil) { + self.prefix = prefix + self.outputStream = outputStream + } +} + // See Documentation.docc/Extensions/Query.md @propertyWrapper @MainActor public struct Query { @@ -22,7 +32,7 @@ import SwiftUI /// The `Query` configuration. private let configuration: Configuration - + private let printPublisherConfiguration: QueryPublisherPrintConfiguration? /// The last published database value. public var wrappedValue: Request.Value { tracker.value ?? Request.defaultValue @@ -73,10 +83,12 @@ import SwiftUI /// - parameter keyPath: A key path to the database in the environment. public init( _ request: Request, - in keyPath: KeyPath) + in keyPath: KeyPath, + printPublisherConfiguration: QueryPublisherPrintConfiguration? = nil) { - self._database = Environment(keyPath) - self.configuration = .initial(request) + self.init(configuration: .initial(request), + in: keyPath, + printPublisherConfiguration: printPublisherConfiguration) } /// Creates a `Query`, given a ``Queryable`` request, and a key path to @@ -111,10 +123,12 @@ import SwiftUI /// - parameter keyPath: A key path to the database in the environment. public init( constant request: Request, - in keyPath: KeyPath) + in keyPath: KeyPath, + printPublisherConfiguration: QueryPublisherPrintConfiguration? = nil) { - self._database = Environment(keyPath) - self.configuration = .constant(request) + self.init(configuration: .constant(request), + in: keyPath, + printPublisherConfiguration: printPublisherConfiguration) } /// Creates a `Query`, given a SwiftUI binding to its ``Queryable`` @@ -158,12 +172,25 @@ import SwiftUI /// - parameter keyPath: A key path to the database in the environment. public init( _ request: Binding, - in keyPath: KeyPath) + in keyPath: KeyPath, + printPublisherConfiguration: QueryPublisherPrintConfiguration? = nil) + { + self.init(configuration: .binding(request), + in: keyPath, + printPublisherConfiguration: printPublisherConfiguration) + } + + private init( + configuration: Configuration, + in keyPath: KeyPath, + printPublisherConfiguration: QueryPublisherPrintConfiguration?) { self._database = Environment(keyPath) - self.configuration = .binding(request) + self.configuration = configuration + self.printPublisherConfiguration = printPublisherConfiguration } + /// A wrapper of the underlying `Query` that creates bindings to /// its ``Queryable`` request. /// @@ -252,8 +279,10 @@ import SwiftUI func update( queryObservationEnabled: Bool, configuration queryConfiguration: Configuration, + printPublisherConfiguration: QueryPublisherPrintConfiguration?, database: Request.Context) { + // Give up if observation is disabled guard queryObservationEnabled else { trackedRequest = nil @@ -291,9 +320,17 @@ import SwiftUI return } + var finalPublisher = publisher.eraseToAnyPublisher() + + if let printConfiguration = printPublisherConfiguration { + finalPublisher = finalPublisher.print(printConfiguration.prefix, + to: printConfiguration.outputStream) + .eraseToAnyPublisher() + } + // Start tracking the new request var isUpdating = true - cancellable = publisher.sink( + cancellable = finalPublisher.sink( receiveCompletion: { [weak self] completion in guard let self = self else { return } MainActor.assumeIsolated { @@ -335,6 +372,7 @@ extension Query: DynamicProperty { tracker.update( queryObservationEnabled: queryObservationEnabled, configuration: configuration, + printPublisherConfiguration: printPublisherConfiguration, database: database) } } From 4fe80f5c63da4290bc36f596f8bff6c006072a3b Mon Sep 17 00:00:00 2001 From: Siarhei Yakushevich Date: Thu, 24 Apr 2025 12:00:26 +0200 Subject: [PATCH 2/2] updated by xcode: Version 16.3 (16E140) --- .../xcshareddata/swiftpm/Package.resolved | 6 +++--- Documentation/MVVMDemo/MVVMDemo.xcodeproj/project.pbxproj | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Documentation/DemoApps.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Documentation/DemoApps.xcworkspace/xcshareddata/swiftpm/Package.resolved index 2336d70..5ef2250 100644 --- a/Documentation/DemoApps.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Documentation/DemoApps.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,13 +1,13 @@ { - "originHash" : "8b3eda36da18d89a659acf1bf9271f6614d3a169035b13ebe8ce220e231fe8a6", + "originHash" : "cb18ed509d253f716a675c3aa0d72e4cba16c89893ddd5e9b601ccf2127bf5ff", "pins" : [ { "identity" : "grdb.swift", "kind" : "remoteSourceControl", "location" : "https://github.com/groue/GRDB.swift.git", "state" : { - "revision" : "47a7ddf08a619fff3e215df321fba9f4d77413e5", - "version" : "7.0.0-beta" + "revision" : "04e73c26c4ce8218ab85aaf791942bb0b204f330", + "version" : "7.4.1" } } ], diff --git a/Documentation/MVVMDemo/MVVMDemo.xcodeproj/project.pbxproj b/Documentation/MVVMDemo/MVVMDemo.xcodeproj/project.pbxproj index f287b15..f4e6bd4 100644 --- a/Documentation/MVVMDemo/MVVMDemo.xcodeproj/project.pbxproj +++ b/Documentation/MVVMDemo/MVVMDemo.xcodeproj/project.pbxproj @@ -461,6 +461,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"MVVMDemo/Preview Content\""; + DEVELOPMENT_TEAM = ""; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; @@ -489,6 +490,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"MVVMDemo/Preview Content\""; + DEVELOPMENT_TEAM = ""; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;