From 9c3a37f74367320043e72e65e7a4237577874536 Mon Sep 17 00:00:00 2001 From: carlosDelaMoraFavor Date: Wed, 4 Dec 2024 12:52:10 -0600 Subject: [PATCH 1/7] Support for iOS 16 --- Package.swift | 4 ++-- Sources/SwiftRepo/Repository/ModelResponse.swift | 1 + .../Repository/Protocols/Query/Query.swift | 1 + .../Repository/DefaultQueryRepository.swift | 2 ++ .../Repository/Store/PersistentStore.swift | 1 + .../Repository/Store/SwiftDataStore.swift | 1 + Sources/SwiftRepo/Repository/StoreModel.swift | 9 +++++---- .../SwiftRepo/SwiftUI/LoadingControllerView.swift | 13 ++++++++++--- Sources/SwiftRepo/SwiftUI/View+Extensions.swift | 14 ++++++++++++++ 9 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 Sources/SwiftRepo/SwiftUI/View+Extensions.swift diff --git a/Package.swift b/Package.swift index 098130a..151e483 100644 --- a/Package.swift +++ b/Package.swift @@ -1,10 +1,10 @@ -// swift-tools-version:5.8 +// swift-tools-version: 6.0 import PackageDescription let package = Package( name: "SwiftRepo", platforms: [ - .iOS("18.0"), + .iOS("16.0"), .macOS("15.0"), ], products: [ diff --git a/Sources/SwiftRepo/Repository/ModelResponse.swift b/Sources/SwiftRepo/Repository/ModelResponse.swift index 0ced35f..7d2d27d 100644 --- a/Sources/SwiftRepo/Repository/ModelResponse.swift +++ b/Sources/SwiftRepo/Repository/ModelResponse.swift @@ -11,6 +11,7 @@ import Foundation /// Partnered with a `QueryRepository` using an additional model store, `Value` will be /// propagated via an `ObservableStore` and the array of `Model`s will be placed in /// the `ModelStore`. +@available(iOS 17, *) public protocol ModelResponse { /// Can be used to propagate additional metadata related to the response via an `ObservableStore` associatedtype Value diff --git a/Sources/SwiftRepo/Repository/Protocols/Query/Query.swift b/Sources/SwiftRepo/Repository/Protocols/Query/Query.swift index 949ff88..0f1d319 100644 --- a/Sources/SwiftRepo/Repository/Protocols/Query/Query.swift +++ b/Sources/SwiftRepo/Repository/Protocols/Query/Query.swift @@ -129,6 +129,7 @@ public extension Query { /// - strategy: The query strategy /// - willGet: A closure that will be called if and when the query is performed. This is typically the `LoadingController.loading` function. /// - Returns: The value if the query was performed. Otherwise, `nil`. + @available(iOS 17, *) func get( id: QueryId, variables: Variables, diff --git a/Sources/SwiftRepo/Repository/Repository/DefaultQueryRepository.swift b/Sources/SwiftRepo/Repository/Repository/DefaultQueryRepository.swift index b2738ad..d620c0a 100644 --- a/Sources/SwiftRepo/Repository/Repository/DefaultQueryRepository.swift +++ b/Sources/SwiftRepo/Repository/Repository/DefaultQueryRepository.swift @@ -84,6 +84,7 @@ where QueryId: Hashable, Variables: Hashable, Key: Hashable { /// - modelStore: The underlying `Store` implementation to use for `QueryValue.Model`. /// - queryStrategy: The query strategy to use. /// - queryOperation: The operation to use to perform the actual query. + @available(iOS 17, *) public init( observableStore: ObservableStoreType, modelStore: any Store, @@ -148,6 +149,7 @@ where QueryId: Hashable, Variables: Hashable, Key: Hashable { /// - modelStore: The underlying `Store` implementation to use for models. /// - queryStrategy: The query strategy to use. /// - queryOperation: The operation to use to perform the actual query. + @available(iOS 17, *) public convenience init( observableStore: ObservableStoreType, modelStore: any Store, diff --git a/Sources/SwiftRepo/Repository/Store/PersistentStore.swift b/Sources/SwiftRepo/Repository/Store/PersistentStore.swift index 5f37cdc..7de83d2 100644 --- a/Sources/SwiftRepo/Repository/Store/PersistentStore.swift +++ b/Sources/SwiftRepo/Repository/Store/PersistentStore.swift @@ -9,6 +9,7 @@ import Foundation import SwiftData /// A persistent `Store` implementation implementation using `SwiftData`. +@available(iOS 18, *) public class PersistentStore: Store { public var keys: [Key] { diff --git a/Sources/SwiftRepo/Repository/Store/SwiftDataStore.swift b/Sources/SwiftRepo/Repository/Store/SwiftDataStore.swift index 7ea95f3..d6490c8 100644 --- a/Sources/SwiftRepo/Repository/Store/SwiftDataStore.swift +++ b/Sources/SwiftRepo/Repository/Store/SwiftDataStore.swift @@ -11,6 +11,7 @@ import SwiftData import SwiftRepoCore // An implementation of `Store` that uses `SwiftData` under the hood +@available(iOS 18, *) public class SwiftDataStore: Store where Model: PersistentModel, Model.Key: Hashable & Codable { public typealias Key = Model.Key public typealias Value = Model diff --git a/Sources/SwiftRepo/Repository/StoreModel.swift b/Sources/SwiftRepo/Repository/StoreModel.swift index 5904254..0320645 100644 --- a/Sources/SwiftRepo/Repository/StoreModel.swift +++ b/Sources/SwiftRepo/Repository/StoreModel.swift @@ -11,6 +11,7 @@ import Foundation /// This interface is to be used with models that will be retrieved by the app /// through database queries, rather than published by a `QueryRepository`, /// such as when using SwiftData. +@available(iOS 17, *) public protocol StoreModel { /// The type to use as the identifier for the model associatedtype Key = any Hashable @@ -21,7 +22,7 @@ public protocol StoreModel { /// A predicate that can be used to query for the `StoreModel` static func predicate(key: Key) -> Predicate } - +@available(iOS 17, *) public extension StoreModel where Key == Data { static func predicate(key: Key) -> Predicate { @@ -30,7 +31,7 @@ public extension StoreModel where Key == Data { } } } - +@available(iOS 17, *) public extension StoreModel where Key == UUID { static func predicate(key: Key) -> Predicate { @@ -39,7 +40,7 @@ public extension StoreModel where Key == UUID { } } } - +@available(iOS 17, *) public extension StoreModel where Key == String { static func predicate(key: Key) -> Predicate { @@ -48,7 +49,7 @@ public extension StoreModel where Key == String { } } } - +@available(iOS 17, *) public extension StoreModel where Key == Int { static func predicate(key: Key) -> Predicate { diff --git a/Sources/SwiftRepo/SwiftUI/LoadingControllerView.swift b/Sources/SwiftRepo/SwiftUI/LoadingControllerView.swift index 94fed60..79f0714 100644 --- a/Sources/SwiftRepo/SwiftUI/LoadingControllerView.swift +++ b/Sources/SwiftRepo/SwiftUI/LoadingControllerView.swift @@ -45,7 +45,8 @@ public struct LoadingControllerView some View) -> some View { + modifier(self) + } +} From 78570640679b8ad6c9a55bcef6a7e101bd3277ac Mon Sep 17 00:00:00 2001 From: carlosDelaMoraFavor Date: Tue, 10 Dec 2024 11:59:25 -0600 Subject: [PATCH 2/7] Add trasnform effect --- Sources/SwiftRepo/SwiftUI/LoadingControllerView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/SwiftRepo/SwiftUI/LoadingControllerView.swift b/Sources/SwiftRepo/SwiftUI/LoadingControllerView.swift index 79f0714..64ff51f 100644 --- a/Sources/SwiftRepo/SwiftUI/LoadingControllerView.swift +++ b/Sources/SwiftRepo/SwiftUI/LoadingControllerView.swift @@ -71,7 +71,7 @@ public struct LoadingControllerView Date: Tue, 10 Dec 2024 12:54:45 -0600 Subject: [PATCH 3/7] Fix tests --- Package.swift | 2 +- Tests/SwiftRepoTests/DefaultQueryRepositoryTests.swift | 5 +++++ Tests/SwiftRepoTests/SwiftDataStoreTests.swift | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 151e483..50a7c0c 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 6.0 +// swift-tools-version: 5.8 import PackageDescription let package = Package( diff --git a/Tests/SwiftRepoTests/DefaultQueryRepositoryTests.swift b/Tests/SwiftRepoTests/DefaultQueryRepositoryTests.swift index dd83e71..e3115f0 100644 --- a/Tests/SwiftRepoTests/DefaultQueryRepositoryTests.swift +++ b/Tests/SwiftRepoTests/DefaultQueryRepositoryTests.swift @@ -32,6 +32,7 @@ class DefaultQueryRepositoryTests: XCTestCase { XCTAssertEqual(spy.publishedValues, [valueA1, valueA1, valueA1, valueA2]) } + @available(iOS 17, *) @MainActor func test_GetSuccess_ModelResponse() async throws { let repo = makeModelResponseStoreRepository( @@ -59,6 +60,7 @@ class DefaultQueryRepositoryTests: XCTestCase { XCTAssertEqual(try modelStore.get(key: Self.modelCId), responseB.models.last) } + @available(iOS 17, *) @MainActor func test_GetSuccess_ModelResponse_Trim() async throws { let repo = makeModelResponseStoreRepository( @@ -98,6 +100,7 @@ class DefaultQueryRepositoryTests: XCTestCase { XCTAssertEqual(spy.publishedValues.compactMap { $0 as? TestError }, [TestError(category: .failure)]) } + @available(iOS 17, *) func test_GetError_ModelResponse() async throws { let repo = makeModelResponseStoreRepository( delayedValues: DelayedValues(values: [ @@ -234,6 +237,7 @@ class DefaultQueryRepositoryTests: XCTestCase { var id: UUID var updatedAt = Date() + @available(iOS 17, *) static func predicate(key: UUID) -> Predicate { #Predicate { $0.id == key } } @@ -294,6 +298,7 @@ class DefaultQueryRepositoryTests: XCTestCase { /// Makes a repository that stores a single value per unique query ID, /// and places ModelResponse values in a separate model store. + @available(iOS 17, *) private func makeModelResponseStoreRepository( mergeStrategy: ModelStoreMergeStrategy = .upsertAppend, queryStrategy: QueryStrategy = .ifOlderThan(0.1), diff --git a/Tests/SwiftRepoTests/SwiftDataStoreTests.swift b/Tests/SwiftRepoTests/SwiftDataStoreTests.swift index b92d79a..e464dbd 100644 --- a/Tests/SwiftRepoTests/SwiftDataStoreTests.swift +++ b/Tests/SwiftRepoTests/SwiftDataStoreTests.swift @@ -9,6 +9,7 @@ import XCTest import SwiftData @testable import SwiftRepo +@available(iOS 18, *) @MainActor class SwiftDataStoreTests: XCTestCase { From 746e566e9c77256a9330cd2bc93d5ddcac299844 Mon Sep 17 00:00:00 2001 From: carlosDelaMoraFavor Date: Tue, 10 Dec 2024 13:51:30 -0600 Subject: [PATCH 4/7] Fix StoreModel --- Sources/SwiftRepo/Repository/StoreModel.swift | 40 ------------------- 1 file changed, 40 deletions(-) diff --git a/Sources/SwiftRepo/Repository/StoreModel.swift b/Sources/SwiftRepo/Repository/StoreModel.swift index 48d7968..06892b6 100644 --- a/Sources/SwiftRepo/Repository/StoreModel.swift +++ b/Sources/SwiftRepo/Repository/StoreModel.swift @@ -22,43 +22,3 @@ public protocol StoreModel { /// A predicate that can be used to query for the `StoreModel` static func predicate(key: Key) -> Predicate } - -@available(iOS 17, *) -public extension StoreModel where Key == Data { - - static func predicate(key: Key) -> Predicate { - #Predicate { model in - model.id == key - } - } -} - -@available(iOS 17, *) -public extension StoreModel where Key == UUID { - - static func predicate(key: Key) -> Predicate { - #Predicate { model in - model.id == key - } - } -} - -@available(iOS 17, *) -public extension StoreModel where Key == String { - - static func predicate(key: Key) -> Predicate { - #Predicate { model in - model.id == key - } - } -} - -@available(iOS 17, *) -public extension StoreModel where Key == Int { - - static func predicate(key: Key) -> Predicate { - #Predicate { model in - model.id == key - } - } -} From db1867debf4e96e66fd15fa4677668ce225e8437 Mon Sep 17 00:00:00 2001 From: carlosDelaMoraFavor Date: Tue, 10 Dec 2024 13:52:59 -0600 Subject: [PATCH 5/7] Fix tests --- Tests/SwiftRepoTests/DefaultQueryRepositoryTests.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Tests/SwiftRepoTests/DefaultQueryRepositoryTests.swift b/Tests/SwiftRepoTests/DefaultQueryRepositoryTests.swift index ad17ad3..2668e52 100644 --- a/Tests/SwiftRepoTests/DefaultQueryRepositoryTests.swift +++ b/Tests/SwiftRepoTests/DefaultQueryRepositoryTests.swift @@ -89,6 +89,7 @@ class DefaultQueryRepositoryTests: XCTestCase { XCTAssertEqual(try modelStore.get(key: Self.modelCId), responseB.models.last) } + @available(iOS 17, *) @MainActor func test_GetSuccess_ModelResponse_Merge() async throws { let repo = makeModelResponseStoreRepository( From b5f9dd067e99fb5c7a67f37581d92de058399b0e Mon Sep 17 00:00:00 2001 From: carlosDelaMoraFavor Date: Tue, 10 Dec 2024 13:54:01 -0600 Subject: [PATCH 6/7] Remove unwanted space --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 50a7c0c..51bba80 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 5.8 +// swift-tools-version:5.8 import PackageDescription let package = Package( From 2b2b4f4788729500737304a4614cd0a8d1711ef3 Mon Sep 17 00:00:00 2001 From: carlosDelaMoraFavor Date: Tue, 10 Dec 2024 13:58:40 -0600 Subject: [PATCH 7/7] PR feedback --- Sources/SwiftRepo/SwiftUI/LoadingControllerView.swift | 2 +- Sources/SwiftRepo/SwiftUI/View+Extensions.swift | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Sources/SwiftRepo/SwiftUI/LoadingControllerView.swift b/Sources/SwiftRepo/SwiftUI/LoadingControllerView.swift index 64ff51f..8c4d62a 100644 --- a/Sources/SwiftRepo/SwiftUI/LoadingControllerView.swift +++ b/Sources/SwiftRepo/SwiftUI/LoadingControllerView.swift @@ -66,7 +66,7 @@ public struct LoadingControllerView some View) -> some View { - modifier(self) + /// Provides a way to introduce a code block as a view modifier. + @ViewBuilder func map(@ViewBuilder _ transform: (Self) -> Content) -> some View { + transform(self) } }