From 0b83f6b74a1ca75c1636fa67281922bfc7eaffda Mon Sep 17 00:00:00 2001 From: Igor Camilo <11697241+igorcamilo@users.noreply.github.com> Date: Tue, 12 Aug 2025 13:50:45 +0200 Subject: [PATCH 1/2] Add TCA dependency --- Kinova.xcodeproj/project.pbxproj | 17 +++ .../xcshareddata/swiftpm/Package.resolved | 128 +++++++++++++++++- 2 files changed, 144 insertions(+), 1 deletion(-) diff --git a/Kinova.xcodeproj/project.pbxproj b/Kinova.xcodeproj/project.pbxproj index 830ad56..22eb366 100644 --- a/Kinova.xcodeproj/project.pbxproj +++ b/Kinova.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ D1032BF12E2D45A900D3CC5D /* TMDB in Frameworks */ = {isa = PBXBuildFile; productRef = D1032BF02E2D45A800D3CC5D /* TMDB */; }; + D1F7D1EE2E4B61A9005A90C4 /* ComposableArchitecture in Frameworks */ = {isa = PBXBuildFile; productRef = D1F7D1ED2E4B61A9005A90C4 /* ComposableArchitecture */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -50,6 +51,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D1F7D1EE2E4B61A9005A90C4 /* ComposableArchitecture in Frameworks */, D1032BF12E2D45A900D3CC5D /* TMDB in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -119,6 +121,7 @@ name = Kinova; packageProductDependencies = ( D1032BF02E2D45A800D3CC5D /* TMDB */, + D1F7D1ED2E4B61A9005A90C4 /* ComposableArchitecture */, ); productName = Kinova; productReference = D14D232F2E22B02B000EBA25 /* Kinova.app */; @@ -154,6 +157,7 @@ minimizedProjectReferenceProxies = 1; packageReferences = ( D1032BEF2E2D45A800D3CC5D /* XCRemoteSwiftPackageReference "tmdb-swift" */, + D1F7D1EC2E4B61A9005A90C4 /* XCRemoteSwiftPackageReference "swift-composable-architecture" */, ); preferredProjectObjectVersion = 77; productRefGroup = D14D23302E22B02B000EBA25 /* Products */; @@ -484,6 +488,14 @@ minimumVersion = 0.1.0; }; }; + D1F7D1EC2E4B61A9005A90C4 /* XCRemoteSwiftPackageReference "swift-composable-architecture" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/pointfreeco/swift-composable-architecture.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.21.1; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -492,6 +504,11 @@ package = D1032BEF2E2D45A800D3CC5D /* XCRemoteSwiftPackageReference "tmdb-swift" */; productName = TMDB; }; + D1F7D1ED2E4B61A9005A90C4 /* ComposableArchitecture */ = { + isa = XCSwiftPackageProductDependency; + package = D1F7D1EC2E4B61A9005A90C4 /* XCRemoteSwiftPackageReference "swift-composable-architecture" */; + productName = ComposableArchitecture; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = D14D23272E22B02B000EBA25 /* Project object */; diff --git a/Kinova.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Kinova.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 304178d..8363fc1 100644 --- a/Kinova.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Kinova.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,6 +1,123 @@ { - "originHash" : "50a7be36106d362cea9ca5c2c830a2f387cb07735539d5ea5e0e8c8ca642f0b9", + "originHash" : "b0882f1bbbc522760b9279072857883a8cf5edc949f87f498882cc0d52b97a18", "pins" : [ + { + "identity" : "combine-schedulers", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/combine-schedulers", + "state" : { + "revision" : "5928286acce13def418ec36d05a001a9641086f2", + "version" : "1.0.3" + } + }, + { + "identity" : "swift-case-paths", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-case-paths", + "state" : { + "revision" : "9810c8d6c2914de251e072312f01d3bf80071852", + "version" : "1.7.1" + } + }, + { + "identity" : "swift-clocks", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-clocks", + "state" : { + "revision" : "cc46202b53476d64e824e0b6612da09d84ffde8e", + "version" : "1.0.6" + } + }, + { + "identity" : "swift-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-collections", + "state" : { + "revision" : "8c0c0a8b49e080e54e5e328cc552821ff07cd341", + "version" : "1.2.1" + } + }, + { + "identity" : "swift-composable-architecture", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-composable-architecture.git", + "state" : { + "revision" : "4c47829a080789cf20d82c64d8c27291352391d4", + "version" : "1.21.1" + } + }, + { + "identity" : "swift-concurrency-extras", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-concurrency-extras", + "state" : { + "revision" : "82a4ae7170d98d8538ec77238b7eb8e7199ef2e8", + "version" : "1.3.1" + } + }, + { + "identity" : "swift-custom-dump", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-custom-dump", + "state" : { + "revision" : "82645ec760917961cfa08c9c0c7104a57a0fa4b1", + "version" : "1.3.3" + } + }, + { + "identity" : "swift-dependencies", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-dependencies", + "state" : { + "revision" : "eefcdaa88d2e2fd82e3405dfb6eb45872011a0b5", + "version" : "1.9.3" + } + }, + { + "identity" : "swift-identified-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-identified-collections", + "state" : { + "revision" : "322d9ffeeba85c9f7c4984b39422ec7cc3c56597", + "version" : "1.1.1" + } + }, + { + "identity" : "swift-navigation", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-navigation", + "state" : { + "revision" : "4e89284c1966538109dc783497405bc680e9bc96", + "version" : "2.4.0" + } + }, + { + "identity" : "swift-perception", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-perception", + "state" : { + "revision" : "328a0b49e2690135c4c2660661f0ed83f16853e3", + "version" : "2.0.4" + } + }, + { + "identity" : "swift-sharing", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-sharing", + "state" : { + "revision" : "83ff5833e25ef1869f85f57affe6b9bbeb010f6b", + "version" : "2.7.0" + } + }, + { + "identity" : "swift-syntax", + "kind" : "remoteSourceControl", + "location" : "https://github.com/swiftlang/swift-syntax", + "state" : { + "revision" : "f99ae8aa18f0cf0d53481901f88a0991dc3bd4a2", + "version" : "601.0.1" + } + }, { "identity" : "tmdb-swift", "kind" : "remoteSourceControl", @@ -9,6 +126,15 @@ "revision" : "c57a180ccfe88d9483463f39a8fec8fe5c54ca94", "version" : "0.4.0" } + }, + { + "identity" : "xctest-dynamic-overlay", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay", + "state" : { + "revision" : "b2ed9eabefe56202ee4939dd9fc46b6241c88317", + "version" : "1.6.1" + } } ], "version" : 3 From c58d86801af26af0693616ea0ba4f4c5a8a42713 Mon Sep 17 00:00:00 2001 From: Igor Camilo <11697241+igorcamilo@users.noreply.github.com> Date: Wed, 13 Aug 2025 23:03:53 +0200 Subject: [PATCH 2/2] Add TCA --- .gitignore | 1 + Kinova.xcodeproj/project.pbxproj | 21 ++++++++- .../xcshareddata/swiftpm/Package.resolved | 14 +++--- Kinova/Movies/MoviesReducer.swift | 20 +++++++++ KinovaCore/Package.swift | 41 ++++++++++++++++++ .../MoviesFeature/MovieDetailsReducer.swift | 43 +++++++++++++++++++ .../MoviesFeature/MovieDetailsView.swift | 20 +++++++++ .../KinovaCoreTests/KinovaCoreTests.swift | 6 +++ 8 files changed, 157 insertions(+), 9 deletions(-) create mode 100644 Kinova/Movies/MoviesReducer.swift create mode 100644 KinovaCore/Package.swift create mode 100644 KinovaCore/Sources/MoviesFeature/MovieDetailsReducer.swift create mode 100644 KinovaCore/Sources/MoviesFeature/MovieDetailsView.swift create mode 100644 KinovaCore/Tests/KinovaCoreTests/KinovaCoreTests.swift diff --git a/.gitignore b/.gitignore index ea943ff..9b364bd 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /Kinova.xcodeproj/project.xcworkspace/xcuserdata/ /Kinova.xcodeproj/xcuserdata/ /Kinova/KinovaSecrets.swift +/KinovaCore/.swiftpm/xcode/xcuserdata/ diff --git a/Kinova.xcodeproj/project.pbxproj b/Kinova.xcodeproj/project.pbxproj index 22eb366..02cd1c5 100644 --- a/Kinova.xcodeproj/project.pbxproj +++ b/Kinova.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ D1032BF12E2D45A900D3CC5D /* TMDB in Frameworks */ = {isa = PBXBuildFile; productRef = D1032BF02E2D45A800D3CC5D /* TMDB */; }; + D117EBAD2E4D226200CA488E /* MoviesFeature in Frameworks */ = {isa = PBXBuildFile; productRef = D117EBAC2E4D226200CA488E /* MoviesFeature */; }; D1F7D1EE2E4B61A9005A90C4 /* ComposableArchitecture in Frameworks */ = {isa = PBXBuildFile; productRef = D1F7D1ED2E4B61A9005A90C4 /* ComposableArchitecture */; }; /* End PBXBuildFile section */ @@ -24,6 +25,7 @@ /* Begin PBXFileReference section */ D1032BE32E2D2F5400D3CC5D /* KinovaTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KinovaTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; D14D232F2E22B02B000EBA25 /* Kinova.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Kinova.app; sourceTree = BUILT_PRODUCTS_DIR; }; + D153C2652E4D211B00C05EAD /* KinovaCore */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = KinovaCore; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedRootGroup section */ @@ -51,6 +53,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D117EBAD2E4D226200CA488E /* MoviesFeature in Frameworks */, D1F7D1EE2E4B61A9005A90C4 /* ComposableArchitecture in Frameworks */, D1032BF12E2D45A900D3CC5D /* TMDB in Frameworks */, ); @@ -59,11 +62,20 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + D117EBAB2E4D226200CA488E /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; D14D23262E22B02B000EBA25 = { isa = PBXGroup; children = ( D14D23312E22B02B000EBA25 /* Kinova */, D1032BE42E2D2F5400D3CC5D /* KinovaTests */, + D153C2652E4D211B00C05EAD /* KinovaCore */, + D117EBAB2E4D226200CA488E /* Frameworks */, D14D23302E22B02B000EBA25 /* Products */, ); sourceTree = ""; @@ -122,6 +134,7 @@ packageProductDependencies = ( D1032BF02E2D45A800D3CC5D /* TMDB */, D1F7D1ED2E4B61A9005A90C4 /* ComposableArchitecture */, + D117EBAC2E4D226200CA488E /* MoviesFeature */, ); productName = Kinova; productReference = D14D232F2E22B02B000EBA25 /* Kinova.app */; @@ -484,8 +497,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/igorcamilo/tmdb-swift.git"; requirement = { - kind = upToNextMajorVersion; - minimumVersion = 0.1.0; + branch = tca; + kind = branch; }; }; D1F7D1EC2E4B61A9005A90C4 /* XCRemoteSwiftPackageReference "swift-composable-architecture" */ = { @@ -504,6 +517,10 @@ package = D1032BEF2E2D45A800D3CC5D /* XCRemoteSwiftPackageReference "tmdb-swift" */; productName = TMDB; }; + D117EBAC2E4D226200CA488E /* MoviesFeature */ = { + isa = XCSwiftPackageProductDependency; + productName = MoviesFeature; + }; D1F7D1ED2E4B61A9005A90C4 /* ComposableArchitecture */ = { isa = XCSwiftPackageProductDependency; package = D1F7D1EC2E4B61A9005A90C4 /* XCRemoteSwiftPackageReference "swift-composable-architecture" */; diff --git a/Kinova.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Kinova.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 8363fc1..4e2db85 100644 --- a/Kinova.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Kinova.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "b0882f1bbbc522760b9279072857883a8cf5edc949f87f498882cc0d52b97a18", + "originHash" : "39b6455512e90625cbad4293a7716557cc43ecc47b190849046ee9266a1a7c75", "pins" : [ { "identity" : "combine-schedulers", @@ -96,8 +96,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/swift-perception", "state" : { - "revision" : "328a0b49e2690135c4c2660661f0ed83f16853e3", - "version" : "2.0.4" + "revision" : "7d3509c7f4de78ad3eb3d804e036fb62e3585141", + "version" : "2.0.5" } }, { @@ -105,8 +105,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/swift-sharing", "state" : { - "revision" : "83ff5833e25ef1869f85f57affe6b9bbeb010f6b", - "version" : "2.7.0" + "revision" : "bddb52233714512f63e0dfa8cd0ee8203103f3b1", + "version" : "2.7.1" } }, { @@ -123,8 +123,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/igorcamilo/tmdb-swift.git", "state" : { - "revision" : "c57a180ccfe88d9483463f39a8fec8fe5c54ca94", - "version" : "0.4.0" + "branch" : "tca", + "revision" : "b225294700934dd33f1c0f51088fc81c797ad5ca" } }, { diff --git a/Kinova/Movies/MoviesReducer.swift b/Kinova/Movies/MoviesReducer.swift new file mode 100644 index 0000000..0068638 --- /dev/null +++ b/Kinova/Movies/MoviesReducer.swift @@ -0,0 +1,20 @@ +// +// MoviesReducer.swift +// Kinova +// +// Created by Igor Camilo on 12.08.25. +// + +import ComposableArchitecture + +@Reducer +struct MoviesReducer { + @ObservableState + struct State { + var aaaa = 0 + } + + enum Action { + case bbbb + } +} diff --git a/KinovaCore/Package.swift b/KinovaCore/Package.swift new file mode 100644 index 0000000..d930a38 --- /dev/null +++ b/KinovaCore/Package.swift @@ -0,0 +1,41 @@ +// swift-tools-version: 6.2 + +import PackageDescription + +let package = Package( + name: "KinovaCore", + platforms: [ + .iOS("26.0"), + .macOS("26.0"), + .visionOS("26.0") + ], + products: [ + .library( + name: "MoviesFeature", + targets: ["MoviesFeature"] + ), + ], + dependencies: [ + .package( + url: "https://github.com/igorcamilo/tmdb-swift.git", + from: "1.0.0" + ), + .package( + url: "https://github.com/pointfreeco/swift-composable-architecture.git", + from: "1.0.0" + ), + ], + targets: [ + .target( + name: "MoviesFeature", + dependencies: [ + .product(name: "ComposableArchitecture", package: "swift-composable-architecture"), + .product(name: "TMDB", package: "tmdb-swift") + ], + ), + .testTarget( + name: "MoviesFeatureTests", + dependencies: ["MoviesFeature"] + ), + ] +) diff --git a/KinovaCore/Sources/MoviesFeature/MovieDetailsReducer.swift b/KinovaCore/Sources/MoviesFeature/MovieDetailsReducer.swift new file mode 100644 index 0000000..89545fe --- /dev/null +++ b/KinovaCore/Sources/MoviesFeature/MovieDetailsReducer.swift @@ -0,0 +1,43 @@ +// +// MovieDetailsReducer.swift +// KinovaCore +// +// Created by Igor Camilo on 13.08.25. +// + +import ComposableArchitecture +import Dependencies +import TMDB + +@Reducer +struct MovieDetailsReducer { + @ObservableState + struct State { + var aaa = false + } + + enum Action: ViewAction { + case view(View) + + enum View { + case viewAppeared + } + } + + @Dependency(\.movieClient) private var movieClient + + var body: some Reducer { + Reduce { state, action in + switch action { + case .view(.viewAppeared): + return viewAppeared(state: &state) + } + } + } + + private func viewAppeared( + state: inout State + ) -> Effect { + return .none + } +} diff --git a/KinovaCore/Sources/MoviesFeature/MovieDetailsView.swift b/KinovaCore/Sources/MoviesFeature/MovieDetailsView.swift new file mode 100644 index 0000000..531e4bd --- /dev/null +++ b/KinovaCore/Sources/MoviesFeature/MovieDetailsView.swift @@ -0,0 +1,20 @@ +// +// MovieDetailsView.swift +// KinovaCore +// +// Created by Igor Camilo on 13.08.25. +// + +import ComposableArchitecture +import SwiftUI + +@ViewAction(for: MovieDetailsReducer.self) +struct MovieDetailsView: View { + let store: StoreOf + + var body: some View { + } +} + +#Preview { +} diff --git a/KinovaCore/Tests/KinovaCoreTests/KinovaCoreTests.swift b/KinovaCore/Tests/KinovaCoreTests/KinovaCoreTests.swift new file mode 100644 index 0000000..62d8e5b --- /dev/null +++ b/KinovaCore/Tests/KinovaCoreTests/KinovaCoreTests.swift @@ -0,0 +1,6 @@ +import Testing +@testable import KinovaCore + +@Test func example() async throws { + // Write your test here and use APIs like `#expect(...)` to check expected conditions. +}