├── NeedleDependencies
├── NeedleDependencies
│ ├── copyright_header.txt
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ ├── NeedleDependencies.entitlements
│ ├── NeedleDependenciesApp.swift
│ ├── LogInComponent.swift
│ ├── RootComponent.swift
│ ├── AuthenticatedComponent.swift
│ ├── NeedleGenerated.swift
│ └── ContentView.swift
└── NeedleDependencies.xcodeproj
│ └── project.pbxproj
├── SwiftDependencies
├── SwiftDependencies
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ ├── App.swift
│ ├── LoggedOutFeature.swift
│ ├── AppFeature.swift
│ ├── Dependencies.swift
│ └── AuthenticatedFeature.swift
└── SwiftDependencies.xcodeproj
│ └── project.pbxproj
├── FactoryDependencies
├── FactoryDependencies
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ ├── Info.plist
│ ├── Model.swift
│ ├── FactoryDependenciesApp.swift
│ ├── FactoryDependencies.entitlements
│ ├── Container.swift
│ └── ContentView.swift
└── FactoryDependencies.xcodeproj
│ └── project.pbxproj
├── PassedDependencies
├── PassedDependencies
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ ├── Model.swift
│ ├── PassedDependenciesApp.swift
│ ├── PassedDependencies.entitlements
│ ├── Container.swift
│ ├── Factories
│ │ └── AuthenticatedFactory.swift
│ └── ContentView.swift
└── PassedDependencies.xcodeproj
│ └── project.pbxproj
├── ComposableDependencies
├── ComposableDependencies
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ ├── ComposableDependencies.entitlements
│ ├── ComposableDependenciesApp.swift
│ ├── ReducerReader
│ │ └── ReducerReader.swift
│ ├── Dependencies.swift
│ ├── ContentView.swift
│ └── Features.swift
└── ComposableDependencies.xcodeproj
│ ├── xcshareddata
│ └── xcschemes
│ │ └── ComposableDependencies.xcscheme
│ └── project.pbxproj
├── images
└── injection_frameworks_compared.png
├── EnvironmentDependencies
├── EnvironmentDependencies
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ ├── Model.swift
│ ├── EnvironmentDependenciesApp.swift
│ ├── EnvironmentDependencies.entitlements
│ ├── EnvironmentSetup.swift
│ └── ContentView.swift
└── EnvironmentDependencies.xcodeproj
│ └── project.pbxproj
├── SharedDependencies
├── .gitignore
├── Tests
│ └── DependenciesTests
│ │ └── DependenciesTests.swift
├── Sources
│ └── SharedDependencies
│ │ ├── Authentication.swift
│ │ ├── UserManager.swift
│ │ ├── LogInSwitcher.swift
│ │ ├── Placeholders.swift
│ │ └── StoryFetcher.swift
└── Package.swift
├── DependenciesCompared.xcworkspace
├── xcshareddata
│ ├── IDEWorkspaceChecks.plist
│ └── swiftpm
│ │ └── Package.resolved
└── contents.xcworkspacedata
├── .gitignore
└── README.md
/NeedleDependencies/NeedleDependencies/copyright_header.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/SwiftDependencies/SwiftDependencies/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/FactoryDependencies/FactoryDependencies/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/NeedleDependencies/NeedleDependencies/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PassedDependencies/PassedDependencies/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ComposableDependencies/ComposableDependencies/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/images/injection_frameworks_compared.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LucasVanDongen/SwiftDependencyInjectionCompared/HEAD/images/injection_frameworks_compared.png
--------------------------------------------------------------------------------
/EnvironmentDependencies/EnvironmentDependencies/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/NeedleDependencies/NeedleDependencies/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PassedDependencies/PassedDependencies/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/SwiftDependencies/SwiftDependencies/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/FactoryDependencies/FactoryDependencies/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ComposableDependencies/ComposableDependencies/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/EnvironmentDependencies/EnvironmentDependencies/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/SharedDependencies/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | /.build
3 | /Packages
4 | xcuserdata/
5 | DerivedData/
6 | .swiftpm/configuration/registries.json
7 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
8 | .netrc
9 |
--------------------------------------------------------------------------------
/FactoryDependencies/FactoryDependencies/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/NeedleDependencies/NeedleDependencies/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/PassedDependencies/PassedDependencies/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/SwiftDependencies/SwiftDependencies/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/FactoryDependencies/FactoryDependencies/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ComposableDependencies/ComposableDependencies/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/EnvironmentDependencies/EnvironmentDependencies/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/FactoryDependencies/FactoryDependencies/Model.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Model.swift
3 | // PassedDependencies
4 | //
5 | // Created by Lucas van Dongen on 06/03/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | enum AppState {
11 | case loggedOut
12 | case authenticated(token: String)
13 | }
14 |
--------------------------------------------------------------------------------
/PassedDependencies/PassedDependencies/Model.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Model.swift
3 | // PassedDependencies
4 | //
5 | // Created by Lucas van Dongen on 06/03/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | enum AppState {
11 | case loggedOut
12 | case authenticated(token: String)
13 | }
14 |
--------------------------------------------------------------------------------
/EnvironmentDependencies/EnvironmentDependencies/Model.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Model.swift
3 | // PassedDependencies
4 | //
5 | // Created by Lucas van Dongen on 06/03/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | enum AppState {
11 | case loggedOut
12 | case authenticated(token: String)
13 | }
14 |
--------------------------------------------------------------------------------
/SwiftDependencies/SwiftDependencies/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/DependenciesCompared.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/FactoryDependencies/FactoryDependencies/FactoryDependenciesApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FactoryDependenciesApp.swift
3 | // FactoryDependencies
4 | //
5 | // Created by Lucas van Dongen on 12/03/2024.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct FactoryDependenciesApp: App {
12 | var body: some Scene {
13 | WindowGroup {
14 | ContentView()
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/FactoryDependencies/FactoryDependencies/FactoryDependencies.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/NeedleDependencies/NeedleDependencies/NeedleDependencies.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/PassedDependencies/PassedDependencies/PassedDependenciesApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PassedDependenciesApp.swift
3 | // PassedDependencies
4 | //
5 | // Created by Lucas van Dongen on 06/03/2024.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @MainActor
11 | @main
12 | struct PassedDependenciesApp: App {
13 | var body: some Scene {
14 | WindowGroup {
15 | ContentView()
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/PassedDependencies/PassedDependencies/PassedDependencies.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/EnvironmentDependencies/EnvironmentDependencies/EnvironmentDependenciesApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EnvironmentDependenciesApp.swift
3 | // EnvironmentDependencies
4 | //
5 | // Created by Lucas van Dongen on 15/03/2024.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct EnvironmentDependenciesApp: App {
12 | var body: some Scene {
13 | WindowGroup {
14 | ContentView()
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ComposableDependencies/ComposableDependencies/ComposableDependencies.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/EnvironmentDependencies/EnvironmentDependencies/EnvironmentDependencies.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/NeedleDependencies/NeedleDependencies/NeedleDependenciesApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NeedleDependenciesApp.swift
3 | // NeedleDependencies
4 | //
5 | // Created by Lucas van Dongen on 12/03/2024.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct NeedleDependenciesApp: App {
12 | init() {
13 | registerProviderFactories()
14 | }
15 |
16 | var body: some Scene {
17 | WindowGroup {
18 | ContentView()
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/SharedDependencies/Tests/DependenciesTests/DependenciesTests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 | @testable import Dependencies
3 |
4 | final class DependenciesTests: XCTestCase {
5 | func testExample() throws {
6 | // XCTest Documentation
7 | // https://developer.apple.com/documentation/xctest
8 |
9 | // Defining Test Cases and Test Methods
10 | // https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/SwiftDependencies/SwiftDependencies/App.swift:
--------------------------------------------------------------------------------
1 | //
2 | // App.swift
3 | // SwiftDependencies
4 | //
5 | // Created by Brandon Williams on 30/03/2024.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @MainActor
11 | @main
12 | struct SwiftDependenciesApp: App {
13 | let model = AppModel(
14 | state: .loggedOut(
15 | LoggedOutModel()
16 | )
17 | )
18 |
19 | var body: some Scene {
20 | WindowGroup {
21 | AppView(model: model)
22 | }
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.swp
3 | *~.nib
4 | DerivedData/
5 | build/
6 | *.pbxuser
7 | *.mode1v3
8 | *.mode2v3
9 | *.perspectivev3
10 | !default.pbxuser
11 | !default.mode1v3
12 | !default.mode2v3
13 | !default.perspectivev3
14 | xcuserdata
15 | !xcshareddata
16 | !xcschemes
17 | *.moved-aside
18 | /Pods
19 | /Carthage
20 |
21 | .swiftpm
22 | /node_modules
23 | /tmp
24 |
25 | .env
26 | .env.*
27 |
28 | **/fastlane/report.xml
29 | **/fastlane/Preview.html
30 | **/fastlane/screenshots
31 | **/fastlane/test_output
32 |
--------------------------------------------------------------------------------
/SharedDependencies/Sources/SharedDependencies/Authentication.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Authentication.swift
3 | //
4 | //
5 | // Created by Lucas van Dongen on 05/03/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | public protocol Authenticating: AnyActor {
11 | func authenticate() async throws -> String
12 | }
13 |
14 | public actor Authentication: Authenticating {
15 | public init() { }
16 |
17 | public func authenticate() async throws -> String {
18 | try await Task.sleep(for: .seconds(2))
19 | return "V4L1D-T0K3N"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ComposableDependencies/ComposableDependencies/ComposableDependenciesApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ComposableDependenciesApp.swift
3 | // ComposableDependencies
4 | //
5 | // Created by Lucas van Dongen on 04/03/2024.
6 | //
7 |
8 | import ComposableArchitecture
9 | import SwiftUI
10 |
11 | @main
12 | struct ComposableDependenciesApp: App {
13 | @State private var store = Store(initialState: .logIn(.waiting)) {
14 | AppRootFeature.body
15 | }
16 |
17 | var body: some Scene {
18 | WindowGroup {
19 | AppView(store: store)
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/SharedDependencies/Sources/SharedDependencies/UserManager.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserManager.swift
3 | //
4 | //
5 | // Created by Lucas van Dongen on 05/03/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | // ObservableObject is really here for EnvironmentObject
11 | public protocol UserManaging: Sendable {
12 | var token: String { get set }
13 |
14 | func update(user: String) async throws -> Bool
15 | }
16 |
17 | public struct UserManager: UserManaging {
18 | public var token: String
19 |
20 | public init(token: String) {
21 | self.token = token
22 | }
23 |
24 | public func update(user: String) async throws -> Bool {
25 | try await Task.sleep(for: .seconds(2))
26 | return true
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/SharedDependencies/Sources/SharedDependencies/LogInSwitcher.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LogInSwitcher.swift
3 | //
4 | //
5 | // Created by Lucas van Dongen on 12/03/2024.
6 | //
7 |
8 | import AsyncAlgorithms
9 | import Foundation
10 |
11 | public protocol LogInSwitching: Sendable {
12 | var tokenChannel: AsyncChannel { get }
13 |
14 | func loggedIn(with token: String) async
15 | func loggedOut() async
16 | }
17 |
18 | public final class LogInSwitcher: LogInSwitching {
19 | public let tokenChannel = AsyncChannel()
20 |
21 | public init() { }
22 |
23 | public func loggedIn(with token: String) async {
24 | await tokenChannel.send(token)
25 | }
26 |
27 | public func loggedOut() async {
28 | await tokenChannel.send("")
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/NeedleDependencies/NeedleDependencies/LogInComponent.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LogInComponent.swift
3 | // NeedleDependencies
4 | //
5 | // Created by Lucas van Dongen on 12/03/2024.
6 | //
7 |
8 | import NeedleFoundation
9 | import SharedDependencies
10 | import SwiftUI
11 |
12 | protocol LogInDependency: Dependency {
13 | var logInSwitcher: any LogInSwitching { get }
14 | }
15 |
16 | class LogInComponent: Component {
17 | var authentication: Authenticating {
18 | Authentication()
19 | }
20 |
21 | var logInView: some View {
22 | LogInView(
23 | authentication: authentication,
24 | logInSwitcher: dependency.logInSwitcher // This switcher "automagically" appears because of Needle's generated code
25 | )
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/SharedDependencies/Sources/SharedDependencies/Placeholders.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Placeholders.swift
3 | //
4 | //
5 | // Created by Lucas van Dongen on 22/03/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | // This implementation is used to prevent a `nil` value for this dependency while the user is not authenticated yet
11 | public struct PlaceholderUserManager: UserManaging {
12 | public var token = "WR0NG_T0K3N"
13 |
14 | public init() { }
15 |
16 | public func update(user: String) async throws -> Bool {
17 | return false
18 | }
19 | }
20 |
21 | public struct PlaceholderStoryFetcher: StoryFetching {
22 | public var token = "WR0NG_T0K3N"
23 | public init() { }
24 |
25 | // You have an issue if this function would actually be called
26 | public func fetchStories() async throws -> [Story] {
27 | return []
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/SharedDependencies/Sources/SharedDependencies/StoryFetcher.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StoryFetcher.swift
3 | //
4 | //
5 | // Created by Lucas van Dongen on 19/03/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | public struct Story: Sendable, Equatable {
11 | public let author: String
12 | public let name: String
13 | }
14 |
15 | public protocol StoryFetching: Sendable, Observable {
16 | var token: String { get set }
17 | func fetchStories() async throws -> [Story]
18 | }
19 |
20 | @Observable
21 | public final class StoryFetcher: StoryFetching {
22 | public var token: String
23 |
24 | public init(token: String) {
25 | self.token = token
26 | }
27 |
28 | public func fetchStories() async throws -> [Story] {
29 | try await Task.sleep(for: .seconds(2))
30 | return [
31 | Story(author: "Frank Herbert", name: "Dune"),
32 | Story(author: "Larry Niven", name: "Ringworld"),
33 | Story(author: "Vernor Vinge", name: "A Fire Upon the Deep")
34 | ]
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/DependenciesCompared.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
10 |
12 |
13 |
14 |
16 |
17 |
19 |
20 |
22 |
23 |
25 |
26 |
28 |
29 |
31 |
32 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/ComposableDependencies/ComposableDependencies/ReducerReader/ReducerReader.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ReducerReader.swift
3 | // ComposableDependencies
4 | //
5 | // Created by Lucas van Dongen on 13/03/2024.
6 | //
7 |
8 | import ComposableArchitecture
9 |
10 | /// A reducer that builds a reducer from the current state and action.
11 | public struct ReducerReader: Reducer where Reader.State == State, Reader.Action == Action {
12 | @usableFromInline
13 | let reader: (State, Action) -> Reader
14 |
15 | /// Initializes a reducer that builds a reducer from the current state and action.
16 | ///
17 | /// - Parameter reader: A reducer builder that has access to the current state and action.
18 | @inlinable
19 | public init(@ReducerBuilder reader: @escaping (State, Action) -> Reader) {
20 | self.init(internal: reader)
21 | }
22 |
23 | @usableFromInline
24 | init(internal reader: @escaping (State, Action) -> Reader) {
25 | self.reader = reader
26 | }
27 |
28 | @inlinable
29 | public func reduce(into state: inout State, action: Action) -> Effect {
30 | self.reader(state, action).reduce(into: &state, action: action)
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/FactoryDependencies/FactoryDependencies/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "scale" : "1x",
6 | "size" : "16x16"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "scale" : "2x",
11 | "size" : "16x16"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "scale" : "1x",
16 | "size" : "32x32"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "scale" : "2x",
21 | "size" : "32x32"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "scale" : "1x",
26 | "size" : "128x128"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "scale" : "2x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "scale" : "1x",
36 | "size" : "256x256"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "scale" : "2x",
41 | "size" : "256x256"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "scale" : "1x",
46 | "size" : "512x512"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "scale" : "2x",
51 | "size" : "512x512"
52 | }
53 | ],
54 | "info" : {
55 | "author" : "xcode",
56 | "version" : 1
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/NeedleDependencies/NeedleDependencies/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "scale" : "1x",
6 | "size" : "16x16"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "scale" : "2x",
11 | "size" : "16x16"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "scale" : "1x",
16 | "size" : "32x32"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "scale" : "2x",
21 | "size" : "32x32"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "scale" : "1x",
26 | "size" : "128x128"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "scale" : "2x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "scale" : "1x",
36 | "size" : "256x256"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "scale" : "2x",
41 | "size" : "256x256"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "scale" : "1x",
46 | "size" : "512x512"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "scale" : "2x",
51 | "size" : "512x512"
52 | }
53 | ],
54 | "info" : {
55 | "author" : "xcode",
56 | "version" : 1
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/EnvironmentDependencies/EnvironmentDependencies/EnvironmentSetup.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EnvironmentSetup.swift
3 | // EnvironmentDependencies
4 | //
5 | // Created by Lucas van Dongen on 23/03/2024.
6 | //
7 |
8 | import Foundation
9 | import SharedDependencies
10 | import SwiftUI
11 |
12 | private struct AuthenticationEnvironmentKey: EnvironmentKey {
13 | static let defaultValue: Authenticating = Authentication()
14 | }
15 |
16 | private struct UserManagerEnvironmentKey: EnvironmentKey {
17 | static let defaultValue: UserManaging = PlaceholderUserManager()
18 | }
19 |
20 | private struct LogInSwitcherEnvironmentKey: EnvironmentKey {
21 | static let defaultValue: LogInSwitching = LogInSwitcher()
22 | }
23 |
24 | extension EnvironmentValues {
25 | var authentication: Authenticating {
26 | get { self[AuthenticationEnvironmentKey.self] }
27 | set { self[AuthenticationEnvironmentKey.self] = newValue }
28 | }
29 | var userManager: UserManaging {
30 | get { self[UserManagerEnvironmentKey.self] }
31 | set { self[UserManagerEnvironmentKey.self] = newValue }
32 | }
33 | var logInSwitcher: LogInSwitching {
34 | get { self[LogInSwitcherEnvironmentKey.self] }
35 | set { self[LogInSwitcherEnvironmentKey.self] = newValue }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/PassedDependencies/PassedDependencies/Container.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Container.swift
3 | // PassedDependencies
4 | //
5 | // Created by Lucas van Dongen on 06/03/2024.
6 | //
7 |
8 | import Combine
9 | import SharedDependencies
10 |
11 | protocol LogInDependenciesContaining {
12 | var authentication: Authenticating { get }
13 | var logInSwitcher: any LogInSwitching { get }
14 | }
15 |
16 | class LogInDependencies: LogInDependenciesContaining {
17 | let authentication: Authenticating = Authentication()
18 | let logInSwitcher: any LogInSwitching = LogInSwitcher()
19 | }
20 |
21 | protocol AuthenticatedDependenciesContaining {
22 | var logInSwitcher: any LogInSwitching { get }
23 | var userManager: any UserManaging { get }
24 | var storyFetcher: any StoryFetching { get }
25 | }
26 |
27 | class AuthenticatedDependencies: AuthenticatedDependenciesContaining {
28 | let userManager: any UserManaging
29 | let logInSwitcher: any LogInSwitching
30 | let storyFetcher: any StoryFetching
31 |
32 | init(
33 | token: String,
34 | logInSwitcher: any LogInSwitching
35 | ) {
36 | self.userManager = UserManager(token: token)
37 | self.logInSwitcher = logInSwitcher
38 | self.storyFetcher = StoryFetcher(token: token)
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/FactoryDependencies/FactoryDependencies/Container.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Container.swift
3 | // PassedDependencies
4 | //
5 | // Created by Lucas van Dongen on 06/03/2024.
6 | //
7 |
8 | import Combine
9 | import Factory
10 | import SharedDependencies
11 |
12 | extension Container {
13 | var authentication: Factory {
14 | self { Authentication() }.singleton
15 | }
16 |
17 | var logInSwitcher: Factory {
18 | self { LogInSwitcher() }.singleton
19 | }
20 |
21 | var userManager: Factory {
22 | self { PlaceholderUserManager() }.graph
23 | }
24 |
25 | var storyFetcher: Factory {
26 | self { PlaceholderStoryFetcher() }.graph
27 | }
28 | }
29 |
30 | class AuthenticatedDependenciesManager {
31 | static func handle(token: String) {
32 | switch token.isEmpty {
33 | case true: break // We're relying on the `graph` feature to dismiss `token`-based real implementations
34 | case false: register(with: token)
35 | }
36 | }
37 |
38 | static func register(with token: String) {
39 | Container.shared.userManager.register { UserManager(token: token) }
40 | Container.shared.storyFetcher.register { StoryFetcher(token: token) }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/PassedDependencies/PassedDependencies/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "scale" : "1x",
11 | "size" : "16x16"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "scale" : "2x",
16 | "size" : "16x16"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "scale" : "1x",
21 | "size" : "32x32"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "scale" : "2x",
26 | "size" : "32x32"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "scale" : "1x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "scale" : "2x",
36 | "size" : "128x128"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "scale" : "1x",
41 | "size" : "256x256"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "scale" : "2x",
46 | "size" : "256x256"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "scale" : "1x",
51 | "size" : "512x512"
52 | },
53 | {
54 | "idiom" : "mac",
55 | "scale" : "2x",
56 | "size" : "512x512"
57 | }
58 | ],
59 | "info" : {
60 | "author" : "xcode",
61 | "version" : 1
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/NeedleDependencies/NeedleDependencies/RootComponent.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RootComponent.swift
3 | // NeedleDependencies
4 | //
5 | // Created by Lucas van Dongen on 12/03/2024.
6 | //
7 |
8 | import SharedDependencies
9 | import NeedleFoundation
10 | import SwiftUI
11 |
12 | class RootComponent: BootstrapComponent {
13 | var logInComponent: LogInComponent { LogInComponent(parent: self) }
14 |
15 | func authenticatedComponent(token: String) -> AuthenticatedComponent {
16 | AuthenticatedComponent(
17 | parent: self,
18 | token: token
19 | )
20 | }
21 | }
22 |
23 | extension RootComponent: LogInDependency {
24 | var logInSwitcher: any LogInSwitching {
25 | shared { LogInSwitcher() }
26 | }
27 | }
28 |
29 | protocol AppViewBuilding {
30 | @MainActor
31 | var appView: AppView { get }
32 |
33 | @MainActor
34 | var appViewModel: AppViewModel { get }
35 | }
36 |
37 | extension RootComponent: AppViewBuilding {
38 | @MainActor
39 | var appView: AppView {
40 | AppView(
41 | viewModel: self.appViewModel,
42 | rootComponent: self,
43 | logInComponent: logInComponent
44 | )
45 | }
46 |
47 | @MainActor
48 | var appViewModel: AppViewModel {
49 | AppViewModel(logInSwitcher: logInComponent.logInSwitcher)
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/ComposableDependencies/ComposableDependencies/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "scale" : "1x",
11 | "size" : "16x16"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "scale" : "2x",
16 | "size" : "16x16"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "scale" : "1x",
21 | "size" : "32x32"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "scale" : "2x",
26 | "size" : "32x32"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "scale" : "1x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "scale" : "2x",
36 | "size" : "128x128"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "scale" : "1x",
41 | "size" : "256x256"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "scale" : "2x",
46 | "size" : "256x256"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "scale" : "1x",
51 | "size" : "512x512"
52 | },
53 | {
54 | "idiom" : "mac",
55 | "scale" : "2x",
56 | "size" : "512x512"
57 | }
58 | ],
59 | "info" : {
60 | "author" : "xcode",
61 | "version" : 1
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/EnvironmentDependencies/EnvironmentDependencies/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "scale" : "1x",
11 | "size" : "16x16"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "scale" : "2x",
16 | "size" : "16x16"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "scale" : "1x",
21 | "size" : "32x32"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "scale" : "2x",
26 | "size" : "32x32"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "scale" : "1x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "scale" : "2x",
36 | "size" : "128x128"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "scale" : "1x",
41 | "size" : "256x256"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "scale" : "2x",
46 | "size" : "256x256"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "scale" : "1x",
51 | "size" : "512x512"
52 | },
53 | {
54 | "idiom" : "mac",
55 | "scale" : "2x",
56 | "size" : "512x512"
57 | }
58 | ],
59 | "info" : {
60 | "author" : "xcode",
61 | "version" : 1
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/SwiftDependencies/SwiftDependencies/LoggedOutFeature.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LoggedOutFeature.swift
3 | // SwiftDependencies
4 | //
5 | // Created by Brandon Williams on 30/03/2024.
6 | //
7 |
8 | import Dependencies
9 | import SwiftUI
10 |
11 | @MainActor
12 | @Observable
13 | class LoggedOutModel {
14 | @ObservationIgnored
15 | @Dependency(\.authentication) var authentication
16 | @ObservationIgnored
17 | @Dependency(\.logInSwitcher) var logInSwitcher
18 |
19 | var isAuthenticating = false
20 | func loginButtonTapped() async {
21 | isAuthenticating = true
22 | defer { isAuthenticating = false }
23 | do {
24 | let token = try await authentication.authenticate()
25 | await logInSwitcher.loggedIn(with: token)
26 | } catch {
27 | // TODO: Handle this
28 | }
29 | }
30 | }
31 |
32 | struct LoggedOutView: View {
33 | let model: LoggedOutModel
34 |
35 | var body: some View {
36 | VStack {
37 | if model.isAuthenticating {
38 | HStack {
39 | Text("Authenticating...")
40 | ProgressView()
41 | }
42 | } else {
43 | Text("You are logged out")
44 | }
45 | Button("Log in") {
46 | Task { await model.loginButtonTapped() }
47 | }
48 | .disabled(model.isAuthenticating)
49 | }
50 | }
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/SharedDependencies/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version: 5.9
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let name = "SharedDependencies"
7 | let asyncAlgorithms: Target.Dependency = .product(name: "AsyncAlgorithms", package: "swift-async-algorithms")
8 | let strictConcurrency: SwiftSetting = .enableExperimentalFeature("StrictConcurrency")
9 |
10 | let package = Package(
11 | name: name,
12 | platforms: [
13 | .macOS(.v14),
14 | .iOS(.v17),
15 | .visionOS(.v1),
16 | .tvOS(.v15),
17 | .watchOS(.v10)
18 | ],
19 | products: [
20 | .library(
21 | name: name,
22 | targets: [name]
23 | )
24 | ],
25 | dependencies: [
26 | // .package(url: "git@github.com:apple/swift-async-algorithms", from: "1.0.0")//,
27 | .package(url: "https://github.com/apple/swift-async-algorithms", from: "1.0.0")
28 | ],
29 | targets: [
30 | .target(
31 | name: name,
32 | dependencies: [
33 | asyncAlgorithms
34 | ],
35 | swiftSettings: [
36 | strictConcurrency
37 | ]
38 | ),
39 | .testTarget(
40 | name: "DependenciesTests",
41 | dependencies: [
42 | "SharedDependencies"
43 | ],
44 | swiftSettings: [
45 | strictConcurrency
46 | ]
47 | ),
48 | ]
49 | )
50 |
--------------------------------------------------------------------------------
/SwiftDependencies/SwiftDependencies/AppFeature.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppFeature.swift
3 | // SwiftDependencies
4 | //
5 | // Created by Brandon Williams on 30/03/2024.
6 | //
7 |
8 | import Dependencies
9 | import SharedDependencies
10 | import SwiftUI
11 |
12 | @MainActor
13 | @Observable
14 | class AppModel {
15 | @ObservationIgnored
16 | @Dependency(\.logInSwitcher) var logInSwitcher
17 |
18 | private(set) var state: State
19 |
20 | init(state: State) {
21 | self.state = state
22 | self.subscribe()
23 | }
24 |
25 | enum State {
26 | case authenticated(AuthenticatedModel)
27 | case loggedOut(LoggedOutModel)
28 | }
29 |
30 | func subscribe() {
31 | Task {
32 | for await token in logInSwitcher.tokenChannel {
33 | if token.isEmpty {
34 | state = .loggedOut(LoggedOutModel())
35 | } else {
36 | // Providing the 'token' to AuthenticatedModel is now proof that the user is
37 | // authenticated.
38 | state = .authenticated(AuthenticatedModel(token: token))
39 | }
40 | }
41 | }
42 | }
43 | }
44 |
45 | struct AppView: View {
46 | let model: AppModel
47 |
48 | var body: some View {
49 | switch model.state {
50 | case let .authenticated(model):
51 | AuthenticatedView(model: model)
52 | case let .loggedOut(model):
53 | LoggedOutView(model: model)
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/NeedleDependencies/NeedleDependencies/AuthenticatedComponent.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AuthenticatedComponent.swift
3 | // NeedleDependencies
4 | //
5 | // Created by Lucas van Dongen on 12/03/2024.
6 | //
7 |
8 | import NeedleFoundation
9 | import SharedDependencies
10 | import SwiftUI
11 |
12 | protocol AuthenticatedDependency: Dependency {
13 | var logInSwitcher: any LogInSwitching { get }
14 | }
15 |
16 | class AuthenticatedComponent: Component {
17 | var userManager: any UserManaging {
18 | return shared { UserManager(token: token) }
19 | }
20 |
21 | var storyFetcher: any StoryFetching {
22 | return shared { StoryFetcher(token: token) }
23 | }
24 |
25 | private let token: String
26 |
27 | init(
28 | parent: Scope,
29 | token: String
30 | ) {
31 | self.token = token
32 | super.init(parent: parent)
33 | }
34 | }
35 |
36 | @MainActor
37 | protocol AuthenticatedViewBuilding {
38 | var authenticatedView: AuthenticatedView { get }
39 | var storiesView: StoriesView { get }
40 | var userManagementView: UserManagementView { get }
41 | }
42 |
43 | extension AuthenticatedComponent: AuthenticatedViewBuilding {
44 | var authenticatedView: AuthenticatedView {
45 | AuthenticatedView(
46 | logInSwitcher: dependency.logInSwitcher,
47 | component: self
48 | )
49 | }
50 |
51 | var storiesView: StoriesView {
52 | StoriesView(storyFetcher: storyFetcher)
53 | }
54 |
55 | var userManagementView: UserManagementView {
56 | UserManagementView(userManager: userManager)
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/ComposableDependencies/ComposableDependencies/Dependencies.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Dependencies.swift
3 | // ComposableDependencies
4 | //
5 | // Created by Lucas van Dongen on 05/03/2024.
6 | //
7 |
8 | import ComposableArchitecture
9 | import SharedDependencies
10 |
11 | private enum AuthenticationKey: DependencyKey {
12 | static let liveValue: Authenticating = Authentication()
13 | }
14 |
15 | extension DependencyValues {
16 | var authentication: Authenticating {
17 | get { self[AuthenticationKey.self] }
18 | set { self[AuthenticationKey.self] = newValue }
19 | }
20 | }
21 |
22 | // This implementation is used to prevent a `nil` value for this dependency while the user is not authenticated yet
23 | final class PlaceholderUserManager: UserManaging {
24 | var token = "WR0NG_T4K3N"
25 |
26 | func update(user: String) async throws -> Bool {
27 | return false
28 | }
29 | }
30 |
31 | private enum UserManagerKey: DependencyKey {
32 | static let liveValue: any UserManaging = PlaceholderUserManager()
33 | }
34 |
35 | extension DependencyValues {
36 | var userManager: any UserManaging {
37 | get { self[UserManagerKey.self] }
38 | set { self[UserManagerKey.self] = newValue }
39 | }
40 | }
41 |
42 | final class PlaceholderStoryFetcher: StoryFetching {
43 | var token: String = ""
44 |
45 | // If this function would ever be executed, we have a problem
46 | func fetchStories() async throws -> [Story] {
47 | return []
48 | }
49 | }
50 |
51 | private enum StoryFetcherKey: DependencyKey {
52 | static let liveValue: any StoryFetching = PlaceholderStoryFetcher()
53 | }
54 |
55 | extension DependencyValues {
56 | var storyFetcher: any StoryFetching {
57 | get { self[StoryFetcherKey.self] }
58 | set { self[StoryFetcherKey.self] = newValue }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/SwiftDependencies/SwiftDependencies/Dependencies.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Dependencies.swift
3 | // SwiftDependencies
4 | //
5 | // Created by Brandon Williams on 30/03/2024.
6 | //
7 |
8 | import Dependencies
9 | import SharedDependencies
10 |
11 | private enum LogInSwitchingKey: DependencyKey {
12 | static let liveValue: any LogInSwitching = LogInSwitcher()
13 | }
14 |
15 | extension DependencyValues {
16 | var logInSwitcher: any LogInSwitching {
17 | get { self[LogInSwitchingKey.self] }
18 | set { self[LogInSwitchingKey.self] = newValue }
19 | }
20 | }
21 |
22 | private enum AuthenticationKey: DependencyKey {
23 | static let liveValue: any Authenticating = Authentication()
24 | }
25 |
26 | extension DependencyValues {
27 | var authentication: Authenticating {
28 | get { self[AuthenticationKey.self] }
29 | set { self[AuthenticationKey.self] = newValue }
30 | }
31 | }
32 |
33 | extension DependencyValues {
34 | private enum UserManagerKey: DependencyKey {
35 | static let liveValue: any UserManaging = UserManager(token: "invalid-token")
36 | }
37 | subscript(userManagerForToken token: String) -> any UserManaging {
38 | get {
39 | var manager = self[UserManagerKey.self]
40 | manager.token = token
41 | return manager
42 | }
43 | set {
44 | var newValue = newValue
45 | newValue.token = token
46 | self[UserManagerKey.self] = newValue
47 | }
48 | }
49 | }
50 |
51 | extension DependencyValues {
52 | private enum StoryFetcherKey: DependencyKey {
53 | static let liveValue: any StoryFetching = StoryFetcher(token: "invalid-token")
54 | }
55 | subscript(storyFetcherForToken token: String) -> any StoryFetching {
56 | get {
57 | var manager = self[StoryFetcherKey.self]
58 | manager.token = token
59 | return manager
60 | }
61 | set {
62 | var newValue = newValue
63 | newValue.token = token
64 | self[StoryFetcherKey.self] = newValue
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Dependency Injection for Modern Swift Applications
2 | ## Dependency Injection for Modern Swift Applications and Comparing five different approaches towards Dependency Injection
3 |
4 | 
5 |
6 | This repo belongs to two articles I've written about dependency injection. I'm reviewing the following five principeles:
7 |
8 | * [Compile-Time Safety](https://dependency_injection_swift_swiftui.php#compile-time-safety) - if it compiles, is it correct and crash-free?
9 | * [Generational Safety](https://dependency_injection_swift_swiftui.php#generational-safety) - can we safely unlock dependencies later on?
10 | * [Scalability](https://dependency_injection_swift_swiftui.php#scaling) - how hard is it to maintain or add features when the app grows?
11 | * [Usability](https://dependency_injection_swift_swiftui.php#usability) - how easy is it to new team members and to add or maintain features?
12 | * [Testability](https://dependency_injection_swift_swiftui.php#testability-and-previews) - can we easily mock our dependencies for tests and previews?
13 |
14 | This repo holds simple but complete examples that highlight the different aspects of DI for each different approach. The following five frameworks or techniques for DI have been selected to give a complete overview of all different types of solutions that exist:
15 |
16 | * [Manual Tree](https://github.com/LucasVanDongen/SwiftDependencyInjectionCompared/tree/main/PassedDependencies) - Pass all dependencies manually
17 | * [EnvironmentObject](https://github.com/LucasVanDongen/SwiftDependencyInjectionCompared/tree/main/EnvironmentDependencies) - Using SwiftUI's built in storage
18 | * [Factory](https://github.com/LucasVanDongen/SwiftDependencyInjectionCompared/tree/main/FactoryDependencies) - A simple statically declared container approach
19 | * [Needle](https://github.com/LucasVanDongen/SwiftDependencyInjectionCompared/tree/main/NeedleDependencies) - Uber's solution to boilerplate-heavy manual solutions
20 | * [Composable Architecture](https://https://github.com/LucasVanDongen/SwiftDependencyInjectionCompared/tree/main/ComposableDependencies) - How does TCA's solution compare?
21 |
22 | Read the first article ["Managing Dependencies in the Age of SwiftUI" here](dependency_injection_swift_swiftui.php), and the second article ["Comparing five different approaches towards Dependency Injection" here](dependency_injection_swift_swiftui.php).
23 |
--------------------------------------------------------------------------------
/PassedDependencies/PassedDependencies/Factories/AuthenticatedFactory.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AuthenticatedFactory.swift
3 | // PassedDependencies
4 | //
5 | // Created by Lucas van Dongen on 23/03/2024.
6 | //
7 |
8 | import Foundation
9 | import SharedDependencies
10 |
11 | class AuthenticatedFactory: AuthenticatedDependenciesContaining {
12 | let logInSwitcher: LogInSwitching
13 | let userManager: UserManaging
14 | let storyFetcher: StoryFetching
15 |
16 | /// Everything that is needed to build this Factory needs to be passed forward, including dependencies already created in a parent node
17 | /// - Parameters:
18 | /// - token: The key to unlock the `UserManager` and `StoryFetcher` implementations
19 | /// - logInSwitcher: A dependency we need to pass forward from the root
20 | init(
21 | token: String,
22 | logInSwitcher: LogInSwitching // In Needle, all dependencies inherited from all nodes toward and including the root are handled by the `parent` Component
23 | ) {
24 | self.logInSwitcher = logInSwitcher
25 | userManager = UserManager(token: token)
26 | storyFetcher = StoryFetcher(token: token)
27 | }
28 | }
29 |
30 | // A separate extension for building the Views
31 | // Ideal for keeping your Factories UI dependency free, or for supporting multiple platforms
32 | extension AuthenticatedFactory {
33 | var userManagementView: UserManagementView {
34 | UserManagementView(userManager: userManager)
35 | }
36 |
37 | var storiesView: StoriesView {
38 | StoriesView(storyFetcher: storyFetcher)
39 | }
40 | }
41 |
42 | // Example implementation for AuthenticatedView using this Factory:
43 | import SwiftUI
44 |
45 | @MainActor
46 | struct AuthenticatedFactoryView: View {
47 | let factory: AuthenticatedFactory
48 |
49 | @State private var isLoggingOut = false
50 |
51 | var body: some View {
52 | VStack {
53 | // This View now knows nothing about how these Views are built
54 | factory.userManagementView
55 | factory.storiesView
56 | Button {
57 | isLoggingOut = true
58 | } label: {
59 | Text("Log Out")
60 | }.task(id: isLoggingOut, priority: .high) {
61 | guard isLoggingOut else {
62 | return
63 | }
64 |
65 | defer {
66 | isLoggingOut = false
67 | }
68 |
69 | await factory.logInSwitcher.loggedOut()
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/NeedleDependencies/NeedleDependencies/NeedleGenerated.swift:
--------------------------------------------------------------------------------
1 |
2 |
3 | import NeedleFoundation
4 | import SharedDependencies
5 | import SwiftUI
6 |
7 | // swiftlint:disable unused_declaration
8 | private let needleDependenciesHash : String? = nil
9 |
10 | // MARK: - Traversal Helpers
11 |
12 | private func parent1(_ component: NeedleFoundation.Scope) -> NeedleFoundation.Scope {
13 | return component.parent
14 | }
15 |
16 | // MARK: - Providers
17 |
18 | #if !NEEDLE_DYNAMIC
19 |
20 | private class AuthenticatedDependencycda53ef9a0d1fafe1614Provider: AuthenticatedDependency {
21 | var logInSwitcher: any LogInSwitching {
22 | return rootComponent.logInSwitcher
23 | }
24 | private let rootComponent: RootComponent
25 | init(rootComponent: RootComponent) {
26 | self.rootComponent = rootComponent
27 | }
28 | }
29 | /// ^->RootComponent->AuthenticatedComponent
30 | private func factory31f7272d9f1e1bb4556eb3a8f24c1d289f2c0f2e(_ component: NeedleFoundation.Scope) -> AnyObject {
31 | return AuthenticatedDependencycda53ef9a0d1fafe1614Provider(rootComponent: parent1(component) as! RootComponent)
32 | }
33 | private class LogInDependency59c56af202a7286b1d4fProvider: LogInDependency {
34 | var logInSwitcher: any LogInSwitching {
35 | return rootComponent.logInSwitcher
36 | }
37 | private let rootComponent: RootComponent
38 | init(rootComponent: RootComponent) {
39 | self.rootComponent = rootComponent
40 | }
41 | }
42 | /// ^->RootComponent->LogInComponent
43 | private func factory722f9ff168b373921da5b3a8f24c1d289f2c0f2e(_ component: NeedleFoundation.Scope) -> AnyObject {
44 | return LogInDependency59c56af202a7286b1d4fProvider(rootComponent: parent1(component) as! RootComponent)
45 | }
46 |
47 | #else
48 | extension AuthenticatedComponent: Registration {
49 | public func registerItems() {
50 | keyPathToName[\AuthenticatedDependency.logInSwitcher] = "logInSwitcher-any LogInSwitching"
51 | }
52 | }
53 | extension RootComponent: Registration {
54 | public func registerItems() {
55 |
56 |
57 | }
58 | }
59 | extension LogInComponent: Registration {
60 | public func registerItems() {
61 | keyPathToName[\LogInDependency.logInSwitcher] = "logInSwitcher-any LogInSwitching"
62 | }
63 | }
64 |
65 |
66 | #endif
67 |
68 | private func factoryEmptyDependencyProvider(_ component: NeedleFoundation.Scope) -> AnyObject {
69 | return EmptyDependencyProvider(component: component)
70 | }
71 |
72 | // MARK: - Registration
73 | private func registerProviderFactory(_ componentPath: String, _ factory: @escaping (NeedleFoundation.Scope) -> AnyObject) {
74 | __DependencyProviderRegistry.instance.registerDependencyProviderFactory(for: componentPath, factory)
75 | }
76 |
77 | #if !NEEDLE_DYNAMIC
78 |
79 | @inline(never) private func register1() {
80 | registerProviderFactory("^->RootComponent->AuthenticatedComponent", factory31f7272d9f1e1bb4556eb3a8f24c1d289f2c0f2e)
81 | registerProviderFactory("^->RootComponent", factoryEmptyDependencyProvider)
82 | registerProviderFactory("^->RootComponent->LogInComponent", factory722f9ff168b373921da5b3a8f24c1d289f2c0f2e)
83 | }
84 | #endif
85 |
86 | public func registerProviderFactories() {
87 | #if !NEEDLE_DYNAMIC
88 | register1()
89 | #endif
90 | }
91 |
--------------------------------------------------------------------------------
/ComposableDependencies/ComposableDependencies.xcodeproj/xcshareddata/xcschemes/ComposableDependencies.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
9 |
10 |
16 |
22 |
23 |
24 |
25 |
26 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
60 |
62 |
68 |
69 |
70 |
71 |
73 |
74 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/ComposableDependencies/ComposableDependencies/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // ComposableDependencies
4 | //
5 | // Created by Lucas van Dongen on 04/03/2024.
6 | //
7 |
8 | import ComposableArchitecture
9 | import SharedDependencies
10 | import SwiftUI
11 |
12 | @MainActor
13 | struct AuthenticatedView: View {
14 | let store: StoreOf
15 |
16 | let userManagementFeature = Store(initialState: UserManagementFeature.State.loaded) {
17 | UserManagementFeature()
18 | }
19 | let storiesFeature = Store(initialState: StoriesFeature.State.loading) {
20 | StoriesFeature()
21 | }
22 |
23 | var body: some View {
24 | VStack {
25 | UserManagementView(store: userManagementFeature)
26 | StoriesView(store: storiesFeature)
27 | Button {
28 | store.send(.logOut)
29 | } label: {
30 | Text("Log Out")
31 | }
32 | }
33 | }
34 | }
35 |
36 | @MainActor
37 | struct UserManagementView: View {
38 | let store: StoreOf
39 |
40 | @Dependency(\.userManager) var userManager
41 |
42 | var body: some View {
43 | VStack {
44 | Text("You are logged in with token \(userManager.token)")
45 |
46 | switch store.state {
47 | case .loaded:
48 | Button {
49 | store.send(.update)
50 | } label: {
51 | Text("Update User")
52 | }
53 | case .updating:
54 | HStack {
55 | Text("Updating User...")
56 | ProgressView()
57 | }
58 | case let .failed(reason):
59 | Text("Failed updating User:\n\(reason)")
60 | case .updated:
61 | Text("You have updated your user successfully")
62 | }
63 | }
64 | }
65 | }
66 |
67 | @MainActor
68 | struct StoriesView: View {
69 | let store: StoreOf
70 |
71 | var body: some View {
72 | switch store.state {
73 | case .loading:
74 | HStack {
75 | Text("Fetching stories...")
76 | ProgressView()
77 | }
78 | .task {
79 | store.send(.startLoading)
80 | }
81 | case let .failed(reason):
82 | Text("Failed fetching stories:\n\(reason)")
83 | case let .loaded(stories):
84 | List {
85 | ForEach(stories, id: \.name) { story in
86 | Text("Author: \(story.author)\nName: \(story.name)")
87 | }
88 | }
89 | }
90 | }
91 | }
92 |
93 | @MainActor
94 | struct LogInView: View {
95 | let store: StoreOf
96 |
97 | var body: some View {
98 | switch store.state {
99 | case .authenticating:
100 | HStack {
101 | Text("Authenticating...")
102 | ProgressView()
103 | }
104 | case .waiting:
105 | VStack {
106 | Text("You are logged out now")
107 | Button {
108 | store.send(.logIn)
109 | } label: {
110 | Text("Log In")
111 | }
112 | }
113 | }
114 | }
115 | }
116 |
117 | @MainActor
118 | struct AppView: View {
119 | let store: StoreOf
120 |
121 | var body: some View {
122 | switch store.case {
123 | case let .authenticated(store):
124 | AuthenticatedView(store: store)
125 | case let .logIn(store):
126 | LogInView(store: store)
127 | }
128 | }
129 | }
130 |
131 | @MainActor
132 | struct ContentView: View {
133 | let store: StoreOf
134 |
135 | init() {
136 | let authState = LogInFeature.State.waiting
137 | let featureState = AppRootFeature.State.logIn(authState)
138 |
139 | store = Store(initialState: featureState) {
140 | AppRootFeature.body._printChanges()
141 | }
142 | }
143 |
144 | var body: some View {
145 | AppView(store: store)
146 | }
147 | }
148 |
149 | #Preview {
150 | ContentView()
151 | }
152 |
--------------------------------------------------------------------------------
/SwiftDependencies/SwiftDependencies/AuthenticatedFeature.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AuthenticatedFeature.swift
3 | // SwiftDependencies
4 | //
5 | // Created by Brandon Williams on 30/03/2024.
6 | //
7 |
8 | import Dependencies
9 | import SharedDependencies
10 | import SwiftUI
11 |
12 | @MainActor
13 | @Observable
14 | class AuthenticatedModel {
15 | @ObservationIgnored
16 | @Dependency(\.logInSwitcher) var logInSwitcher
17 |
18 | var isLoggingOut = false
19 | let stories: StoriesModel
20 | let userManagement: UserManagementModel
21 |
22 | init(token: String) {
23 | stories = StoriesModel(token: token)
24 | userManagement = UserManagementModel(token: token)
25 | }
26 |
27 | func logoutButtonTapped() async {
28 | isLoggingOut = true
29 | defer { isLoggingOut = false }
30 |
31 | await logInSwitcher.loggedOut()
32 | }
33 | }
34 |
35 | struct AuthenticatedView: View {
36 | let model: AuthenticatedModel
37 |
38 | var body: some View {
39 | Form {
40 | UserManagementView(model: model.userManagement)
41 | StoriesView(model: model.stories)
42 |
43 | Button("Log out") {
44 | Task { await model.logoutButtonTapped() }
45 | }
46 | .disabled(model.isLoggingOut)
47 | }
48 | }
49 | }
50 |
51 | @MainActor
52 | @Observable
53 | class UserManagementModel {
54 | @ObservationIgnored
55 | @Dependency var userManager: any UserManaging
56 |
57 | init(token: String) {
58 | // In order to access the 'userManager` dependency we must supply proof that the user is
59 | // authenticated by passing the token to the subscript key path.
60 | self._userManager = Dependency(\.[userManagerForToken: token])
61 | self.state = .loaded
62 | }
63 |
64 | var state = State.loaded
65 |
66 | enum State {
67 | case loaded
68 | case updating
69 | case failed(reason: String)
70 | case updated
71 | }
72 |
73 | func updateUserButtonTapped() async {
74 | state = .updating
75 | do {
76 | _ = try await userManager.update(user: "")
77 | state = .updated
78 | } catch {
79 | state = .failed(reason: "Something went wrong")
80 | }
81 | }
82 | }
83 |
84 | struct UserManagementView: View {
85 | let model: UserManagementModel
86 |
87 | var body: some View {
88 | Section {
89 | Text("You are logged in with token \(model.userManager.token)")
90 | switch model.state {
91 | case .loaded:
92 | Button("Update user") {
93 | Task { await model.updateUserButtonTapped() }
94 | }
95 | case .updating:
96 | HStack { Text("Updating User..."); ProgressView() }
97 | case let .failed(reason):
98 | Text("Failed updating User:\n\(reason)")
99 | case .updated:
100 | Text("You have updated your user successfully")
101 | }
102 | } header: {
103 | Text("User management")
104 | }
105 | }
106 | }
107 |
108 | @MainActor
109 | @Observable
110 | class StoriesModel {
111 | @ObservationIgnored
112 | @Dependency private var storyFetcher: any StoryFetching
113 |
114 | init(token: String) {
115 | // In order to access the 'storyFetcher` dependency we must supply proof that the user is
116 | // authenticated by passing the token to the subscript key path.
117 | self._storyFetcher = Dependency(\.[storyFetcherForToken: token])
118 | self.state = state
119 | }
120 |
121 | var state = State.fetching
122 |
123 | enum State {
124 | case fetching
125 | case failed(reason: String)
126 | case fetched(stories: [Story])
127 | }
128 |
129 | func onFetch() async {
130 | state = .fetching
131 | do {
132 | state = .fetched(stories: try await storyFetcher.fetchStories())
133 | } catch let error {
134 | state = .failed(reason: error.localizedDescription)
135 | }
136 | }
137 | }
138 |
139 | struct StoriesView: View {
140 | let model: StoriesModel
141 |
142 | var body: some View {
143 | switch model.state {
144 | case .fetching:
145 | HStack {
146 | Text("Fetching stories...")
147 | ProgressView()
148 | }
149 | .task { await model.onFetch() }
150 | case let .failed(reason):
151 | Text("Failed fetching stories:\n\(reason)")
152 | case let .fetched(stories):
153 | List {
154 | ForEach(stories, id: \.name) { story in
155 | Text("Author: \(story.author)\nName: \(story.name)")
156 | }
157 | }
158 | }
159 | }
160 | }
161 |
162 |
--------------------------------------------------------------------------------
/DependenciesCompared.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "pins" : [
3 | {
4 | "identity" : "combine-schedulers",
5 | "kind" : "remoteSourceControl",
6 | "location" : "https://github.com/pointfreeco/combine-schedulers",
7 | "state" : {
8 | "revision" : "9dc9cbe4bc45c65164fa653a563d8d8db61b09bb",
9 | "version" : "1.0.0"
10 | }
11 | },
12 | {
13 | "identity" : "factory",
14 | "kind" : "remoteSourceControl",
15 | "location" : "http://github.com/hmlongco/Factory",
16 | "state" : {
17 | "revision" : "587995f7d5cc667951d635fbf6b4252324ba0439",
18 | "version" : "2.3.2"
19 | }
20 | },
21 | {
22 | "identity" : "needle",
23 | "kind" : "remoteSourceControl",
24 | "location" : "https://github.com/uber/needle",
25 | "state" : {
26 | "branch" : "master",
27 | "revision" : "6db73ae873952794b94fd6bb5111554e23c160af"
28 | }
29 | },
30 | {
31 | "identity" : "swift-async-algorithms",
32 | "kind" : "remoteSourceControl",
33 | "location" : "https://github.com/apple/swift-async-algorithms",
34 | "state" : {
35 | "revision" : "da4e36f86544cdf733a40d59b3a2267e3a7bbf36",
36 | "version" : "1.0.0"
37 | }
38 | },
39 | {
40 | "identity" : "swift-case-paths",
41 | "kind" : "remoteSourceControl",
42 | "location" : "https://github.com/pointfreeco/swift-case-paths",
43 | "state" : {
44 | "revision" : "e593aba2c6222daad7c4f2732a431eed2c09bb07",
45 | "version" : "1.3.0"
46 | }
47 | },
48 | {
49 | "identity" : "swift-clocks",
50 | "kind" : "remoteSourceControl",
51 | "location" : "https://github.com/pointfreeco/swift-clocks",
52 | "state" : {
53 | "revision" : "a8421d68068d8f45fbceb418fbf22c5dad4afd33",
54 | "version" : "1.0.2"
55 | }
56 | },
57 | {
58 | "identity" : "swift-collections",
59 | "kind" : "remoteSourceControl",
60 | "location" : "https://github.com/apple/swift-collections",
61 | "state" : {
62 | "revision" : "94cf62b3ba8d4bed62680a282d4c25f9c63c2efb",
63 | "version" : "1.1.0"
64 | }
65 | },
66 | {
67 | "identity" : "swift-composable-architecture",
68 | "kind" : "remoteSourceControl",
69 | "location" : "https://github.com/pointfreeco/swift-composable-architecture",
70 | "state" : {
71 | "revision" : "115fe5af41d333b6156d4924d7c7058bc77fd580",
72 | "version" : "1.9.2"
73 | }
74 | },
75 | {
76 | "identity" : "swift-concurrency-extras",
77 | "kind" : "remoteSourceControl",
78 | "location" : "https://github.com/pointfreeco/swift-concurrency-extras",
79 | "state" : {
80 | "revision" : "bb5059bde9022d69ac516803f4f227d8ac967f71",
81 | "version" : "1.1.0"
82 | }
83 | },
84 | {
85 | "identity" : "swift-custom-dump",
86 | "kind" : "remoteSourceControl",
87 | "location" : "https://github.com/pointfreeco/swift-custom-dump",
88 | "state" : {
89 | "revision" : "3ce83179e5f0c83ad54c305779c6b438e82aaf1d",
90 | "version" : "1.2.1"
91 | }
92 | },
93 | {
94 | "identity" : "swift-dependencies",
95 | "kind" : "remoteSourceControl",
96 | "location" : "https://github.com/pointfreeco/swift-dependencies",
97 | "state" : {
98 | "revision" : "d3a5af3038a09add4d7682f66555d6212058a3c0",
99 | "version" : "1.2.2"
100 | }
101 | },
102 | {
103 | "identity" : "swift-identified-collections",
104 | "kind" : "remoteSourceControl",
105 | "location" : "https://github.com/pointfreeco/swift-identified-collections",
106 | "state" : {
107 | "revision" : "d1e45f3e1eee2c9193f5369fa9d70a6ddad635e8",
108 | "version" : "1.0.0"
109 | }
110 | },
111 | {
112 | "identity" : "swift-perception",
113 | "kind" : "remoteSourceControl",
114 | "location" : "https://github.com/pointfreeco/swift-perception",
115 | "state" : {
116 | "revision" : "42240120b2a8797595433288ab4118f8042214c3",
117 | "version" : "1.1.1"
118 | }
119 | },
120 | {
121 | "identity" : "swift-syntax",
122 | "kind" : "remoteSourceControl",
123 | "location" : "https://github.com/apple/swift-syntax",
124 | "state" : {
125 | "revision" : "64889f0c732f210a935a0ad7cda38f77f876262d",
126 | "version" : "509.1.1"
127 | }
128 | },
129 | {
130 | "identity" : "swiftui-navigation",
131 | "kind" : "remoteSourceControl",
132 | "location" : "https://github.com/pointfreeco/swiftui-navigation",
133 | "state" : {
134 | "revision" : "d9e72f3083c08375794afa216fb2f89c0114f303",
135 | "version" : "1.2.1"
136 | }
137 | },
138 | {
139 | "identity" : "xctest-dynamic-overlay",
140 | "kind" : "remoteSourceControl",
141 | "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay",
142 | "state" : {
143 | "revision" : "b58e6627149808b40634c4552fcf2f44d0b3ca87",
144 | "version" : "1.1.0"
145 | }
146 | }
147 | ],
148 | "version" : 2
149 | }
150 |
--------------------------------------------------------------------------------
/ComposableDependencies/ComposableDependencies/Features.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Features.swift
3 | // ComposableDependencies
4 | //
5 | // Created by Lucas van Dongen on 06/03/2024.
6 | //
7 |
8 | import ComposableArchitecture
9 | import SharedDependencies
10 |
11 | struct Session: Equatable {
12 | let token: String
13 | }
14 |
15 | @Reducer(state: .equatable)
16 | enum AppRootFeature {
17 | case authenticated(AuthenticatedFeature)
18 | case logIn(LogInFeature)
19 |
20 | public static var body: some ReducerOf {
21 | Reduce { state, action in
22 | switch action {
23 | case let .logIn(.authenticatedSuccessfully(token)):
24 | state = .authenticated(AuthenticatedFeature.State(token: token))
25 | return .none
26 | case .logIn:
27 | return .none // Ignore the rest
28 | case .authenticated:
29 | return .none // Ignore unless we would have log out functionality
30 | }
31 | }
32 | .ifCaseLet(\.logIn, action: \.logIn) {
33 | LogInFeature()
34 | }
35 | .ifCaseLet(\.authenticated, action: \.authenticated) {
36 | AuthenticatedFeature()
37 | // .dependency(\.userManager, UserManager(token: token)
38 | // .dependency(\.storyFetcher, .StoryFetcher(token: token)
39 | }._printChanges()
40 | }
41 | }
42 |
43 | @Reducer
44 | struct AuthenticatedFeature {
45 | @ObservableState
46 | struct State: Equatable {
47 | let token: String
48 | }
49 |
50 | enum Action {
51 | case logOut
52 | }
53 |
54 | var body: some Reducer {
55 | Reduce { state, action in
56 | switch action {
57 | case .logOut:
58 | return .none
59 | }
60 | }
61 | }
62 | }
63 |
64 | @Reducer
65 | struct LogInFeature {
66 | @Dependency(\.authentication) var authentication
67 |
68 | @ObservableState
69 | enum State: Equatable {
70 | case waiting
71 | case authenticating
72 | }
73 |
74 | enum Action {
75 | case logIn
76 | case authenticationError(Error)
77 | case authenticatedSuccessfully(token: String)
78 | }
79 |
80 | var body: some Reducer {
81 | Reduce { state, action in
82 | switch action {
83 | case .logIn:
84 | state = .authenticating
85 | return .run { send in
86 | do {
87 | let token = try await authentication.authenticate()
88 | await send(.authenticatedSuccessfully(token: token))
89 | } catch let error {
90 | await send(.authenticationError(error))
91 | }
92 | }
93 | case .authenticationError:
94 | return .none // Not handled ATM
95 | case .authenticatedSuccessfully:
96 | return .none // Only interesting for root feature
97 | }
98 | }
99 | }
100 | }
101 |
102 | @Reducer
103 | struct StoriesFeature {
104 | @Dependency(\.storyFetcher) var storyFetcher
105 |
106 | @ObservableState
107 | enum State: Equatable {
108 | case loading
109 | case failed(reason: String)
110 | case loaded(stories: [Story])
111 | }
112 |
113 | enum Action {
114 | case startLoading
115 | case loaded(stories: [Story])
116 | }
117 |
118 | var body: some Reducer {
119 | Reduce { state, action in
120 | switch action {
121 | case .startLoading:
122 | return .run { send in
123 | do {
124 | let stories = try await storyFetcher.fetchStories()
125 | await send(.loaded(stories: stories))
126 | } catch {
127 | // We're ignoring error handling for now
128 | }
129 | }
130 | case let .loaded(stories):
131 | state = .loaded(stories: stories)
132 | return .none
133 | }
134 | }
135 | }
136 | }
137 |
138 | @Reducer
139 | struct UserManagementFeature {
140 | @Dependency(\.userManager) var userManager
141 |
142 | @ObservableState
143 | enum State: Equatable {
144 | case loaded
145 | case updating
146 | case failed(reason: String)
147 | case updated
148 | }
149 |
150 | enum Action {
151 | case update
152 | case failed(reason: String)
153 | case updated
154 | }
155 |
156 | var body: some Reducer {
157 | Reduce { state, action in
158 | switch action {
159 | case .update:
160 | state = .updating
161 |
162 | return .run { send in
163 | do {
164 | _ = try await userManager.update(user: "")
165 | await send(.updated)
166 | } catch {
167 | // Ignore for now
168 | }
169 | }
170 | case let .failed(reason):
171 | state = .failed(reason: reason)
172 | return .none
173 | case .updated:
174 | state = .updated
175 | return .none
176 | }
177 | }
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/NeedleDependencies/NeedleDependencies/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // NeedleDependencies
4 | //
5 | // Created by Lucas van Dongen on 12/03/2024.
6 | //
7 |
8 | import SharedDependencies
9 | import SwiftUI
10 |
11 | @MainActor
12 | struct AuthenticatedView: View {
13 | let logInSwitcher: any LogInSwitching
14 | let component: AuthenticatedComponent
15 |
16 | @State private var isLoggingOut = false
17 |
18 | var body: some View {
19 | VStack {
20 | // AuthenticatedView needs to know what dependencies UserManagementView and StoriesView need
21 | // A small burden now, but it will increase exponentially with the app's complexity
22 | component.userManagementView
23 | component.storiesView
24 | Button {
25 | isLoggingOut = true
26 | } label: {
27 | Text("Log Out")
28 | }.task(id: isLoggingOut, priority: .high) {
29 | guard isLoggingOut else {
30 | return
31 | }
32 |
33 | defer {
34 | isLoggingOut = false
35 | }
36 |
37 | await logInSwitcher.loggedOut()
38 | }
39 | }
40 | }
41 | }
42 |
43 | @MainActor
44 | struct UserManagementView: View {
45 | private enum ViewState: Equatable {
46 | case loaded
47 | case updating
48 | case failed(reason: String)
49 | case updated
50 | }
51 |
52 | @State private var state: ViewState = .loaded
53 |
54 | let userManager: any UserManaging
55 |
56 | var body: some View {
57 | VStack {
58 | Text("You are logged in with token \(userManager.token)")
59 |
60 | switch state {
61 | case .loaded:
62 | Button {
63 | state = .updating
64 | } label: {
65 | Text("Update User")
66 | }
67 | case .updating:
68 | HStack {
69 | Text("Updating User...")
70 | ProgressView()
71 | }
72 | case let .failed(reason):
73 | Text("Failed updating User:\n\(reason)")
74 | case .updated:
75 | Text("You have updated your user successfully")
76 | }
77 | }.task(id: state, priority: .high) {
78 | guard state == .updating else {
79 | return
80 | }
81 |
82 | do {
83 | _ = try await userManager.update(user: "")
84 | state = .updated
85 | } catch {
86 | // Ignore for now
87 | }
88 | }
89 | }
90 | }
91 |
92 | @MainActor
93 | struct StoriesView: View {
94 | private enum LoadingState {
95 | case fetching
96 | case failed(reason: String)
97 | case fetched(stories: [Story])
98 | }
99 |
100 | @State private var state: LoadingState = .fetching
101 |
102 | let storyFetcher: any StoryFetching
103 |
104 | var body: some View {
105 | switch state {
106 | case .fetching:
107 | HStack {
108 | Text("Fetching stories...")
109 | ProgressView()
110 | }
111 | .task {
112 | state = .fetching
113 | do {
114 | let stories = try await storyFetcher.fetchStories()
115 | state = .fetched(stories: stories) // You can safely mutate state properties from any thread.
116 | } catch let error {
117 | state = .failed(reason: error.localizedDescription)
118 | }
119 | }
120 | case let .failed(reason):
121 | Text("Failed fetching stories:\n\(reason)")
122 | case let .fetched(stories):
123 | List {
124 | ForEach(stories, id: \.name) { story in
125 | Text("Author: \(story.author)\nName: \(story.name)")
126 | }
127 | }
128 | }
129 | }
130 | }
131 |
132 | @MainActor
133 | struct LogInView: View {
134 | let authentication: Authenticating
135 | let logInSwitcher: any LogInSwitching
136 |
137 | @State private var isAuthenticating = false
138 |
139 | var body: some View {
140 | switch isAuthenticating {
141 | case true:
142 | HStack {
143 | Text("Authenticating...")
144 | ProgressView()
145 | }
146 | case false:
147 | VStack {
148 | Text("You are logged out now")
149 | Button {
150 | Task {
151 | await authenticate()
152 | }
153 | } label: {
154 | Text("Log In")
155 | }
156 | }
157 | }
158 | }
159 |
160 | private func authenticate() async {
161 | isAuthenticating = true
162 |
163 | defer {
164 | isAuthenticating = false
165 | }
166 |
167 | do {
168 | let token = try await authentication.authenticate()
169 | await logInSwitcher.tokenChannel.send(token)
170 | } catch {
171 | // Not implemented
172 | }
173 | }
174 | }
175 |
176 | enum AppState {
177 | case loggedOut
178 | case authenticated(token: String)
179 | }
180 |
181 | @MainActor
182 | class AppViewModel: ObservableObject {
183 | @Published private(set) var state: AppState = .loggedOut
184 |
185 | private let logInSwitcher: any LogInSwitching
186 |
187 | init(logInSwitcher: any LogInSwitching) {
188 | self.logInSwitcher = logInSwitcher
189 |
190 | Task.detached { [weak self] in
191 | await self?.observe(logInSwitcher: logInSwitcher)
192 | }
193 | }
194 |
195 | private func observe(logInSwitcher: any LogInSwitching) async {
196 | for await token in logInSwitcher.tokenChannel {
197 | state = switch token.isEmpty {
198 | case true: .loggedOut
199 | case false: .authenticated(token: token)
200 | }
201 | }
202 | }
203 | }
204 |
205 | @MainActor
206 | struct AppView: View {
207 | @StateObject var viewModel: AppViewModel
208 |
209 | let rootComponent: RootComponent
210 | let logInComponent: LogInComponent
211 |
212 | var body: some View {
213 | switch viewModel.state {
214 | case let .authenticated(token):
215 | rootComponent.authenticatedComponent(token: token)
216 | .authenticatedView
217 | case .loggedOut:
218 | logInComponent.logInView
219 | }
220 | }
221 | }
222 |
223 | struct ContentView: View {
224 | @State private var rootComponent = RootComponent()
225 |
226 | var body: some View {
227 | rootComponent.appView
228 | }
229 | }
230 |
231 | #Preview {
232 | ContentView()
233 | }
234 |
--------------------------------------------------------------------------------
/FactoryDependencies/FactoryDependencies/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // FactoryDependencies
4 | //
5 | // Created by Lucas van Dongen on 12/03/2024.
6 | //
7 |
8 | import Factory
9 | import SharedDependencies
10 | import SwiftUI
11 |
12 | @MainActor
13 | struct AuthenticatedView: View {
14 | @Injected(\.logInSwitcher) private var logInSwitcher
15 |
16 | @State private var isLoggingOut = false
17 |
18 | var body: some View {
19 | VStack {
20 | // No dependencies are passed here, making it easier to modularize your application
21 | UserManagementView()
22 | StoriesView()
23 | Button {
24 | isLoggingOut = true
25 | } label: {
26 | Text("Log Out")
27 | }.task(id: isLoggingOut, priority: .high) {
28 | guard isLoggingOut else {
29 | return
30 | }
31 |
32 | defer {
33 | isLoggingOut = false
34 | }
35 |
36 | await logInSwitcher.loggedOut()
37 | }
38 | }
39 | }
40 | }
41 |
42 | @MainActor
43 | struct UserManagementView: View {
44 | private enum ViewState: Equatable {
45 | case loaded
46 | case updating
47 | case failed(reason: String)
48 | case updated
49 | }
50 |
51 | @State private var state: ViewState = .loaded
52 |
53 | @Injected(\.userManager) private var userManager
54 |
55 | var body: some View {
56 | VStack {
57 | Text("You are logged in with token \(userManager.token)")
58 |
59 | switch state {
60 | case .loaded:
61 | Button {
62 | state = .updating
63 | } label: {
64 | Text("Update User")
65 | }
66 | case .updating:
67 | HStack {
68 | Text("Updating User...")
69 | ProgressView()
70 | }
71 | case let .failed(reason):
72 | Text("Failed updating User:\n\(reason)")
73 | case .updated:
74 | Text("You have updated your user successfully")
75 | }
76 | }.task(id: state, priority: .high) {
77 | guard state == .updating else {
78 | return
79 | }
80 |
81 | do {
82 | _ = try await userManager.update(user: "")
83 | state = .updated
84 | } catch {
85 | // Ignore for now
86 | }
87 | }
88 | }
89 | }
90 |
91 | @MainActor
92 | struct StoriesView: View {
93 | private enum LoadingState {
94 | case fetching
95 | case failed(reason: String)
96 | case fetched(stories: [Story])
97 | }
98 |
99 | @State private var state: LoadingState = .fetching
100 |
101 | @Injected(\.storyFetcher) private var storyFetcher
102 |
103 | var body: some View {
104 | switch state {
105 | case .fetching:
106 | HStack {
107 | Text("Fetching stories...")
108 | ProgressView()
109 | }
110 | .task {
111 | state = .fetching
112 | do {
113 | let stories = try await storyFetcher.fetchStories()
114 | state = .fetched(stories: stories) // You can safely mutate state properties from any thread.
115 | } catch let error {
116 | state = .failed(reason: error.localizedDescription)
117 | }
118 | }
119 | case let .failed(reason):
120 | Text("Failed fetching stories:\n\(reason)")
121 | case let .fetched(stories):
122 | List {
123 | ForEach(stories, id: \.name) { story in
124 | Text("Author: \(story.author)\nName: \(story.name)")
125 | }
126 | }
127 | }
128 | }
129 | }
130 |
131 | @MainActor
132 | struct LogInView: View {
133 | @Injected(\.authentication) private var authentication
134 | @Injected(\.logInSwitcher) private var logInSwitcher
135 |
136 | @State private var isAuthenticating = false
137 |
138 | var body: some View {
139 | switch isAuthenticating {
140 | case true:
141 | HStack {
142 | Text("Authenticating...")
143 | ProgressView()
144 | }
145 | case false:
146 | VStack {
147 | Text("You are logged out now")
148 | Button {
149 | Task {
150 | await authenticate()
151 | }
152 | } label: {
153 | Text("Log In")
154 | }
155 | }
156 | }
157 | }
158 |
159 | private func authenticate() async {
160 | isAuthenticating = true
161 |
162 | defer {
163 | isAuthenticating = false
164 | }
165 |
166 | do {
167 | let token = try await authentication.authenticate()
168 | await logInSwitcher.tokenChannel.send(token)
169 | } catch {
170 | // Not implemented
171 | }
172 | }
173 | }
174 |
175 | import Combine
176 |
177 | @MainActor
178 | class AppViewModel: ObservableObject {
179 | @Published private(set) var state: AppState = .loggedOut
180 |
181 | @Injected(\.logInSwitcher) private var logInSwitcher
182 |
183 | private var cancelBag = Set()
184 |
185 | init() {
186 | Task.detached { [weak self] in
187 | guard
188 | let self
189 | else {
190 | return
191 | }
192 |
193 | await observe(logInSwitcher: await logInSwitcher)
194 | }
195 | }
196 |
197 | private func observe(logInSwitcher: any LogInSwitching) async {
198 | for await token in logInSwitcher.tokenChannel {
199 | // First assign the dependencies
200 | AuthenticatedDependenciesManager.handle(token: token)
201 |
202 | // Then flip the UI switch
203 | state = switch token.isEmpty {
204 | case true: .loggedOut
205 | case false: .authenticated(token: token)
206 | }
207 |
208 | // If I would have these two steps reversed it would be broken, so slightly brittle
209 | }
210 | }
211 | }
212 |
213 | @MainActor
214 | struct AppView: View {
215 | @StateObject var viewModel = AppViewModel() // No dependencies needed
216 |
217 | var body: some View {
218 | // Dependencies are not passed
219 | switch viewModel.state {
220 | case .authenticated:
221 | AuthenticatedView()
222 | case .loggedOut:
223 | LogInView()
224 | }
225 | }
226 | }
227 |
228 | struct ContentView: View {
229 | var body: some View {
230 | AppView()
231 | }
232 | }
233 |
234 | #Preview {
235 | ContentView()
236 | }
237 |
--------------------------------------------------------------------------------
/EnvironmentDependencies/EnvironmentDependencies/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // EnvironmentDependencies
4 | //
5 | // Created by Lucas van Dongen on 15/03/2024.
6 | //
7 |
8 | import SharedDependencies
9 | import SwiftUI
10 |
11 | @MainActor
12 | struct AuthenticatedView: View {
13 | @Environment(\.logInSwitcher) private var logInSwitcher: LogInSwitching
14 |
15 | @State private var isLoggingOut = false
16 |
17 | var body: some View {
18 | VStack {
19 | // Here, we need to assume the right environment values were set the moment we got the token
20 | // If we would have multiple Views consuming the same dependencies, it would save a lot of work
21 | // When not set, we would have a crash here
22 | UserManagementView()
23 | StoriesView()
24 | Button {
25 | isLoggingOut = true
26 | } label: {
27 | Text("Log Out")
28 | }.task(id: isLoggingOut, priority: .high) {
29 | guard isLoggingOut else {
30 | return
31 | }
32 |
33 | defer {
34 | isLoggingOut = false
35 | }
36 |
37 | await logInSwitcher.loggedOut()
38 | }
39 | }
40 | }
41 | }
42 |
43 | @MainActor
44 | struct UserManagementView: View {
45 | private enum ViewState: Equatable {
46 | case loaded
47 | case updating
48 | case failed(reason: String)
49 | case updated
50 | }
51 |
52 | @State private var state: ViewState = .loaded
53 |
54 | @Environment(\.userManager) private var userManager: UserManaging
55 |
56 | var body: some View {
57 | VStack {
58 | Text("You are logged in with token \(userManager.token)")
59 | switch state {
60 | case .loaded:
61 | Button {
62 | state = .updating
63 | } label: {
64 | Text("Update User")
65 | }
66 | case .updating:
67 | HStack {
68 | Text("Updating User...")
69 | ProgressView()
70 | }
71 | case let .failed(reason):
72 | Text("Failed updating User:\n\(reason)")
73 | case .updated:
74 | Text("You have updated your user successfully")
75 | }
76 | }.task(id: state, priority: .high) {
77 | guard state == .updating else {
78 | return
79 | }
80 |
81 | do {
82 | _ = try await userManager.update(user: "")
83 | state = .updated
84 | } catch {
85 | // Ignore for now
86 | }
87 | }
88 | }
89 | }
90 |
91 | @MainActor
92 | struct StoriesView: View {
93 | private enum LoadingState {
94 | case fetching
95 | case failed(reason: String)
96 | case fetched(stories: [Story])
97 | }
98 |
99 | @State private var state: LoadingState = .fetching
100 |
101 | @Environment(StoryFetcher.self) private var storyFetcher: StoryFetcher
102 |
103 | var body: some View {
104 | switch state {
105 | case .fetching:
106 | HStack {
107 | Text("Fetching stories...")
108 | ProgressView()
109 | }
110 | .task {
111 | state = .fetching
112 | do {
113 | let stories = try await storyFetcher.fetchStories()
114 | state = .fetched(stories: stories) // You can safely mutate state properties from any thread.
115 | } catch let error {
116 | state = .failed(reason: error.localizedDescription)
117 | }
118 | }
119 | case let .failed(reason):
120 | Text("Failed fetching stories:\n\(reason)")
121 | case let .fetched(stories):
122 | List {
123 | ForEach(stories, id: \.name) { story in
124 | Text("Author: \(story.author)\nName: \(story.name)")
125 | }
126 | }
127 | }
128 | }
129 | }
130 |
131 | @MainActor
132 | struct LogInView: View {
133 | @Environment(\.authentication) private var authentication: Authenticating
134 | @Environment(\.logInSwitcher) private var logInSwitcher: LogInSwitching
135 |
136 | @State private var isAuthenticating = false
137 |
138 | var body: some View {
139 | switch isAuthenticating {
140 | case true:
141 | HStack {
142 | Text("Authenticating...")
143 | ProgressView()
144 | }
145 | case false:
146 | VStack {
147 | Text("You are logged out now")
148 | Button {
149 | Task.detached {
150 | await authenticate()
151 | }
152 | } label: {
153 | Text("Log In")
154 | }
155 | }
156 | }
157 | }
158 |
159 | private func authenticate() async {
160 | isAuthenticating = true
161 |
162 | defer {
163 | isAuthenticating = false
164 | }
165 |
166 | do {
167 | let token = try await authentication.authenticate()
168 | await logInSwitcher.tokenChannel.send(token)
169 | } catch {
170 | // Not implemented
171 | }
172 | }
173 | }
174 |
175 | @MainActor
176 | class AppViewModel: ObservableObject {
177 | @Published private(set) var state: AppState = .loggedOut
178 |
179 | init(logInSwitcher: LogInSwitching) {
180 | Task.detached { [weak self] in
181 | await self?.observe(logInSwitcher: logInSwitcher)
182 | }
183 | }
184 |
185 | private func observe(logInSwitcher: LogInSwitching) async {
186 | for await token in logInSwitcher.tokenChannel {
187 | state = switch token.isEmpty {
188 | case true: .loggedOut
189 | case false: .authenticated(token: token)
190 | }
191 | }
192 | }
193 | }
194 |
195 | @MainActor
196 | struct AppView: View {
197 | @StateObject var viewModel: AppViewModel
198 |
199 | var body: some View {
200 | switch viewModel.state {
201 | case let .authenticated(token):
202 | // AppView is now responsible for passing the right dependencies into `environment` or `environmentObject`
203 | // Failing to set the `UserManager` will result in the `PlaceholderUserManager` being used
204 | // Failing to set the `StoryFetcher` will result in a crash when it's accessed
205 | // It does work really well to keep certain dependencies only in one part of the tree
206 | AuthenticatedView()
207 | .environment(\.userManager, UserManager(token: token))
208 | .environment(StoryFetcher(token: token))
209 | case .loggedOut:
210 | LogInView()
211 | }
212 | }
213 | }
214 |
215 | @MainActor
216 | struct ContentView: View {
217 | @Environment(\.logInSwitcher) private var logInSwitcher: LogInSwitching
218 |
219 | var body: some View {
220 | AppView(viewModel: AppViewModel(logInSwitcher: logInSwitcher))
221 | }
222 | }
223 |
224 | #Preview {
225 | ContentView()
226 | }
227 |
--------------------------------------------------------------------------------
/PassedDependencies/PassedDependencies/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // PassedDependencies
4 | //
5 | // Created by Lucas van Dongen on 06/03/2024.
6 | //
7 |
8 | import SharedDependencies
9 | import SwiftUI
10 |
11 | @MainActor
12 | struct AuthenticatedView: View {
13 | let dependencies: AuthenticatedDependenciesContaining
14 |
15 | @State private var isLoggingOut = false
16 |
17 | var body: some View {
18 | VStack {
19 | // AuthenticatedView needs to know what dependencies UserManagementView and StoriesView need
20 | // A small burden now, but it will increase exponentially with the app's complexity
21 | UserManagementView(userManager: dependencies.userManager)
22 | StoriesView(storyFetcher: dependencies.storyFetcher)
23 | Button {
24 | isLoggingOut = true
25 | } label: {
26 | Text("Log Out")
27 | }.task(id: isLoggingOut, priority: .high) {
28 | guard isLoggingOut else {
29 | return
30 | }
31 |
32 | defer {
33 | isLoggingOut = false
34 | }
35 |
36 | await dependencies.logInSwitcher.loggedOut()
37 | }
38 | }
39 | }
40 | }
41 |
42 | @MainActor
43 | struct UserManagementView: View {
44 | private enum ViewState: Equatable {
45 | case loaded
46 | case updating
47 | case failed(reason: String)
48 | case updated
49 | }
50 |
51 | @State private var state: ViewState = .loaded
52 |
53 | let userManager: any UserManaging
54 |
55 | var body: some View {
56 | VStack {
57 | Text("You are logged in with token \(userManager.token)")
58 |
59 | switch state {
60 | case .loaded:
61 | Button {
62 | state = .updating
63 | } label: {
64 | Text("Update User")
65 | }
66 | case .updating:
67 | HStack {
68 | Text("Updating User...")
69 | ProgressView()
70 | }
71 | case let .failed(reason):
72 | Text("Failed updating User:\n\(reason)")
73 | case .updated:
74 | Text("You have updated your user successfully")
75 | }
76 | }.task(id: state, priority: .high) {
77 | guard state == .updating else {
78 | return
79 | }
80 |
81 | do {
82 | _ = try await userManager.update(user: "")
83 | state = .updated
84 | } catch {
85 | // Ignore for now
86 | }
87 | }
88 | }
89 | }
90 |
91 | @MainActor
92 | struct StoriesView: View {
93 | private enum LoadingState {
94 | case fetching
95 | case failed(reason: String)
96 | case fetched(stories: [Story])
97 | }
98 |
99 | @State private var state: LoadingState = .fetching
100 |
101 | let storyFetcher: any StoryFetching
102 |
103 | var body: some View {
104 | switch state {
105 | case .fetching:
106 | HStack {
107 | Text("Fetching stories...")
108 | ProgressView()
109 | }
110 | .task {
111 | state = .fetching
112 | do {
113 | let stories = try await storyFetcher.fetchStories()
114 | state = .fetched(stories: stories) // You can safely mutate state properties from any thread.
115 | } catch let error {
116 | state = .failed(reason: error.localizedDescription)
117 | }
118 | }
119 | case let .failed(reason):
120 | Text("Failed fetching stories:\n\(reason)")
121 | case let .fetched(stories):
122 | List {
123 | ForEach(stories, id: \.name) { story in
124 | Text("Author: \(story.author)\nName: \(story.name)")
125 | }
126 | }
127 | }
128 | }
129 | }
130 |
131 | @MainActor
132 | struct LogInView: View {
133 | let dependencies: LogInDependenciesContaining
134 |
135 | @State private var isAuthenticating = false
136 | @State private var tapped = 0
137 |
138 | var body: some View {
139 | Group {
140 | switch isAuthenticating {
141 | case true:
142 | VStack {
143 | HStack {
144 | Text("Authenticating...")
145 | ProgressView()
146 | }
147 | }
148 | case false:
149 | VStack {
150 | Text("You are logged out now")
151 | Button {
152 | Task {
153 | await authenticate()
154 | }
155 | } label: {
156 | Text("Log In")
157 | }
158 | }
159 | }
160 | }
161 | }
162 |
163 | private func authenticate() async {
164 | isAuthenticating = true
165 |
166 | defer {
167 | isAuthenticating = false
168 | }
169 |
170 | do {
171 | let token = try await dependencies.authentication.authenticate()
172 | await dependencies.logInSwitcher.tokenChannel.send(token)
173 | } catch {
174 | // Not implemented
175 | }
176 | }
177 | }
178 |
179 | @MainActor
180 | class AppViewModel: ObservableObject {
181 | @Published private(set) var state: AppState = .loggedOut
182 |
183 | let logInDependencies: LogInDependenciesContaining
184 |
185 | init(logInDependencies: LogInDependenciesContaining) {
186 | self.logInDependencies = logInDependencies
187 |
188 | let logInSwitcher = logInDependencies.logInSwitcher
189 |
190 | Task.detached { [weak self] in
191 | await self?.observe(logInSwitcher: logInSwitcher)
192 | }
193 | }
194 |
195 | private func observe(logInSwitcher: any LogInSwitching) async {
196 | for await token in logInSwitcher.tokenChannel {
197 | state = switch token.isEmpty {
198 | case true: .loggedOut
199 | case false: .authenticated(token: token)
200 | }
201 | }
202 | }
203 | }
204 |
205 | @MainActor
206 | struct AppView: View {
207 | @StateObject var viewModel: AppViewModel
208 |
209 | // Clearly the AppView knows a lot about logging in - too much perhaps
210 | private let logInDependencies: LogInDependenciesContaining
211 |
212 | init(
213 | dependencies: LogInDependencies
214 | ) {
215 | _viewModel = StateObject(wrappedValue: AppViewModel(logInDependencies: dependencies))
216 | self.logInDependencies = dependencies
217 | }
218 |
219 | var body: some View {
220 | switch viewModel.state {
221 | case let .authenticated(token):
222 | // Watch out: the dependencies get recreated every time the View gets re-rendered
223 | // Is this what you really want? Only when your dependencies are truly stateless!
224 | AuthenticatedView(
225 | dependencies: buildAuthenticatedDependencies(for: token)
226 | )
227 | case .loggedOut:
228 | LogInView(dependencies: logInDependencies)
229 | }
230 | }
231 |
232 | private func buildAuthenticatedDependencies(for token: String) -> AuthenticatedDependencies {
233 | AuthenticatedDependencies(
234 | token: token,
235 | logInSwitcher: logInDependencies.logInSwitcher
236 | )
237 | }
238 | }
239 |
240 | @MainActor
241 | struct ContentView: View {
242 | var body: some View {
243 | AppView(dependencies: LogInDependencies())
244 | }
245 | }
246 |
247 | #Preview {
248 | ContentView()
249 | }
250 |
--------------------------------------------------------------------------------
/FactoryDependencies/FactoryDependencies.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 60;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | A0107A1A2BA0809C00D3A35B /* FactoryDependenciesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0107A192BA0809C00D3A35B /* FactoryDependenciesApp.swift */; };
11 | A0107A1C2BA0809C00D3A35B /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0107A1B2BA0809C00D3A35B /* ContentView.swift */; };
12 | A0107A1E2BA0809E00D3A35B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A0107A1D2BA0809E00D3A35B /* Assets.xcassets */; };
13 | A0107A212BA0809E00D3A35B /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A0107A202BA0809E00D3A35B /* Preview Assets.xcassets */; };
14 | A0107A2B2BA080D600D3A35B /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0107A2A2BA080D600D3A35B /* Container.swift */; };
15 | A0107A2F2BA080FE00D3A35B /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0107A2E2BA080FE00D3A35B /* Model.swift */; };
16 | A0107A392BA08C4000D3A35B /* SharedDependencies in Frameworks */ = {isa = PBXBuildFile; productRef = A0107A382BA08C4000D3A35B /* SharedDependencies */; };
17 | CAFD9B712BB2371F00B35F4A /* Factory in Frameworks */ = {isa = PBXBuildFile; productRef = CAFD9B702BB2371F00B35F4A /* Factory */; };
18 | /* End PBXBuildFile section */
19 |
20 | /* Begin PBXFileReference section */
21 | A0107A162BA0809C00D3A35B /* FactoryDependencies.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FactoryDependencies.app; sourceTree = BUILT_PRODUCTS_DIR; };
22 | A0107A192BA0809C00D3A35B /* FactoryDependenciesApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FactoryDependenciesApp.swift; sourceTree = ""; };
23 | A0107A1B2BA0809C00D3A35B /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
24 | A0107A1D2BA0809E00D3A35B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
25 | A0107A202BA0809E00D3A35B /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
26 | A0107A222BA0809E00D3A35B /* FactoryDependencies.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = FactoryDependencies.entitlements; sourceTree = ""; };
27 | A0107A2A2BA080D600D3A35B /* Container.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = ""; };
28 | A0107A2E2BA080FE00D3A35B /* Model.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Model.swift; sourceTree = ""; };
29 | A0107A312BA0819800D3A35B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; };
30 | /* End PBXFileReference section */
31 |
32 | /* Begin PBXFrameworksBuildPhase section */
33 | A0107A132BA0809C00D3A35B /* Frameworks */ = {
34 | isa = PBXFrameworksBuildPhase;
35 | buildActionMask = 2147483647;
36 | files = (
37 | A0107A392BA08C4000D3A35B /* SharedDependencies in Frameworks */,
38 | CAFD9B712BB2371F00B35F4A /* Factory in Frameworks */,
39 | );
40 | runOnlyForDeploymentPostprocessing = 0;
41 | };
42 | /* End PBXFrameworksBuildPhase section */
43 |
44 | /* Begin PBXGroup section */
45 | A0107A0D2BA0809C00D3A35B = {
46 | isa = PBXGroup;
47 | children = (
48 | A0107A182BA0809C00D3A35B /* FactoryDependencies */,
49 | A0107A172BA0809C00D3A35B /* Products */,
50 | A0107A332BA0846D00D3A35B /* Frameworks */,
51 | );
52 | sourceTree = "";
53 | };
54 | A0107A172BA0809C00D3A35B /* Products */ = {
55 | isa = PBXGroup;
56 | children = (
57 | A0107A162BA0809C00D3A35B /* FactoryDependencies.app */,
58 | );
59 | name = Products;
60 | sourceTree = "";
61 | };
62 | A0107A182BA0809C00D3A35B /* FactoryDependencies */ = {
63 | isa = PBXGroup;
64 | children = (
65 | A0107A312BA0819800D3A35B /* Info.plist */,
66 | A0107A2A2BA080D600D3A35B /* Container.swift */,
67 | A0107A192BA0809C00D3A35B /* FactoryDependenciesApp.swift */,
68 | A0107A1B2BA0809C00D3A35B /* ContentView.swift */,
69 | A0107A2E2BA080FE00D3A35B /* Model.swift */,
70 | A0107A1D2BA0809E00D3A35B /* Assets.xcassets */,
71 | A0107A222BA0809E00D3A35B /* FactoryDependencies.entitlements */,
72 | A0107A1F2BA0809E00D3A35B /* Preview Content */,
73 | );
74 | path = FactoryDependencies;
75 | sourceTree = "";
76 | };
77 | A0107A1F2BA0809E00D3A35B /* Preview Content */ = {
78 | isa = PBXGroup;
79 | children = (
80 | A0107A202BA0809E00D3A35B /* Preview Assets.xcassets */,
81 | );
82 | path = "Preview Content";
83 | sourceTree = "";
84 | };
85 | A0107A332BA0846D00D3A35B /* Frameworks */ = {
86 | isa = PBXGroup;
87 | children = (
88 | );
89 | name = Frameworks;
90 | sourceTree = "";
91 | };
92 | /* End PBXGroup section */
93 |
94 | /* Begin PBXNativeTarget section */
95 | A0107A152BA0809C00D3A35B /* FactoryDependencies */ = {
96 | isa = PBXNativeTarget;
97 | buildConfigurationList = A0107A252BA0809E00D3A35B /* Build configuration list for PBXNativeTarget "FactoryDependencies" */;
98 | buildPhases = (
99 | A0107A122BA0809C00D3A35B /* Sources */,
100 | A0107A132BA0809C00D3A35B /* Frameworks */,
101 | A0107A142BA0809C00D3A35B /* Resources */,
102 | );
103 | buildRules = (
104 | );
105 | dependencies = (
106 | );
107 | name = FactoryDependencies;
108 | packageProductDependencies = (
109 | A0107A382BA08C4000D3A35B /* SharedDependencies */,
110 | CAFD9B702BB2371F00B35F4A /* Factory */,
111 | );
112 | productName = FactoryDependencies;
113 | productReference = A0107A162BA0809C00D3A35B /* FactoryDependencies.app */;
114 | productType = "com.apple.product-type.application";
115 | };
116 | /* End PBXNativeTarget section */
117 |
118 | /* Begin PBXProject section */
119 | A0107A0E2BA0809C00D3A35B /* Project object */ = {
120 | isa = PBXProject;
121 | attributes = {
122 | BuildIndependentTargetsInParallel = 1;
123 | LastSwiftUpdateCheck = 1520;
124 | LastUpgradeCheck = 1530;
125 | TargetAttributes = {
126 | A0107A152BA0809C00D3A35B = {
127 | CreatedOnToolsVersion = 15.2;
128 | };
129 | };
130 | };
131 | buildConfigurationList = A0107A112BA0809C00D3A35B /* Build configuration list for PBXProject "FactoryDependencies" */;
132 | compatibilityVersion = "Xcode 14.0";
133 | developmentRegion = en;
134 | hasScannedForEncodings = 0;
135 | knownRegions = (
136 | en,
137 | Base,
138 | );
139 | mainGroup = A0107A0D2BA0809C00D3A35B;
140 | packageReferences = (
141 | A0107A372BA08C4000D3A35B /* XCLocalSwiftPackageReference "../SharedDependencies" */,
142 | CAFD9AC02BB22F6400B35F4A /* XCRemoteSwiftPackageReference "Factory" */,
143 | );
144 | productRefGroup = A0107A172BA0809C00D3A35B /* Products */;
145 | projectDirPath = "";
146 | projectRoot = "";
147 | targets = (
148 | A0107A152BA0809C00D3A35B /* FactoryDependencies */,
149 | );
150 | };
151 | /* End PBXProject section */
152 |
153 | /* Begin PBXResourcesBuildPhase section */
154 | A0107A142BA0809C00D3A35B /* Resources */ = {
155 | isa = PBXResourcesBuildPhase;
156 | buildActionMask = 2147483647;
157 | files = (
158 | A0107A212BA0809E00D3A35B /* Preview Assets.xcassets in Resources */,
159 | A0107A1E2BA0809E00D3A35B /* Assets.xcassets in Resources */,
160 | );
161 | runOnlyForDeploymentPostprocessing = 0;
162 | };
163 | /* End PBXResourcesBuildPhase section */
164 |
165 | /* Begin PBXSourcesBuildPhase section */
166 | A0107A122BA0809C00D3A35B /* Sources */ = {
167 | isa = PBXSourcesBuildPhase;
168 | buildActionMask = 2147483647;
169 | files = (
170 | A0107A1C2BA0809C00D3A35B /* ContentView.swift in Sources */,
171 | A0107A2B2BA080D600D3A35B /* Container.swift in Sources */,
172 | A0107A1A2BA0809C00D3A35B /* FactoryDependenciesApp.swift in Sources */,
173 | A0107A2F2BA080FE00D3A35B /* Model.swift in Sources */,
174 | );
175 | runOnlyForDeploymentPostprocessing = 0;
176 | };
177 | /* End PBXSourcesBuildPhase section */
178 |
179 | /* Begin XCBuildConfiguration section */
180 | A0107A232BA0809E00D3A35B /* Debug */ = {
181 | isa = XCBuildConfiguration;
182 | buildSettings = {
183 | ALWAYS_SEARCH_USER_PATHS = NO;
184 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
185 | CLANG_ANALYZER_NONNULL = YES;
186 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
187 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
188 | CLANG_ENABLE_MODULES = YES;
189 | CLANG_ENABLE_OBJC_ARC = YES;
190 | CLANG_ENABLE_OBJC_WEAK = YES;
191 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
192 | CLANG_WARN_BOOL_CONVERSION = YES;
193 | CLANG_WARN_COMMA = YES;
194 | CLANG_WARN_CONSTANT_CONVERSION = YES;
195 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
196 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
197 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
198 | CLANG_WARN_EMPTY_BODY = YES;
199 | CLANG_WARN_ENUM_CONVERSION = YES;
200 | CLANG_WARN_INFINITE_RECURSION = YES;
201 | CLANG_WARN_INT_CONVERSION = YES;
202 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
203 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
204 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
205 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
206 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
207 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
208 | CLANG_WARN_STRICT_PROTOTYPES = YES;
209 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
210 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
211 | CLANG_WARN_UNREACHABLE_CODE = YES;
212 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
213 | COPY_PHASE_STRIP = NO;
214 | DEAD_CODE_STRIPPING = YES;
215 | DEBUG_INFORMATION_FORMAT = dwarf;
216 | ENABLE_STRICT_OBJC_MSGSEND = YES;
217 | ENABLE_TESTABILITY = YES;
218 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
219 | GCC_C_LANGUAGE_STANDARD = gnu17;
220 | GCC_DYNAMIC_NO_PIC = NO;
221 | GCC_NO_COMMON_BLOCKS = YES;
222 | GCC_OPTIMIZATION_LEVEL = 0;
223 | GCC_PREPROCESSOR_DEFINITIONS = (
224 | "DEBUG=1",
225 | "$(inherited)",
226 | );
227 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
228 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
229 | GCC_WARN_UNDECLARED_SELECTOR = YES;
230 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
231 | GCC_WARN_UNUSED_FUNCTION = YES;
232 | GCC_WARN_UNUSED_VARIABLE = YES;
233 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
234 | MACOSX_DEPLOYMENT_TARGET = 14.2;
235 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
236 | MTL_FAST_MATH = YES;
237 | ONLY_ACTIVE_ARCH = YES;
238 | SDKROOT = macosx;
239 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
240 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
241 | SWIFT_STRICT_CONCURRENCY = complete;
242 | };
243 | name = Debug;
244 | };
245 | A0107A242BA0809E00D3A35B /* Release */ = {
246 | isa = XCBuildConfiguration;
247 | buildSettings = {
248 | ALWAYS_SEARCH_USER_PATHS = NO;
249 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
250 | CLANG_ANALYZER_NONNULL = YES;
251 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
252 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
253 | CLANG_ENABLE_MODULES = YES;
254 | CLANG_ENABLE_OBJC_ARC = YES;
255 | CLANG_ENABLE_OBJC_WEAK = YES;
256 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
257 | CLANG_WARN_BOOL_CONVERSION = YES;
258 | CLANG_WARN_COMMA = YES;
259 | CLANG_WARN_CONSTANT_CONVERSION = YES;
260 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
261 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
262 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
263 | CLANG_WARN_EMPTY_BODY = YES;
264 | CLANG_WARN_ENUM_CONVERSION = YES;
265 | CLANG_WARN_INFINITE_RECURSION = YES;
266 | CLANG_WARN_INT_CONVERSION = YES;
267 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
268 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
269 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
270 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
271 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
272 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
273 | CLANG_WARN_STRICT_PROTOTYPES = YES;
274 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
275 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
276 | CLANG_WARN_UNREACHABLE_CODE = YES;
277 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
278 | COPY_PHASE_STRIP = NO;
279 | DEAD_CODE_STRIPPING = YES;
280 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
281 | ENABLE_NS_ASSERTIONS = NO;
282 | ENABLE_STRICT_OBJC_MSGSEND = YES;
283 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
284 | GCC_C_LANGUAGE_STANDARD = gnu17;
285 | GCC_NO_COMMON_BLOCKS = YES;
286 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
287 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
288 | GCC_WARN_UNDECLARED_SELECTOR = YES;
289 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
290 | GCC_WARN_UNUSED_FUNCTION = YES;
291 | GCC_WARN_UNUSED_VARIABLE = YES;
292 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
293 | MACOSX_DEPLOYMENT_TARGET = 14.2;
294 | MTL_ENABLE_DEBUG_INFO = NO;
295 | MTL_FAST_MATH = YES;
296 | SDKROOT = macosx;
297 | SWIFT_COMPILATION_MODE = wholemodule;
298 | SWIFT_STRICT_CONCURRENCY = complete;
299 | };
300 | name = Release;
301 | };
302 | A0107A262BA0809E00D3A35B /* Debug */ = {
303 | isa = XCBuildConfiguration;
304 | buildSettings = {
305 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
306 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
307 | CODE_SIGN_ENTITLEMENTS = FactoryDependencies/FactoryDependencies.entitlements;
308 | CODE_SIGN_STYLE = Automatic;
309 | COMBINE_HIDPI_IMAGES = YES;
310 | CURRENT_PROJECT_VERSION = 1;
311 | DEAD_CODE_STRIPPING = YES;
312 | DEVELOPMENT_ASSET_PATHS = "\"FactoryDependencies/Preview Content\"";
313 | DEVELOPMENT_TEAM = 79L7M968L6;
314 | ENABLE_HARDENED_RUNTIME = YES;
315 | ENABLE_PREVIEWS = YES;
316 | GENERATE_INFOPLIST_FILE = YES;
317 | INFOPLIST_FILE = FactoryDependencies/Info.plist;
318 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
319 | LD_RUNPATH_SEARCH_PATHS = (
320 | "$(inherited)",
321 | "@executable_path/../Frameworks",
322 | );
323 | MACOSX_DEPLOYMENT_TARGET = 14.0;
324 | MARKETING_VERSION = 1.0;
325 | PRODUCT_BUNDLE_IDENTIFIER = dev.lucasvandongen.FactoryDependencies;
326 | PRODUCT_NAME = "$(TARGET_NAME)";
327 | SWIFT_EMIT_LOC_STRINGS = YES;
328 | SWIFT_VERSION = 5.0;
329 | };
330 | name = Debug;
331 | };
332 | A0107A272BA0809E00D3A35B /* Release */ = {
333 | isa = XCBuildConfiguration;
334 | buildSettings = {
335 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
336 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
337 | CODE_SIGN_ENTITLEMENTS = FactoryDependencies/FactoryDependencies.entitlements;
338 | CODE_SIGN_STYLE = Automatic;
339 | COMBINE_HIDPI_IMAGES = YES;
340 | CURRENT_PROJECT_VERSION = 1;
341 | DEAD_CODE_STRIPPING = YES;
342 | DEVELOPMENT_ASSET_PATHS = "\"FactoryDependencies/Preview Content\"";
343 | DEVELOPMENT_TEAM = 79L7M968L6;
344 | ENABLE_HARDENED_RUNTIME = YES;
345 | ENABLE_PREVIEWS = YES;
346 | GENERATE_INFOPLIST_FILE = YES;
347 | INFOPLIST_FILE = FactoryDependencies/Info.plist;
348 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
349 | LD_RUNPATH_SEARCH_PATHS = (
350 | "$(inherited)",
351 | "@executable_path/../Frameworks",
352 | );
353 | MACOSX_DEPLOYMENT_TARGET = 14.0;
354 | MARKETING_VERSION = 1.0;
355 | PRODUCT_BUNDLE_IDENTIFIER = dev.lucasvandongen.FactoryDependencies;
356 | PRODUCT_NAME = "$(TARGET_NAME)";
357 | SWIFT_EMIT_LOC_STRINGS = YES;
358 | SWIFT_VERSION = 5.0;
359 | };
360 | name = Release;
361 | };
362 | /* End XCBuildConfiguration section */
363 |
364 | /* Begin XCConfigurationList section */
365 | A0107A112BA0809C00D3A35B /* Build configuration list for PBXProject "FactoryDependencies" */ = {
366 | isa = XCConfigurationList;
367 | buildConfigurations = (
368 | A0107A232BA0809E00D3A35B /* Debug */,
369 | A0107A242BA0809E00D3A35B /* Release */,
370 | );
371 | defaultConfigurationIsVisible = 0;
372 | defaultConfigurationName = Release;
373 | };
374 | A0107A252BA0809E00D3A35B /* Build configuration list for PBXNativeTarget "FactoryDependencies" */ = {
375 | isa = XCConfigurationList;
376 | buildConfigurations = (
377 | A0107A262BA0809E00D3A35B /* Debug */,
378 | A0107A272BA0809E00D3A35B /* Release */,
379 | );
380 | defaultConfigurationIsVisible = 0;
381 | defaultConfigurationName = Release;
382 | };
383 | /* End XCConfigurationList section */
384 |
385 | /* Begin XCLocalSwiftPackageReference section */
386 | A0107A372BA08C4000D3A35B /* XCLocalSwiftPackageReference "../SharedDependencies" */ = {
387 | isa = XCLocalSwiftPackageReference;
388 | relativePath = ../SharedDependencies;
389 | };
390 | /* End XCLocalSwiftPackageReference section */
391 |
392 | /* Begin XCRemoteSwiftPackageReference section */
393 | CAFD9AC02BB22F6400B35F4A /* XCRemoteSwiftPackageReference "Factory" */ = {
394 | isa = XCRemoteSwiftPackageReference;
395 | repositoryURL = "http://github.com/hmlongco/Factory";
396 | requirement = {
397 | kind = upToNextMajorVersion;
398 | minimumVersion = 2.3.2;
399 | };
400 | };
401 | /* End XCRemoteSwiftPackageReference section */
402 |
403 | /* Begin XCSwiftPackageProductDependency section */
404 | A0107A382BA08C4000D3A35B /* SharedDependencies */ = {
405 | isa = XCSwiftPackageProductDependency;
406 | productName = SharedDependencies;
407 | };
408 | CAFD9B702BB2371F00B35F4A /* Factory */ = {
409 | isa = XCSwiftPackageProductDependency;
410 | package = CAFD9AC02BB22F6400B35F4A /* XCRemoteSwiftPackageReference "Factory" */;
411 | productName = Factory;
412 | };
413 | /* End XCSwiftPackageProductDependency section */
414 | };
415 | rootObject = A0107A0E2BA0809C00D3A35B /* Project object */;
416 | }
417 |
--------------------------------------------------------------------------------
/SwiftDependencies/SwiftDependencies.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 56;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | CAFD9B3F2BB234B700B35F4A /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFD9B3E2BB234B700B35F4A /* App.swift */; };
11 | CAFD9B412BB234B700B35F4A /* AppFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFD9B402BB234B700B35F4A /* AppFeature.swift */; };
12 | CAFD9B432BB234B800B35F4A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CAFD9B422BB234B800B35F4A /* Assets.xcassets */; };
13 | CAFD9B462BB234B800B35F4A /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CAFD9B452BB234B800B35F4A /* Preview Assets.xcassets */; };
14 | CAFD9B6A2BB234C600B35F4A /* SharedDependencies in Frameworks */ = {isa = PBXBuildFile; productRef = CAFD9B692BB234C600B35F4A /* SharedDependencies */; };
15 | CAFD9B6D2BB234FD00B35F4A /* Dependencies in Frameworks */ = {isa = PBXBuildFile; productRef = CAFD9B6C2BB234FD00B35F4A /* Dependencies */; };
16 | CAFD9B6F2BB2367800B35F4A /* LoggedOutFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFD9B6E2BB2367800B35F4A /* LoggedOutFeature.swift */; };
17 | CAFD9B732BB2375800B35F4A /* Dependencies.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFD9B722BB2375800B35F4A /* Dependencies.swift */; };
18 | CAFD9B752BB23AD800B35F4A /* AuthenticatedFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFD9B742BB23AD800B35F4A /* AuthenticatedFeature.swift */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXFileReference section */
22 | CAFD9B3B2BB234B700B35F4A /* SwiftDependencies.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftDependencies.app; sourceTree = BUILT_PRODUCTS_DIR; };
23 | CAFD9B3E2BB234B700B35F4A /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = ""; };
24 | CAFD9B402BB234B700B35F4A /* AppFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppFeature.swift; sourceTree = ""; };
25 | CAFD9B422BB234B800B35F4A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
26 | CAFD9B452BB234B800B35F4A /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
27 | CAFD9B6E2BB2367800B35F4A /* LoggedOutFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggedOutFeature.swift; sourceTree = ""; };
28 | CAFD9B722BB2375800B35F4A /* Dependencies.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dependencies.swift; sourceTree = ""; };
29 | CAFD9B742BB23AD800B35F4A /* AuthenticatedFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticatedFeature.swift; sourceTree = ""; };
30 | /* End PBXFileReference section */
31 |
32 | /* Begin PBXFrameworksBuildPhase section */
33 | CAFD9B382BB234B700B35F4A /* Frameworks */ = {
34 | isa = PBXFrameworksBuildPhase;
35 | buildActionMask = 2147483647;
36 | files = (
37 | CAFD9B6A2BB234C600B35F4A /* SharedDependencies in Frameworks */,
38 | CAFD9B6D2BB234FD00B35F4A /* Dependencies in Frameworks */,
39 | );
40 | runOnlyForDeploymentPostprocessing = 0;
41 | };
42 | /* End PBXFrameworksBuildPhase section */
43 |
44 | /* Begin PBXGroup section */
45 | CAFD9B322BB234B700B35F4A = {
46 | isa = PBXGroup;
47 | children = (
48 | CAFD9B3D2BB234B700B35F4A /* SwiftDependencies */,
49 | CAFD9B3C2BB234B700B35F4A /* Products */,
50 | CAFD9B682BB234C600B35F4A /* Frameworks */,
51 | );
52 | sourceTree = "";
53 | };
54 | CAFD9B3C2BB234B700B35F4A /* Products */ = {
55 | isa = PBXGroup;
56 | children = (
57 | CAFD9B3B2BB234B700B35F4A /* SwiftDependencies.app */,
58 | );
59 | name = Products;
60 | sourceTree = "";
61 | };
62 | CAFD9B3D2BB234B700B35F4A /* SwiftDependencies */ = {
63 | isa = PBXGroup;
64 | children = (
65 | CAFD9B3E2BB234B700B35F4A /* App.swift */,
66 | CAFD9B402BB234B700B35F4A /* AppFeature.swift */,
67 | CAFD9B742BB23AD800B35F4A /* AuthenticatedFeature.swift */,
68 | CAFD9B722BB2375800B35F4A /* Dependencies.swift */,
69 | CAFD9B6E2BB2367800B35F4A /* LoggedOutFeature.swift */,
70 | CAFD9B422BB234B800B35F4A /* Assets.xcassets */,
71 | CAFD9B442BB234B800B35F4A /* Preview Content */,
72 | );
73 | path = SwiftDependencies;
74 | sourceTree = "";
75 | };
76 | CAFD9B442BB234B800B35F4A /* Preview Content */ = {
77 | isa = PBXGroup;
78 | children = (
79 | CAFD9B452BB234B800B35F4A /* Preview Assets.xcassets */,
80 | );
81 | path = "Preview Content";
82 | sourceTree = "";
83 | };
84 | CAFD9B682BB234C600B35F4A /* Frameworks */ = {
85 | isa = PBXGroup;
86 | children = (
87 | );
88 | name = Frameworks;
89 | sourceTree = "";
90 | };
91 | /* End PBXGroup section */
92 |
93 | /* Begin PBXNativeTarget section */
94 | CAFD9B3A2BB234B700B35F4A /* SwiftDependencies */ = {
95 | isa = PBXNativeTarget;
96 | buildConfigurationList = CAFD9B5F2BB234B900B35F4A /* Build configuration list for PBXNativeTarget "SwiftDependencies" */;
97 | buildPhases = (
98 | CAFD9B372BB234B700B35F4A /* Sources */,
99 | CAFD9B382BB234B700B35F4A /* Frameworks */,
100 | CAFD9B392BB234B700B35F4A /* Resources */,
101 | );
102 | buildRules = (
103 | );
104 | dependencies = (
105 | );
106 | name = SwiftDependencies;
107 | packageProductDependencies = (
108 | CAFD9B692BB234C600B35F4A /* SharedDependencies */,
109 | CAFD9B6C2BB234FD00B35F4A /* Dependencies */,
110 | );
111 | productName = SwiftDependencies;
112 | productReference = CAFD9B3B2BB234B700B35F4A /* SwiftDependencies.app */;
113 | productType = "com.apple.product-type.application";
114 | };
115 | /* End PBXNativeTarget section */
116 |
117 | /* Begin PBXProject section */
118 | CAFD9B332BB234B700B35F4A /* Project object */ = {
119 | isa = PBXProject;
120 | attributes = {
121 | BuildIndependentTargetsInParallel = 1;
122 | LastSwiftUpdateCheck = 1530;
123 | LastUpgradeCheck = 1530;
124 | TargetAttributes = {
125 | CAFD9B3A2BB234B700B35F4A = {
126 | CreatedOnToolsVersion = 15.3;
127 | };
128 | };
129 | };
130 | buildConfigurationList = CAFD9B362BB234B700B35F4A /* Build configuration list for PBXProject "SwiftDependencies" */;
131 | compatibilityVersion = "Xcode 14.0";
132 | developmentRegion = en;
133 | hasScannedForEncodings = 0;
134 | knownRegions = (
135 | en,
136 | Base,
137 | );
138 | mainGroup = CAFD9B322BB234B700B35F4A;
139 | packageReferences = (
140 | CAFD9B6B2BB234FD00B35F4A /* XCRemoteSwiftPackageReference "swift-dependencies" */,
141 | );
142 | productRefGroup = CAFD9B3C2BB234B700B35F4A /* Products */;
143 | projectDirPath = "";
144 | projectRoot = "";
145 | targets = (
146 | CAFD9B3A2BB234B700B35F4A /* SwiftDependencies */,
147 | );
148 | };
149 | /* End PBXProject section */
150 |
151 | /* Begin PBXResourcesBuildPhase section */
152 | CAFD9B392BB234B700B35F4A /* Resources */ = {
153 | isa = PBXResourcesBuildPhase;
154 | buildActionMask = 2147483647;
155 | files = (
156 | CAFD9B462BB234B800B35F4A /* Preview Assets.xcassets in Resources */,
157 | CAFD9B432BB234B800B35F4A /* Assets.xcassets in Resources */,
158 | );
159 | runOnlyForDeploymentPostprocessing = 0;
160 | };
161 | /* End PBXResourcesBuildPhase section */
162 |
163 | /* Begin PBXSourcesBuildPhase section */
164 | CAFD9B372BB234B700B35F4A /* Sources */ = {
165 | isa = PBXSourcesBuildPhase;
166 | buildActionMask = 2147483647;
167 | files = (
168 | CAFD9B732BB2375800B35F4A /* Dependencies.swift in Sources */,
169 | CAFD9B412BB234B700B35F4A /* AppFeature.swift in Sources */,
170 | CAFD9B752BB23AD800B35F4A /* AuthenticatedFeature.swift in Sources */,
171 | CAFD9B3F2BB234B700B35F4A /* App.swift in Sources */,
172 | CAFD9B6F2BB2367800B35F4A /* LoggedOutFeature.swift in Sources */,
173 | );
174 | runOnlyForDeploymentPostprocessing = 0;
175 | };
176 | /* End PBXSourcesBuildPhase section */
177 |
178 | /* Begin XCBuildConfiguration section */
179 | CAFD9B5D2BB234B900B35F4A /* Debug */ = {
180 | isa = XCBuildConfiguration;
181 | buildSettings = {
182 | ALWAYS_SEARCH_USER_PATHS = NO;
183 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
184 | CLANG_ANALYZER_NONNULL = YES;
185 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
186 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
187 | CLANG_ENABLE_MODULES = YES;
188 | CLANG_ENABLE_OBJC_ARC = YES;
189 | CLANG_ENABLE_OBJC_WEAK = YES;
190 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
191 | CLANG_WARN_BOOL_CONVERSION = YES;
192 | CLANG_WARN_COMMA = YES;
193 | CLANG_WARN_CONSTANT_CONVERSION = YES;
194 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
195 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
196 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
197 | CLANG_WARN_EMPTY_BODY = YES;
198 | CLANG_WARN_ENUM_CONVERSION = YES;
199 | CLANG_WARN_INFINITE_RECURSION = YES;
200 | CLANG_WARN_INT_CONVERSION = YES;
201 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
202 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
203 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
204 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
205 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
206 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
207 | CLANG_WARN_STRICT_PROTOTYPES = YES;
208 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
209 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
210 | CLANG_WARN_UNREACHABLE_CODE = YES;
211 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
212 | COPY_PHASE_STRIP = NO;
213 | DEBUG_INFORMATION_FORMAT = dwarf;
214 | ENABLE_STRICT_OBJC_MSGSEND = YES;
215 | ENABLE_TESTABILITY = YES;
216 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
217 | GCC_C_LANGUAGE_STANDARD = gnu17;
218 | GCC_DYNAMIC_NO_PIC = NO;
219 | GCC_NO_COMMON_BLOCKS = YES;
220 | GCC_OPTIMIZATION_LEVEL = 0;
221 | GCC_PREPROCESSOR_DEFINITIONS = (
222 | "DEBUG=1",
223 | "$(inherited)",
224 | );
225 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
226 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
227 | GCC_WARN_UNDECLARED_SELECTOR = YES;
228 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
229 | GCC_WARN_UNUSED_FUNCTION = YES;
230 | GCC_WARN_UNUSED_VARIABLE = YES;
231 | IPHONEOS_DEPLOYMENT_TARGET = 17.4;
232 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
233 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
234 | MTL_FAST_MATH = YES;
235 | ONLY_ACTIVE_ARCH = YES;
236 | SDKROOT = iphoneos;
237 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
238 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
239 | SWIFT_STRICT_CONCURRENCY = complete;
240 | };
241 | name = Debug;
242 | };
243 | CAFD9B5E2BB234B900B35F4A /* Release */ = {
244 | isa = XCBuildConfiguration;
245 | buildSettings = {
246 | ALWAYS_SEARCH_USER_PATHS = NO;
247 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
248 | CLANG_ANALYZER_NONNULL = YES;
249 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
250 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
251 | CLANG_ENABLE_MODULES = YES;
252 | CLANG_ENABLE_OBJC_ARC = YES;
253 | CLANG_ENABLE_OBJC_WEAK = YES;
254 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
255 | CLANG_WARN_BOOL_CONVERSION = YES;
256 | CLANG_WARN_COMMA = YES;
257 | CLANG_WARN_CONSTANT_CONVERSION = YES;
258 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
259 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
260 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
261 | CLANG_WARN_EMPTY_BODY = YES;
262 | CLANG_WARN_ENUM_CONVERSION = YES;
263 | CLANG_WARN_INFINITE_RECURSION = YES;
264 | CLANG_WARN_INT_CONVERSION = YES;
265 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
266 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
267 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
268 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
269 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
270 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
271 | CLANG_WARN_STRICT_PROTOTYPES = YES;
272 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
273 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
274 | CLANG_WARN_UNREACHABLE_CODE = YES;
275 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
276 | COPY_PHASE_STRIP = NO;
277 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
278 | ENABLE_NS_ASSERTIONS = NO;
279 | ENABLE_STRICT_OBJC_MSGSEND = YES;
280 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
281 | GCC_C_LANGUAGE_STANDARD = gnu17;
282 | GCC_NO_COMMON_BLOCKS = YES;
283 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
284 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
285 | GCC_WARN_UNDECLARED_SELECTOR = YES;
286 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
287 | GCC_WARN_UNUSED_FUNCTION = YES;
288 | GCC_WARN_UNUSED_VARIABLE = YES;
289 | IPHONEOS_DEPLOYMENT_TARGET = 17.4;
290 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
291 | MTL_ENABLE_DEBUG_INFO = NO;
292 | MTL_FAST_MATH = YES;
293 | SDKROOT = iphoneos;
294 | SWIFT_COMPILATION_MODE = wholemodule;
295 | SWIFT_STRICT_CONCURRENCY = complete;
296 | VALIDATE_PRODUCT = YES;
297 | };
298 | name = Release;
299 | };
300 | CAFD9B602BB234B900B35F4A /* Debug */ = {
301 | isa = XCBuildConfiguration;
302 | buildSettings = {
303 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
304 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
305 | CODE_SIGN_STYLE = Automatic;
306 | CURRENT_PROJECT_VERSION = 1;
307 | DEVELOPMENT_ASSET_PATHS = "\"SwiftDependencies/Preview Content\"";
308 | ENABLE_PREVIEWS = YES;
309 | GENERATE_INFOPLIST_FILE = YES;
310 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
311 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
312 | INFOPLIST_KEY_UILaunchScreen_Generation = YES;
313 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
314 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
315 | IPHONEOS_DEPLOYMENT_TARGET = 17.2;
316 | LD_RUNPATH_SEARCH_PATHS = (
317 | "$(inherited)",
318 | "@executable_path/Frameworks",
319 | );
320 | MACOSX_DEPLOYMENT_TARGET = 14.2;
321 | MARKETING_VERSION = 1.0;
322 | PRODUCT_BUNDLE_IDENTIFIER = co.pointfree.SwiftDependencies;
323 | PRODUCT_NAME = "$(TARGET_NAME)";
324 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
325 | SUPPORTS_MACCATALYST = NO;
326 | SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
327 | SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
328 | SWIFT_EMIT_LOC_STRINGS = YES;
329 | SWIFT_VERSION = 5.0;
330 | TARGETED_DEVICE_FAMILY = "1,2";
331 | };
332 | name = Debug;
333 | };
334 | CAFD9B612BB234B900B35F4A /* Release */ = {
335 | isa = XCBuildConfiguration;
336 | buildSettings = {
337 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
338 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
339 | CODE_SIGN_STYLE = Automatic;
340 | CURRENT_PROJECT_VERSION = 1;
341 | DEVELOPMENT_ASSET_PATHS = "\"SwiftDependencies/Preview Content\"";
342 | ENABLE_PREVIEWS = YES;
343 | GENERATE_INFOPLIST_FILE = YES;
344 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
345 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
346 | INFOPLIST_KEY_UILaunchScreen_Generation = YES;
347 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
348 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
349 | IPHONEOS_DEPLOYMENT_TARGET = 17.2;
350 | LD_RUNPATH_SEARCH_PATHS = (
351 | "$(inherited)",
352 | "@executable_path/Frameworks",
353 | );
354 | MACOSX_DEPLOYMENT_TARGET = 14.2;
355 | MARKETING_VERSION = 1.0;
356 | PRODUCT_BUNDLE_IDENTIFIER = co.pointfree.SwiftDependencies;
357 | PRODUCT_NAME = "$(TARGET_NAME)";
358 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
359 | SUPPORTS_MACCATALYST = NO;
360 | SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
361 | SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
362 | SWIFT_EMIT_LOC_STRINGS = YES;
363 | SWIFT_VERSION = 5.0;
364 | TARGETED_DEVICE_FAMILY = "1,2";
365 | };
366 | name = Release;
367 | };
368 | /* End XCBuildConfiguration section */
369 |
370 | /* Begin XCConfigurationList section */
371 | CAFD9B362BB234B700B35F4A /* Build configuration list for PBXProject "SwiftDependencies" */ = {
372 | isa = XCConfigurationList;
373 | buildConfigurations = (
374 | CAFD9B5D2BB234B900B35F4A /* Debug */,
375 | CAFD9B5E2BB234B900B35F4A /* Release */,
376 | );
377 | defaultConfigurationIsVisible = 0;
378 | defaultConfigurationName = Release;
379 | };
380 | CAFD9B5F2BB234B900B35F4A /* Build configuration list for PBXNativeTarget "SwiftDependencies" */ = {
381 | isa = XCConfigurationList;
382 | buildConfigurations = (
383 | CAFD9B602BB234B900B35F4A /* Debug */,
384 | CAFD9B612BB234B900B35F4A /* Release */,
385 | );
386 | defaultConfigurationIsVisible = 0;
387 | defaultConfigurationName = Release;
388 | };
389 | /* End XCConfigurationList section */
390 |
391 | /* Begin XCRemoteSwiftPackageReference section */
392 | CAFD9B6B2BB234FD00B35F4A /* XCRemoteSwiftPackageReference "swift-dependencies" */ = {
393 | isa = XCRemoteSwiftPackageReference;
394 | repositoryURL = "https://github.com/pointfreeco/swift-dependencies.git";
395 | requirement = {
396 | kind = upToNextMajorVersion;
397 | minimumVersion = 1.2.2;
398 | };
399 | };
400 | /* End XCRemoteSwiftPackageReference section */
401 |
402 | /* Begin XCSwiftPackageProductDependency section */
403 | CAFD9B692BB234C600B35F4A /* SharedDependencies */ = {
404 | isa = XCSwiftPackageProductDependency;
405 | productName = SharedDependencies;
406 | };
407 | CAFD9B6C2BB234FD00B35F4A /* Dependencies */ = {
408 | isa = XCSwiftPackageProductDependency;
409 | package = CAFD9B6B2BB234FD00B35F4A /* XCRemoteSwiftPackageReference "swift-dependencies" */;
410 | productName = Dependencies;
411 | };
412 | /* End XCSwiftPackageProductDependency section */
413 | };
414 | rootObject = CAFD9B332BB234B700B35F4A /* Project object */;
415 | }
416 |
--------------------------------------------------------------------------------
/EnvironmentDependencies/EnvironmentDependencies.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 60;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | A0107ABF2BA45EAC00D3A35B /* EnvironmentDependenciesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0107ABE2BA45EAC00D3A35B /* EnvironmentDependenciesApp.swift */; };
11 | A0107AC12BA45EAC00D3A35B /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0107AC02BA45EAC00D3A35B /* ContentView.swift */; };
12 | A0107AC32BA45EB100D3A35B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A0107AC22BA45EB100D3A35B /* Assets.xcassets */; };
13 | A0107AC72BA45EB100D3A35B /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A0107AC62BA45EB100D3A35B /* Preview Assets.xcassets */; };
14 | A0107AD02BA466EA00D3A35B /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0107ACF2BA466E900D3A35B /* Model.swift */; };
15 | A0107AD32BA46CB000D3A35B /* SharedDependencies in Frameworks */ = {isa = PBXBuildFile; productRef = A0107AD22BA46CB000D3A35B /* SharedDependencies */; };
16 | A0C7F3E02BAEEC4500204047 /* EnvironmentSetup.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0C7F3DF2BAEEC4500204047 /* EnvironmentSetup.swift */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXFileReference section */
20 | A0107ABB2BA45EAC00D3A35B /* EnvironmentDependencies.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EnvironmentDependencies.app; sourceTree = BUILT_PRODUCTS_DIR; };
21 | A0107ABE2BA45EAC00D3A35B /* EnvironmentDependenciesApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnvironmentDependenciesApp.swift; sourceTree = ""; };
22 | A0107AC02BA45EAC00D3A35B /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
23 | A0107AC22BA45EB100D3A35B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
24 | A0107AC42BA45EB100D3A35B /* EnvironmentDependencies.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = EnvironmentDependencies.entitlements; sourceTree = ""; };
25 | A0107AC62BA45EB100D3A35B /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
26 | A0107ACF2BA466E900D3A35B /* Model.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Model.swift; sourceTree = ""; };
27 | A0C7F3DF2BAEEC4500204047 /* EnvironmentSetup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnvironmentSetup.swift; sourceTree = ""; };
28 | /* End PBXFileReference section */
29 |
30 | /* Begin PBXFrameworksBuildPhase section */
31 | A0107AB82BA45EAC00D3A35B /* Frameworks */ = {
32 | isa = PBXFrameworksBuildPhase;
33 | buildActionMask = 2147483647;
34 | files = (
35 | A0107AD32BA46CB000D3A35B /* SharedDependencies in Frameworks */,
36 | );
37 | runOnlyForDeploymentPostprocessing = 0;
38 | };
39 | /* End PBXFrameworksBuildPhase section */
40 |
41 | /* Begin PBXGroup section */
42 | A0107AB22BA45EAC00D3A35B = {
43 | isa = PBXGroup;
44 | children = (
45 | A0107ABD2BA45EAC00D3A35B /* EnvironmentDependencies */,
46 | A0107ABC2BA45EAC00D3A35B /* Products */,
47 | );
48 | sourceTree = "";
49 | };
50 | A0107ABC2BA45EAC00D3A35B /* Products */ = {
51 | isa = PBXGroup;
52 | children = (
53 | A0107ABB2BA45EAC00D3A35B /* EnvironmentDependencies.app */,
54 | );
55 | name = Products;
56 | sourceTree = "";
57 | };
58 | A0107ABD2BA45EAC00D3A35B /* EnvironmentDependencies */ = {
59 | isa = PBXGroup;
60 | children = (
61 | A0107ABE2BA45EAC00D3A35B /* EnvironmentDependenciesApp.swift */,
62 | A0107AC02BA45EAC00D3A35B /* ContentView.swift */,
63 | A0107ACF2BA466E900D3A35B /* Model.swift */,
64 | A0C7F3DF2BAEEC4500204047 /* EnvironmentSetup.swift */,
65 | A0107AC22BA45EB100D3A35B /* Assets.xcassets */,
66 | A0107AC42BA45EB100D3A35B /* EnvironmentDependencies.entitlements */,
67 | A0107AC52BA45EB100D3A35B /* Preview Content */,
68 | );
69 | path = EnvironmentDependencies;
70 | sourceTree = "";
71 | };
72 | A0107AC52BA45EB100D3A35B /* Preview Content */ = {
73 | isa = PBXGroup;
74 | children = (
75 | A0107AC62BA45EB100D3A35B /* Preview Assets.xcassets */,
76 | );
77 | path = "Preview Content";
78 | sourceTree = "";
79 | };
80 | /* End PBXGroup section */
81 |
82 | /* Begin PBXNativeTarget section */
83 | A0107ABA2BA45EAC00D3A35B /* EnvironmentDependencies */ = {
84 | isa = PBXNativeTarget;
85 | buildConfigurationList = A0107ACA2BA45EB100D3A35B /* Build configuration list for PBXNativeTarget "EnvironmentDependencies" */;
86 | buildPhases = (
87 | A0107AB72BA45EAC00D3A35B /* Sources */,
88 | A0107AB82BA45EAC00D3A35B /* Frameworks */,
89 | A0107AB92BA45EAC00D3A35B /* Resources */,
90 | );
91 | buildRules = (
92 | );
93 | dependencies = (
94 | );
95 | name = EnvironmentDependencies;
96 | packageProductDependencies = (
97 | A0107AD22BA46CB000D3A35B /* SharedDependencies */,
98 | );
99 | productName = EnvironmentDependencies;
100 | productReference = A0107ABB2BA45EAC00D3A35B /* EnvironmentDependencies.app */;
101 | productType = "com.apple.product-type.application";
102 | };
103 | /* End PBXNativeTarget section */
104 |
105 | /* Begin PBXProject section */
106 | A0107AB32BA45EAC00D3A35B /* Project object */ = {
107 | isa = PBXProject;
108 | attributes = {
109 | BuildIndependentTargetsInParallel = 1;
110 | LastSwiftUpdateCheck = 1520;
111 | LastUpgradeCheck = 1530;
112 | TargetAttributes = {
113 | A0107ABA2BA45EAC00D3A35B = {
114 | CreatedOnToolsVersion = 15.2;
115 | };
116 | };
117 | };
118 | buildConfigurationList = A0107AB62BA45EAC00D3A35B /* Build configuration list for PBXProject "EnvironmentDependencies" */;
119 | compatibilityVersion = "Xcode 14.0";
120 | developmentRegion = en;
121 | hasScannedForEncodings = 0;
122 | knownRegions = (
123 | en,
124 | Base,
125 | );
126 | mainGroup = A0107AB22BA45EAC00D3A35B;
127 | packageReferences = (
128 | A0107AD12BA46CB000D3A35B /* XCLocalSwiftPackageReference "../SharedDependencies" */,
129 | );
130 | productRefGroup = A0107ABC2BA45EAC00D3A35B /* Products */;
131 | projectDirPath = "";
132 | projectRoot = "";
133 | targets = (
134 | A0107ABA2BA45EAC00D3A35B /* EnvironmentDependencies */,
135 | );
136 | };
137 | /* End PBXProject section */
138 |
139 | /* Begin PBXResourcesBuildPhase section */
140 | A0107AB92BA45EAC00D3A35B /* Resources */ = {
141 | isa = PBXResourcesBuildPhase;
142 | buildActionMask = 2147483647;
143 | files = (
144 | A0107AC72BA45EB100D3A35B /* Preview Assets.xcassets in Resources */,
145 | A0107AC32BA45EB100D3A35B /* Assets.xcassets in Resources */,
146 | );
147 | runOnlyForDeploymentPostprocessing = 0;
148 | };
149 | /* End PBXResourcesBuildPhase section */
150 |
151 | /* Begin PBXSourcesBuildPhase section */
152 | A0107AB72BA45EAC00D3A35B /* Sources */ = {
153 | isa = PBXSourcesBuildPhase;
154 | buildActionMask = 2147483647;
155 | files = (
156 | A0107AD02BA466EA00D3A35B /* Model.swift in Sources */,
157 | A0107AC12BA45EAC00D3A35B /* ContentView.swift in Sources */,
158 | A0107ABF2BA45EAC00D3A35B /* EnvironmentDependenciesApp.swift in Sources */,
159 | A0C7F3E02BAEEC4500204047 /* EnvironmentSetup.swift in Sources */,
160 | );
161 | runOnlyForDeploymentPostprocessing = 0;
162 | };
163 | /* End PBXSourcesBuildPhase section */
164 |
165 | /* Begin XCBuildConfiguration section */
166 | A0107AC82BA45EB100D3A35B /* Debug */ = {
167 | isa = XCBuildConfiguration;
168 | buildSettings = {
169 | ALWAYS_SEARCH_USER_PATHS = NO;
170 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
171 | CLANG_ANALYZER_NONNULL = YES;
172 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
173 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
174 | CLANG_ENABLE_MODULES = YES;
175 | CLANG_ENABLE_OBJC_ARC = YES;
176 | CLANG_ENABLE_OBJC_WEAK = YES;
177 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
178 | CLANG_WARN_BOOL_CONVERSION = YES;
179 | CLANG_WARN_COMMA = YES;
180 | CLANG_WARN_CONSTANT_CONVERSION = YES;
181 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
182 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
183 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
184 | CLANG_WARN_EMPTY_BODY = YES;
185 | CLANG_WARN_ENUM_CONVERSION = YES;
186 | CLANG_WARN_INFINITE_RECURSION = YES;
187 | CLANG_WARN_INT_CONVERSION = YES;
188 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
189 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
190 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
191 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
192 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
193 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
194 | CLANG_WARN_STRICT_PROTOTYPES = YES;
195 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
196 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
197 | CLANG_WARN_UNREACHABLE_CODE = YES;
198 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
199 | COPY_PHASE_STRIP = NO;
200 | DEAD_CODE_STRIPPING = YES;
201 | DEBUG_INFORMATION_FORMAT = dwarf;
202 | ENABLE_STRICT_OBJC_MSGSEND = YES;
203 | ENABLE_TESTABILITY = YES;
204 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
205 | GCC_C_LANGUAGE_STANDARD = gnu17;
206 | GCC_DYNAMIC_NO_PIC = NO;
207 | GCC_NO_COMMON_BLOCKS = YES;
208 | GCC_OPTIMIZATION_LEVEL = 0;
209 | GCC_PREPROCESSOR_DEFINITIONS = (
210 | "DEBUG=1",
211 | "$(inherited)",
212 | );
213 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
214 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
215 | GCC_WARN_UNDECLARED_SELECTOR = YES;
216 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
217 | GCC_WARN_UNUSED_FUNCTION = YES;
218 | GCC_WARN_UNUSED_VARIABLE = YES;
219 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
220 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
221 | MTL_FAST_MATH = YES;
222 | ONLY_ACTIVE_ARCH = YES;
223 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
224 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
225 | SWIFT_STRICT_CONCURRENCY = complete;
226 | };
227 | name = Debug;
228 | };
229 | A0107AC92BA45EB100D3A35B /* Release */ = {
230 | isa = XCBuildConfiguration;
231 | buildSettings = {
232 | ALWAYS_SEARCH_USER_PATHS = NO;
233 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
234 | CLANG_ANALYZER_NONNULL = YES;
235 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
236 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
237 | CLANG_ENABLE_MODULES = YES;
238 | CLANG_ENABLE_OBJC_ARC = YES;
239 | CLANG_ENABLE_OBJC_WEAK = YES;
240 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
241 | CLANG_WARN_BOOL_CONVERSION = YES;
242 | CLANG_WARN_COMMA = YES;
243 | CLANG_WARN_CONSTANT_CONVERSION = YES;
244 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
245 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
246 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
247 | CLANG_WARN_EMPTY_BODY = YES;
248 | CLANG_WARN_ENUM_CONVERSION = YES;
249 | CLANG_WARN_INFINITE_RECURSION = YES;
250 | CLANG_WARN_INT_CONVERSION = YES;
251 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
252 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
253 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
254 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
255 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
256 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
257 | CLANG_WARN_STRICT_PROTOTYPES = YES;
258 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
259 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
260 | CLANG_WARN_UNREACHABLE_CODE = YES;
261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
262 | COPY_PHASE_STRIP = NO;
263 | DEAD_CODE_STRIPPING = YES;
264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
265 | ENABLE_NS_ASSERTIONS = NO;
266 | ENABLE_STRICT_OBJC_MSGSEND = YES;
267 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
268 | GCC_C_LANGUAGE_STANDARD = gnu17;
269 | GCC_NO_COMMON_BLOCKS = YES;
270 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
271 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
272 | GCC_WARN_UNDECLARED_SELECTOR = YES;
273 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
274 | GCC_WARN_UNUSED_FUNCTION = YES;
275 | GCC_WARN_UNUSED_VARIABLE = YES;
276 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
277 | MTL_ENABLE_DEBUG_INFO = NO;
278 | MTL_FAST_MATH = YES;
279 | SWIFT_COMPILATION_MODE = wholemodule;
280 | SWIFT_STRICT_CONCURRENCY = complete;
281 | };
282 | name = Release;
283 | };
284 | A0107ACB2BA45EB100D3A35B /* Debug */ = {
285 | isa = XCBuildConfiguration;
286 | buildSettings = {
287 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
288 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
289 | CODE_SIGN_ENTITLEMENTS = EnvironmentDependencies/EnvironmentDependencies.entitlements;
290 | CODE_SIGN_STYLE = Automatic;
291 | CURRENT_PROJECT_VERSION = 1;
292 | DEAD_CODE_STRIPPING = YES;
293 | DEVELOPMENT_ASSET_PATHS = "\"EnvironmentDependencies/Preview Content\"";
294 | DEVELOPMENT_TEAM = 79L7M968L6;
295 | ENABLE_HARDENED_RUNTIME = YES;
296 | ENABLE_PREVIEWS = YES;
297 | GENERATE_INFOPLIST_FILE = YES;
298 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
299 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
300 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
301 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES;
302 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES;
303 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES;
304 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault;
305 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
306 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
307 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
308 | IPHONEOS_DEPLOYMENT_TARGET = 17.2;
309 | LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
310 | "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
311 | MACOSX_DEPLOYMENT_TARGET = 14.2;
312 | MARKETING_VERSION = 1.0;
313 | PRODUCT_BUNDLE_IDENTIFIER = dev.lucasvandongen.EnvironmentDependencies;
314 | PRODUCT_NAME = "$(TARGET_NAME)";
315 | SDKROOT = auto;
316 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
317 | SWIFT_EMIT_LOC_STRINGS = YES;
318 | SWIFT_STRICT_CONCURRENCY = complete;
319 | SWIFT_VERSION = 5.0;
320 | TARGETED_DEVICE_FAMILY = "1,2";
321 | };
322 | name = Debug;
323 | };
324 | A0107ACC2BA45EB100D3A35B /* Release */ = {
325 | isa = XCBuildConfiguration;
326 | buildSettings = {
327 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
328 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
329 | CODE_SIGN_ENTITLEMENTS = EnvironmentDependencies/EnvironmentDependencies.entitlements;
330 | CODE_SIGN_STYLE = Automatic;
331 | CURRENT_PROJECT_VERSION = 1;
332 | DEAD_CODE_STRIPPING = YES;
333 | DEVELOPMENT_ASSET_PATHS = "\"EnvironmentDependencies/Preview Content\"";
334 | DEVELOPMENT_TEAM = 79L7M968L6;
335 | ENABLE_HARDENED_RUNTIME = YES;
336 | ENABLE_PREVIEWS = YES;
337 | GENERATE_INFOPLIST_FILE = YES;
338 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
339 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
340 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
341 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES;
342 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES;
343 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES;
344 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault;
345 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
346 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
347 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
348 | IPHONEOS_DEPLOYMENT_TARGET = 17.2;
349 | LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
350 | "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
351 | MACOSX_DEPLOYMENT_TARGET = 14.2;
352 | MARKETING_VERSION = 1.0;
353 | PRODUCT_BUNDLE_IDENTIFIER = dev.lucasvandongen.EnvironmentDependencies;
354 | PRODUCT_NAME = "$(TARGET_NAME)";
355 | SDKROOT = auto;
356 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
357 | SWIFT_EMIT_LOC_STRINGS = YES;
358 | SWIFT_STRICT_CONCURRENCY = complete;
359 | SWIFT_VERSION = 5.0;
360 | TARGETED_DEVICE_FAMILY = "1,2";
361 | };
362 | name = Release;
363 | };
364 | /* End XCBuildConfiguration section */
365 |
366 | /* Begin XCConfigurationList section */
367 | A0107AB62BA45EAC00D3A35B /* Build configuration list for PBXProject "EnvironmentDependencies" */ = {
368 | isa = XCConfigurationList;
369 | buildConfigurations = (
370 | A0107AC82BA45EB100D3A35B /* Debug */,
371 | A0107AC92BA45EB100D3A35B /* Release */,
372 | );
373 | defaultConfigurationIsVisible = 0;
374 | defaultConfigurationName = Release;
375 | };
376 | A0107ACA2BA45EB100D3A35B /* Build configuration list for PBXNativeTarget "EnvironmentDependencies" */ = {
377 | isa = XCConfigurationList;
378 | buildConfigurations = (
379 | A0107ACB2BA45EB100D3A35B /* Debug */,
380 | A0107ACC2BA45EB100D3A35B /* Release */,
381 | );
382 | defaultConfigurationIsVisible = 0;
383 | defaultConfigurationName = Release;
384 | };
385 | /* End XCConfigurationList section */
386 |
387 | /* Begin XCLocalSwiftPackageReference section */
388 | A0107AD12BA46CB000D3A35B /* XCLocalSwiftPackageReference "../SharedDependencies" */ = {
389 | isa = XCLocalSwiftPackageReference;
390 | relativePath = ../SharedDependencies;
391 | };
392 | /* End XCLocalSwiftPackageReference section */
393 |
394 | /* Begin XCSwiftPackageProductDependency section */
395 | A0107AD22BA46CB000D3A35B /* SharedDependencies */ = {
396 | isa = XCSwiftPackageProductDependency;
397 | productName = SharedDependencies;
398 | };
399 | /* End XCSwiftPackageProductDependency section */
400 | };
401 | rootObject = A0107AB32BA45EAC00D3A35B /* Project object */;
402 | }
403 |
--------------------------------------------------------------------------------
/PassedDependencies/PassedDependencies.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 60;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | A07AFD4A2B989AEA004954C9 /* PassedDependenciesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A07AFD492B989AEA004954C9 /* PassedDependenciesApp.swift */; };
11 | A07AFD4C2B989AEA004954C9 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A07AFD4B2B989AEA004954C9 /* ContentView.swift */; };
12 | A07AFD4E2B989AED004954C9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A07AFD4D2B989AED004954C9 /* Assets.xcassets */; };
13 | A07AFD522B989AED004954C9 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A07AFD512B989AED004954C9 /* Preview Assets.xcassets */; };
14 | A07AFD592B989AFF004954C9 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = A07AFD582B989AFF004954C9 /* Container.swift */; };
15 | A07AFD5C2B989B4F004954C9 /* SharedDependencies in Frameworks */ = {isa = PBXBuildFile; productRef = A07AFD5B2B989B4F004954C9 /* SharedDependencies */; };
16 | A07AFD5E2B989FD0004954C9 /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = A07AFD5D2B989FD0004954C9 /* Model.swift */; };
17 | A0C7F3DE2BAEE28200204047 /* AuthenticatedFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0C7F3DD2BAEE28200204047 /* AuthenticatedFactory.swift */; };
18 | /* End PBXBuildFile section */
19 |
20 | /* Begin PBXFileReference section */
21 | A07AFD462B989AEA004954C9 /* PassedDependencies.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PassedDependencies.app; sourceTree = BUILT_PRODUCTS_DIR; };
22 | A07AFD492B989AEA004954C9 /* PassedDependenciesApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PassedDependenciesApp.swift; sourceTree = ""; };
23 | A07AFD4B2B989AEA004954C9 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
24 | A07AFD4D2B989AED004954C9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
25 | A07AFD4F2B989AED004954C9 /* PassedDependencies.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PassedDependencies.entitlements; sourceTree = ""; };
26 | A07AFD512B989AED004954C9 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
27 | A07AFD582B989AFF004954C9 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = ""; };
28 | A07AFD5D2B989FD0004954C9 /* Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Model.swift; sourceTree = ""; };
29 | A0C7F3DD2BAEE28200204047 /* AuthenticatedFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticatedFactory.swift; sourceTree = ""; };
30 | /* End PBXFileReference section */
31 |
32 | /* Begin PBXFrameworksBuildPhase section */
33 | A07AFD432B989AEA004954C9 /* Frameworks */ = {
34 | isa = PBXFrameworksBuildPhase;
35 | buildActionMask = 2147483647;
36 | files = (
37 | A07AFD5C2B989B4F004954C9 /* SharedDependencies in Frameworks */,
38 | );
39 | runOnlyForDeploymentPostprocessing = 0;
40 | };
41 | /* End PBXFrameworksBuildPhase section */
42 |
43 | /* Begin PBXGroup section */
44 | A07AFD3D2B989AEA004954C9 = {
45 | isa = PBXGroup;
46 | children = (
47 | A07AFD482B989AEA004954C9 /* PassedDependencies */,
48 | A07AFD472B989AEA004954C9 /* Products */,
49 | );
50 | sourceTree = "";
51 | };
52 | A07AFD472B989AEA004954C9 /* Products */ = {
53 | isa = PBXGroup;
54 | children = (
55 | A07AFD462B989AEA004954C9 /* PassedDependencies.app */,
56 | );
57 | name = Products;
58 | sourceTree = "";
59 | };
60 | A07AFD482B989AEA004954C9 /* PassedDependencies */ = {
61 | isa = PBXGroup;
62 | children = (
63 | A0C7F3DC2BAEE27100204047 /* Factories */,
64 | A07AFD492B989AEA004954C9 /* PassedDependenciesApp.swift */,
65 | A07AFD4B2B989AEA004954C9 /* ContentView.swift */,
66 | A07AFD4D2B989AED004954C9 /* Assets.xcassets */,
67 | A07AFD4F2B989AED004954C9 /* PassedDependencies.entitlements */,
68 | A07AFD502B989AED004954C9 /* Preview Content */,
69 | A07AFD582B989AFF004954C9 /* Container.swift */,
70 | A07AFD5D2B989FD0004954C9 /* Model.swift */,
71 | );
72 | path = PassedDependencies;
73 | sourceTree = "";
74 | };
75 | A07AFD502B989AED004954C9 /* Preview Content */ = {
76 | isa = PBXGroup;
77 | children = (
78 | A07AFD512B989AED004954C9 /* Preview Assets.xcassets */,
79 | );
80 | path = "Preview Content";
81 | sourceTree = "";
82 | };
83 | A0C7F3DC2BAEE27100204047 /* Factories */ = {
84 | isa = PBXGroup;
85 | children = (
86 | A0C7F3DD2BAEE28200204047 /* AuthenticatedFactory.swift */,
87 | );
88 | path = Factories;
89 | sourceTree = "";
90 | };
91 | /* End PBXGroup section */
92 |
93 | /* Begin PBXNativeTarget section */
94 | A07AFD452B989AEA004954C9 /* PassedDependencies */ = {
95 | isa = PBXNativeTarget;
96 | buildConfigurationList = A07AFD552B989AED004954C9 /* Build configuration list for PBXNativeTarget "PassedDependencies" */;
97 | buildPhases = (
98 | A07AFD422B989AEA004954C9 /* Sources */,
99 | A07AFD432B989AEA004954C9 /* Frameworks */,
100 | A07AFD442B989AEA004954C9 /* Resources */,
101 | );
102 | buildRules = (
103 | );
104 | dependencies = (
105 | );
106 | name = PassedDependencies;
107 | packageProductDependencies = (
108 | A07AFD5B2B989B4F004954C9 /* SharedDependencies */,
109 | );
110 | productName = PassedDependencies;
111 | productReference = A07AFD462B989AEA004954C9 /* PassedDependencies.app */;
112 | productType = "com.apple.product-type.application";
113 | };
114 | /* End PBXNativeTarget section */
115 |
116 | /* Begin PBXProject section */
117 | A07AFD3E2B989AEA004954C9 /* Project object */ = {
118 | isa = PBXProject;
119 | attributes = {
120 | BuildIndependentTargetsInParallel = 1;
121 | LastSwiftUpdateCheck = 1520;
122 | LastUpgradeCheck = 1520;
123 | TargetAttributes = {
124 | A07AFD452B989AEA004954C9 = {
125 | CreatedOnToolsVersion = 15.2;
126 | };
127 | };
128 | };
129 | buildConfigurationList = A07AFD412B989AEA004954C9 /* Build configuration list for PBXProject "PassedDependencies" */;
130 | compatibilityVersion = "Xcode 14.0";
131 | developmentRegion = en;
132 | hasScannedForEncodings = 0;
133 | knownRegions = (
134 | en,
135 | Base,
136 | );
137 | mainGroup = A07AFD3D2B989AEA004954C9;
138 | packageReferences = (
139 | A07AFD5A2B989B4F004954C9 /* XCLocalSwiftPackageReference "../SharedDependencies" */,
140 | );
141 | productRefGroup = A07AFD472B989AEA004954C9 /* Products */;
142 | projectDirPath = "";
143 | projectRoot = "";
144 | targets = (
145 | A07AFD452B989AEA004954C9 /* PassedDependencies */,
146 | );
147 | };
148 | /* End PBXProject section */
149 |
150 | /* Begin PBXResourcesBuildPhase section */
151 | A07AFD442B989AEA004954C9 /* Resources */ = {
152 | isa = PBXResourcesBuildPhase;
153 | buildActionMask = 2147483647;
154 | files = (
155 | A07AFD522B989AED004954C9 /* Preview Assets.xcassets in Resources */,
156 | A07AFD4E2B989AED004954C9 /* Assets.xcassets in Resources */,
157 | );
158 | runOnlyForDeploymentPostprocessing = 0;
159 | };
160 | /* End PBXResourcesBuildPhase section */
161 |
162 | /* Begin PBXSourcesBuildPhase section */
163 | A07AFD422B989AEA004954C9 /* Sources */ = {
164 | isa = PBXSourcesBuildPhase;
165 | buildActionMask = 2147483647;
166 | files = (
167 | A07AFD4C2B989AEA004954C9 /* ContentView.swift in Sources */,
168 | A0C7F3DE2BAEE28200204047 /* AuthenticatedFactory.swift in Sources */,
169 | A07AFD592B989AFF004954C9 /* Container.swift in Sources */,
170 | A07AFD4A2B989AEA004954C9 /* PassedDependenciesApp.swift in Sources */,
171 | A07AFD5E2B989FD0004954C9 /* Model.swift in Sources */,
172 | );
173 | runOnlyForDeploymentPostprocessing = 0;
174 | };
175 | /* End PBXSourcesBuildPhase section */
176 |
177 | /* Begin XCBuildConfiguration section */
178 | A07AFD532B989AED004954C9 /* Debug */ = {
179 | isa = XCBuildConfiguration;
180 | buildSettings = {
181 | ALWAYS_SEARCH_USER_PATHS = NO;
182 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
183 | CLANG_ANALYZER_NONNULL = YES;
184 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
185 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
186 | CLANG_ENABLE_MODULES = YES;
187 | CLANG_ENABLE_OBJC_ARC = YES;
188 | CLANG_ENABLE_OBJC_WEAK = YES;
189 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
190 | CLANG_WARN_BOOL_CONVERSION = YES;
191 | CLANG_WARN_COMMA = YES;
192 | CLANG_WARN_CONSTANT_CONVERSION = YES;
193 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
194 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
195 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
196 | CLANG_WARN_EMPTY_BODY = YES;
197 | CLANG_WARN_ENUM_CONVERSION = YES;
198 | CLANG_WARN_INFINITE_RECURSION = YES;
199 | CLANG_WARN_INT_CONVERSION = YES;
200 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
201 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
202 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
203 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
204 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
205 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
206 | CLANG_WARN_STRICT_PROTOTYPES = YES;
207 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
208 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
209 | CLANG_WARN_UNREACHABLE_CODE = YES;
210 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
211 | COPY_PHASE_STRIP = NO;
212 | DEBUG_INFORMATION_FORMAT = dwarf;
213 | ENABLE_STRICT_OBJC_MSGSEND = YES;
214 | ENABLE_TESTABILITY = YES;
215 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
216 | GCC_C_LANGUAGE_STANDARD = gnu17;
217 | GCC_DYNAMIC_NO_PIC = NO;
218 | GCC_NO_COMMON_BLOCKS = YES;
219 | GCC_OPTIMIZATION_LEVEL = 0;
220 | GCC_PREPROCESSOR_DEFINITIONS = (
221 | "DEBUG=1",
222 | "$(inherited)",
223 | );
224 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
225 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
226 | GCC_WARN_UNDECLARED_SELECTOR = YES;
227 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
228 | GCC_WARN_UNUSED_FUNCTION = YES;
229 | GCC_WARN_UNUSED_VARIABLE = YES;
230 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
231 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
232 | MTL_FAST_MATH = YES;
233 | ONLY_ACTIVE_ARCH = YES;
234 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
235 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
236 | SWIFT_STRICT_CONCURRENCY = complete;
237 | };
238 | name = Debug;
239 | };
240 | A07AFD542B989AED004954C9 /* Release */ = {
241 | isa = XCBuildConfiguration;
242 | buildSettings = {
243 | ALWAYS_SEARCH_USER_PATHS = NO;
244 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
245 | CLANG_ANALYZER_NONNULL = YES;
246 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
247 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
248 | CLANG_ENABLE_MODULES = YES;
249 | CLANG_ENABLE_OBJC_ARC = YES;
250 | CLANG_ENABLE_OBJC_WEAK = YES;
251 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
252 | CLANG_WARN_BOOL_CONVERSION = YES;
253 | CLANG_WARN_COMMA = YES;
254 | CLANG_WARN_CONSTANT_CONVERSION = YES;
255 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
256 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
257 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
258 | CLANG_WARN_EMPTY_BODY = YES;
259 | CLANG_WARN_ENUM_CONVERSION = YES;
260 | CLANG_WARN_INFINITE_RECURSION = YES;
261 | CLANG_WARN_INT_CONVERSION = YES;
262 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
263 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
264 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
265 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
266 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
267 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
268 | CLANG_WARN_STRICT_PROTOTYPES = YES;
269 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
270 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
271 | CLANG_WARN_UNREACHABLE_CODE = YES;
272 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
273 | COPY_PHASE_STRIP = NO;
274 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
275 | ENABLE_NS_ASSERTIONS = NO;
276 | ENABLE_STRICT_OBJC_MSGSEND = YES;
277 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
278 | GCC_C_LANGUAGE_STANDARD = gnu17;
279 | GCC_NO_COMMON_BLOCKS = YES;
280 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
281 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
282 | GCC_WARN_UNDECLARED_SELECTOR = YES;
283 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
284 | GCC_WARN_UNUSED_FUNCTION = YES;
285 | GCC_WARN_UNUSED_VARIABLE = YES;
286 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
287 | MTL_ENABLE_DEBUG_INFO = NO;
288 | MTL_FAST_MATH = YES;
289 | SWIFT_COMPILATION_MODE = wholemodule;
290 | SWIFT_STRICT_CONCURRENCY = complete;
291 | };
292 | name = Release;
293 | };
294 | A07AFD562B989AED004954C9 /* Debug */ = {
295 | isa = XCBuildConfiguration;
296 | buildSettings = {
297 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
298 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
299 | CODE_SIGN_ENTITLEMENTS = PassedDependencies/PassedDependencies.entitlements;
300 | CODE_SIGN_STYLE = Automatic;
301 | CURRENT_PROJECT_VERSION = 1;
302 | DEVELOPMENT_ASSET_PATHS = "\"PassedDependencies/Preview Content\"";
303 | DEVELOPMENT_TEAM = 79L7M968L6;
304 | ENABLE_HARDENED_RUNTIME = YES;
305 | ENABLE_PREVIEWS = YES;
306 | GENERATE_INFOPLIST_FILE = YES;
307 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
308 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
309 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
310 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES;
311 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES;
312 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES;
313 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault;
314 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
315 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
316 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
317 | IPHONEOS_DEPLOYMENT_TARGET = 17.2;
318 | LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
319 | "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
320 | MACOSX_DEPLOYMENT_TARGET = 14.2;
321 | MARKETING_VERSION = 1.0;
322 | PRODUCT_BUNDLE_IDENTIFIER = dev.lucasvandongen.PassedDependencies;
323 | PRODUCT_NAME = "$(TARGET_NAME)";
324 | SDKROOT = auto;
325 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
326 | SWIFT_EMIT_LOC_STRINGS = YES;
327 | SWIFT_VERSION = 5.0;
328 | TARGETED_DEVICE_FAMILY = "1,2";
329 | };
330 | name = Debug;
331 | };
332 | A07AFD572B989AED004954C9 /* Release */ = {
333 | isa = XCBuildConfiguration;
334 | buildSettings = {
335 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
336 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
337 | CODE_SIGN_ENTITLEMENTS = PassedDependencies/PassedDependencies.entitlements;
338 | CODE_SIGN_STYLE = Automatic;
339 | CURRENT_PROJECT_VERSION = 1;
340 | DEVELOPMENT_ASSET_PATHS = "\"PassedDependencies/Preview Content\"";
341 | DEVELOPMENT_TEAM = 79L7M968L6;
342 | ENABLE_HARDENED_RUNTIME = YES;
343 | ENABLE_PREVIEWS = YES;
344 | GENERATE_INFOPLIST_FILE = YES;
345 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
346 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
347 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
348 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES;
349 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES;
350 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES;
351 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault;
352 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
353 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
354 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
355 | IPHONEOS_DEPLOYMENT_TARGET = 17.2;
356 | LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
357 | "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
358 | MACOSX_DEPLOYMENT_TARGET = 14.2;
359 | MARKETING_VERSION = 1.0;
360 | PRODUCT_BUNDLE_IDENTIFIER = dev.lucasvandongen.PassedDependencies;
361 | PRODUCT_NAME = "$(TARGET_NAME)";
362 | SDKROOT = auto;
363 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
364 | SWIFT_EMIT_LOC_STRINGS = YES;
365 | SWIFT_VERSION = 5.0;
366 | TARGETED_DEVICE_FAMILY = "1,2";
367 | };
368 | name = Release;
369 | };
370 | /* End XCBuildConfiguration section */
371 |
372 | /* Begin XCConfigurationList section */
373 | A07AFD412B989AEA004954C9 /* Build configuration list for PBXProject "PassedDependencies" */ = {
374 | isa = XCConfigurationList;
375 | buildConfigurations = (
376 | A07AFD532B989AED004954C9 /* Debug */,
377 | A07AFD542B989AED004954C9 /* Release */,
378 | );
379 | defaultConfigurationIsVisible = 0;
380 | defaultConfigurationName = Release;
381 | };
382 | A07AFD552B989AED004954C9 /* Build configuration list for PBXNativeTarget "PassedDependencies" */ = {
383 | isa = XCConfigurationList;
384 | buildConfigurations = (
385 | A07AFD562B989AED004954C9 /* Debug */,
386 | A07AFD572B989AED004954C9 /* Release */,
387 | );
388 | defaultConfigurationIsVisible = 0;
389 | defaultConfigurationName = Release;
390 | };
391 | /* End XCConfigurationList section */
392 |
393 | /* Begin XCLocalSwiftPackageReference section */
394 | A07AFD5A2B989B4F004954C9 /* XCLocalSwiftPackageReference "../SharedDependencies" */ = {
395 | isa = XCLocalSwiftPackageReference;
396 | relativePath = ../SharedDependencies;
397 | };
398 | /* End XCLocalSwiftPackageReference section */
399 |
400 | /* Begin XCSwiftPackageProductDependency section */
401 | A07AFD5B2B989B4F004954C9 /* SharedDependencies */ = {
402 | isa = XCSwiftPackageProductDependency;
403 | productName = SharedDependencies;
404 | };
405 | /* End XCSwiftPackageProductDependency section */
406 | };
407 | rootObject = A07AFD3E2B989AEA004954C9 /* Project object */;
408 | }
409 |
--------------------------------------------------------------------------------
/NeedleDependencies/NeedleDependencies.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 60;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | A0107A472BA090F300D3A35B /* NeedleDependenciesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0107A462BA090F300D3A35B /* NeedleDependenciesApp.swift */; };
11 | A0107A492BA090F300D3A35B /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0107A482BA090F300D3A35B /* ContentView.swift */; };
12 | A0107A4B2BA090F600D3A35B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A0107A4A2BA090F600D3A35B /* Assets.xcassets */; };
13 | A0107A4E2BA090F600D3A35B /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A0107A4D2BA090F600D3A35B /* Preview Assets.xcassets */; };
14 | A0107A5C2BA099EF00D3A35B /* NeedleGenerated.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0107A5B2BA099EF00D3A35B /* NeedleGenerated.swift */; };
15 | A0107A5E2BA09ADB00D3A35B /* RootComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0107A5D2BA09ADB00D3A35B /* RootComponent.swift */; };
16 | A0107A612BA09B7D00D3A35B /* SharedDependencies in Frameworks */ = {isa = PBXBuildFile; productRef = A0107A602BA09B7D00D3A35B /* SharedDependencies */; };
17 | A0107A632BA0A93B00D3A35B /* LogInComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0107A622BA0A93B00D3A35B /* LogInComponent.swift */; };
18 | A0107A652BA0A96700D3A35B /* AuthenticatedComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0107A642BA0A96700D3A35B /* AuthenticatedComponent.swift */; };
19 | CAFD9B772BB2445100B35F4A /* NeedleFoundation in Frameworks */ = {isa = PBXBuildFile; productRef = CAFD9B762BB2445100B35F4A /* NeedleFoundation */; };
20 | /* End PBXBuildFile section */
21 |
22 | /* Begin PBXFileReference section */
23 | A0107A432BA090F300D3A35B /* NeedleDependencies.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NeedleDependencies.app; sourceTree = BUILT_PRODUCTS_DIR; };
24 | A0107A462BA090F300D3A35B /* NeedleDependenciesApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NeedleDependenciesApp.swift; sourceTree = ""; };
25 | A0107A482BA090F300D3A35B /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
26 | A0107A4A2BA090F600D3A35B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
27 | A0107A4D2BA090F600D3A35B /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
28 | A0107A4F2BA090F600D3A35B /* NeedleDependencies.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NeedleDependencies.entitlements; sourceTree = ""; };
29 | A0107A5B2BA099EF00D3A35B /* NeedleGenerated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NeedleGenerated.swift; sourceTree = ""; };
30 | A0107A5D2BA09ADB00D3A35B /* RootComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootComponent.swift; sourceTree = ""; };
31 | A0107A622BA0A93B00D3A35B /* LogInComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogInComponent.swift; sourceTree = ""; };
32 | A0107A642BA0A96700D3A35B /* AuthenticatedComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticatedComponent.swift; sourceTree = ""; };
33 | /* End PBXFileReference section */
34 |
35 | /* Begin PBXFrameworksBuildPhase section */
36 | A0107A402BA090F300D3A35B /* Frameworks */ = {
37 | isa = PBXFrameworksBuildPhase;
38 | buildActionMask = 2147483647;
39 | files = (
40 | CAFD9B772BB2445100B35F4A /* NeedleFoundation in Frameworks */,
41 | A0107A612BA09B7D00D3A35B /* SharedDependencies in Frameworks */,
42 | );
43 | runOnlyForDeploymentPostprocessing = 0;
44 | };
45 | /* End PBXFrameworksBuildPhase section */
46 |
47 | /* Begin PBXGroup section */
48 | A0107A3A2BA090F300D3A35B = {
49 | isa = PBXGroup;
50 | children = (
51 | A0107A452BA090F300D3A35B /* NeedleDependencies */,
52 | A0107A442BA090F300D3A35B /* Products */,
53 | A0107A572BA0934A00D3A35B /* Frameworks */,
54 | );
55 | sourceTree = "";
56 | };
57 | A0107A442BA090F300D3A35B /* Products */ = {
58 | isa = PBXGroup;
59 | children = (
60 | A0107A432BA090F300D3A35B /* NeedleDependencies.app */,
61 | );
62 | name = Products;
63 | sourceTree = "";
64 | };
65 | A0107A452BA090F300D3A35B /* NeedleDependencies */ = {
66 | isa = PBXGroup;
67 | children = (
68 | A0107A5B2BA099EF00D3A35B /* NeedleGenerated.swift */,
69 | A0107A462BA090F300D3A35B /* NeedleDependenciesApp.swift */,
70 | A0107A482BA090F300D3A35B /* ContentView.swift */,
71 | A0107A4A2BA090F600D3A35B /* Assets.xcassets */,
72 | A0107A4F2BA090F600D3A35B /* NeedleDependencies.entitlements */,
73 | A0107A4C2BA090F600D3A35B /* Preview Content */,
74 | A0107A5D2BA09ADB00D3A35B /* RootComponent.swift */,
75 | A0107A622BA0A93B00D3A35B /* LogInComponent.swift */,
76 | A0107A642BA0A96700D3A35B /* AuthenticatedComponent.swift */,
77 | );
78 | path = NeedleDependencies;
79 | sourceTree = "";
80 | };
81 | A0107A4C2BA090F600D3A35B /* Preview Content */ = {
82 | isa = PBXGroup;
83 | children = (
84 | A0107A4D2BA090F600D3A35B /* Preview Assets.xcassets */,
85 | );
86 | path = "Preview Content";
87 | sourceTree = "";
88 | };
89 | A0107A572BA0934A00D3A35B /* Frameworks */ = {
90 | isa = PBXGroup;
91 | children = (
92 | );
93 | name = Frameworks;
94 | sourceTree = "";
95 | };
96 | /* End PBXGroup section */
97 |
98 | /* Begin PBXNativeTarget section */
99 | A0107A422BA090F300D3A35B /* NeedleDependencies */ = {
100 | isa = PBXNativeTarget;
101 | buildConfigurationList = A0107A522BA090F600D3A35B /* Build configuration list for PBXNativeTarget "NeedleDependencies" */;
102 | buildPhases = (
103 | A0107A5A2BA0959D00D3A35B /* Needle */,
104 | A0107A3F2BA090F300D3A35B /* Sources */,
105 | A0107A402BA090F300D3A35B /* Frameworks */,
106 | A0107A412BA090F300D3A35B /* Resources */,
107 | );
108 | buildRules = (
109 | );
110 | dependencies = (
111 | );
112 | name = NeedleDependencies;
113 | packageProductDependencies = (
114 | A0107A602BA09B7D00D3A35B /* SharedDependencies */,
115 | CAFD9B762BB2445100B35F4A /* NeedleFoundation */,
116 | );
117 | productName = NeedleDependencies;
118 | productReference = A0107A432BA090F300D3A35B /* NeedleDependencies.app */;
119 | productType = "com.apple.product-type.application";
120 | };
121 | /* End PBXNativeTarget section */
122 |
123 | /* Begin PBXProject section */
124 | A0107A3B2BA090F300D3A35B /* Project object */ = {
125 | isa = PBXProject;
126 | attributes = {
127 | BuildIndependentTargetsInParallel = 1;
128 | LastSwiftUpdateCheck = 1520;
129 | LastUpgradeCheck = 1520;
130 | TargetAttributes = {
131 | A0107A422BA090F300D3A35B = {
132 | CreatedOnToolsVersion = 15.2;
133 | };
134 | };
135 | };
136 | buildConfigurationList = A0107A3E2BA090F300D3A35B /* Build configuration list for PBXProject "NeedleDependencies" */;
137 | compatibilityVersion = "Xcode 14.0";
138 | developmentRegion = en;
139 | hasScannedForEncodings = 0;
140 | knownRegions = (
141 | en,
142 | Base,
143 | );
144 | mainGroup = A0107A3A2BA090F300D3A35B;
145 | packageReferences = (
146 | A0107A5F2BA09B7D00D3A35B /* XCLocalSwiftPackageReference "../SharedDependencies" */,
147 | CAFD9ABF2BB22F2B00B35F4A /* XCRemoteSwiftPackageReference "needle" */,
148 | );
149 | productRefGroup = A0107A442BA090F300D3A35B /* Products */;
150 | projectDirPath = "";
151 | projectRoot = "";
152 | targets = (
153 | A0107A422BA090F300D3A35B /* NeedleDependencies */,
154 | );
155 | };
156 | /* End PBXProject section */
157 |
158 | /* Begin PBXResourcesBuildPhase section */
159 | A0107A412BA090F300D3A35B /* Resources */ = {
160 | isa = PBXResourcesBuildPhase;
161 | buildActionMask = 2147483647;
162 | files = (
163 | A0107A4E2BA090F600D3A35B /* Preview Assets.xcassets in Resources */,
164 | A0107A4B2BA090F600D3A35B /* Assets.xcassets in Resources */,
165 | );
166 | runOnlyForDeploymentPostprocessing = 0;
167 | };
168 | /* End PBXResourcesBuildPhase section */
169 |
170 | /* Begin PBXShellScriptBuildPhase section */
171 | A0107A5A2BA0959D00D3A35B /* Needle */ = {
172 | isa = PBXShellScriptBuildPhase;
173 | buildActionMask = 12;
174 | files = (
175 | );
176 | inputFileListPaths = (
177 | );
178 | inputPaths = (
179 | );
180 | name = Needle;
181 | outputFileListPaths = (
182 | );
183 | outputPaths = (
184 | );
185 | runOnlyForDeploymentPostprocessing = 0;
186 | shellPath = /bin/sh;
187 | shellScript = "#export SOURCEKIT_LOGGING=0 && needle generate ./NeedleDependencies/NeedleGenerated.swift ./ --header-doc ./NeedleDependencies/copyright_header.txt\n";
188 | };
189 | /* End PBXShellScriptBuildPhase section */
190 |
191 | /* Begin PBXSourcesBuildPhase section */
192 | A0107A3F2BA090F300D3A35B /* Sources */ = {
193 | isa = PBXSourcesBuildPhase;
194 | buildActionMask = 2147483647;
195 | files = (
196 | A0107A492BA090F300D3A35B /* ContentView.swift in Sources */,
197 | A0107A652BA0A96700D3A35B /* AuthenticatedComponent.swift in Sources */,
198 | A0107A5E2BA09ADB00D3A35B /* RootComponent.swift in Sources */,
199 | A0107A472BA090F300D3A35B /* NeedleDependenciesApp.swift in Sources */,
200 | A0107A632BA0A93B00D3A35B /* LogInComponent.swift in Sources */,
201 | A0107A5C2BA099EF00D3A35B /* NeedleGenerated.swift in Sources */,
202 | );
203 | runOnlyForDeploymentPostprocessing = 0;
204 | };
205 | /* End PBXSourcesBuildPhase section */
206 |
207 | /* Begin XCBuildConfiguration section */
208 | A0107A502BA090F600D3A35B /* Debug */ = {
209 | isa = XCBuildConfiguration;
210 | buildSettings = {
211 | ALWAYS_SEARCH_USER_PATHS = NO;
212 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
213 | CLANG_ANALYZER_NONNULL = YES;
214 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
215 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
216 | CLANG_ENABLE_MODULES = YES;
217 | CLANG_ENABLE_OBJC_ARC = YES;
218 | CLANG_ENABLE_OBJC_WEAK = YES;
219 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
220 | CLANG_WARN_BOOL_CONVERSION = YES;
221 | CLANG_WARN_COMMA = YES;
222 | CLANG_WARN_CONSTANT_CONVERSION = YES;
223 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
224 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
225 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
226 | CLANG_WARN_EMPTY_BODY = YES;
227 | CLANG_WARN_ENUM_CONVERSION = YES;
228 | CLANG_WARN_INFINITE_RECURSION = YES;
229 | CLANG_WARN_INT_CONVERSION = YES;
230 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
231 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
232 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
233 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
234 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
235 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
236 | CLANG_WARN_STRICT_PROTOTYPES = YES;
237 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
238 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
239 | CLANG_WARN_UNREACHABLE_CODE = YES;
240 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
241 | COPY_PHASE_STRIP = NO;
242 | DEBUG_INFORMATION_FORMAT = dwarf;
243 | ENABLE_STRICT_OBJC_MSGSEND = YES;
244 | ENABLE_TESTABILITY = YES;
245 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
246 | GCC_C_LANGUAGE_STANDARD = gnu17;
247 | GCC_DYNAMIC_NO_PIC = NO;
248 | GCC_NO_COMMON_BLOCKS = YES;
249 | GCC_OPTIMIZATION_LEVEL = 0;
250 | GCC_PREPROCESSOR_DEFINITIONS = (
251 | "DEBUG=1",
252 | "$(inherited)",
253 | );
254 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
255 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
256 | GCC_WARN_UNDECLARED_SELECTOR = YES;
257 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
258 | GCC_WARN_UNUSED_FUNCTION = YES;
259 | GCC_WARN_UNUSED_VARIABLE = YES;
260 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
261 | MACOSX_DEPLOYMENT_TARGET = 14.0;
262 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
263 | MTL_FAST_MATH = YES;
264 | ONLY_ACTIVE_ARCH = YES;
265 | SDKROOT = macosx;
266 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
267 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
268 | SWIFT_STRICT_CONCURRENCY = complete;
269 | };
270 | name = Debug;
271 | };
272 | A0107A512BA090F600D3A35B /* Release */ = {
273 | isa = XCBuildConfiguration;
274 | buildSettings = {
275 | ALWAYS_SEARCH_USER_PATHS = NO;
276 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
277 | CLANG_ANALYZER_NONNULL = YES;
278 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
279 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
280 | CLANG_ENABLE_MODULES = YES;
281 | CLANG_ENABLE_OBJC_ARC = YES;
282 | CLANG_ENABLE_OBJC_WEAK = YES;
283 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
284 | CLANG_WARN_BOOL_CONVERSION = YES;
285 | CLANG_WARN_COMMA = YES;
286 | CLANG_WARN_CONSTANT_CONVERSION = YES;
287 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
288 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
289 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
290 | CLANG_WARN_EMPTY_BODY = YES;
291 | CLANG_WARN_ENUM_CONVERSION = YES;
292 | CLANG_WARN_INFINITE_RECURSION = YES;
293 | CLANG_WARN_INT_CONVERSION = YES;
294 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
295 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
296 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
297 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
298 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
299 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
300 | CLANG_WARN_STRICT_PROTOTYPES = YES;
301 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
302 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
303 | CLANG_WARN_UNREACHABLE_CODE = YES;
304 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
305 | COPY_PHASE_STRIP = NO;
306 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
307 | ENABLE_NS_ASSERTIONS = NO;
308 | ENABLE_STRICT_OBJC_MSGSEND = YES;
309 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
310 | GCC_C_LANGUAGE_STANDARD = gnu17;
311 | GCC_NO_COMMON_BLOCKS = YES;
312 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
313 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
314 | GCC_WARN_UNDECLARED_SELECTOR = YES;
315 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
316 | GCC_WARN_UNUSED_FUNCTION = YES;
317 | GCC_WARN_UNUSED_VARIABLE = YES;
318 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
319 | MACOSX_DEPLOYMENT_TARGET = 14.0;
320 | MTL_ENABLE_DEBUG_INFO = NO;
321 | MTL_FAST_MATH = YES;
322 | SDKROOT = macosx;
323 | SWIFT_COMPILATION_MODE = wholemodule;
324 | SWIFT_STRICT_CONCURRENCY = complete;
325 | };
326 | name = Release;
327 | };
328 | A0107A532BA090F600D3A35B /* Debug */ = {
329 | isa = XCBuildConfiguration;
330 | buildSettings = {
331 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
332 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
333 | CODE_SIGN_ENTITLEMENTS = NeedleDependencies/NeedleDependencies.entitlements;
334 | CODE_SIGN_STYLE = Automatic;
335 | COMBINE_HIDPI_IMAGES = YES;
336 | CURRENT_PROJECT_VERSION = 1;
337 | DEVELOPMENT_ASSET_PATHS = "\"NeedleDependencies/Preview Content\"";
338 | DEVELOPMENT_TEAM = 79L7M968L6;
339 | ENABLE_HARDENED_RUNTIME = YES;
340 | ENABLE_PREVIEWS = YES;
341 | ENABLE_USER_SCRIPT_SANDBOXING = NO;
342 | GENERATE_INFOPLIST_FILE = YES;
343 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
344 | LD_RUNPATH_SEARCH_PATHS = (
345 | "$(inherited)",
346 | "@executable_path/../Frameworks",
347 | );
348 | MARKETING_VERSION = 1.0;
349 | PRODUCT_BUNDLE_IDENTIFIER = dev.lucasvandongen.NeedleDependencies;
350 | PRODUCT_NAME = "$(TARGET_NAME)";
351 | SWIFT_EMIT_LOC_STRINGS = YES;
352 | SWIFT_VERSION = 5.0;
353 | };
354 | name = Debug;
355 | };
356 | A0107A542BA090F600D3A35B /* Release */ = {
357 | isa = XCBuildConfiguration;
358 | buildSettings = {
359 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
360 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
361 | CODE_SIGN_ENTITLEMENTS = NeedleDependencies/NeedleDependencies.entitlements;
362 | CODE_SIGN_STYLE = Automatic;
363 | COMBINE_HIDPI_IMAGES = YES;
364 | CURRENT_PROJECT_VERSION = 1;
365 | DEVELOPMENT_ASSET_PATHS = "\"NeedleDependencies/Preview Content\"";
366 | DEVELOPMENT_TEAM = 79L7M968L6;
367 | ENABLE_HARDENED_RUNTIME = YES;
368 | ENABLE_PREVIEWS = YES;
369 | ENABLE_USER_SCRIPT_SANDBOXING = NO;
370 | GENERATE_INFOPLIST_FILE = YES;
371 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
372 | LD_RUNPATH_SEARCH_PATHS = (
373 | "$(inherited)",
374 | "@executable_path/../Frameworks",
375 | );
376 | MARKETING_VERSION = 1.0;
377 | PRODUCT_BUNDLE_IDENTIFIER = dev.lucasvandongen.NeedleDependencies;
378 | PRODUCT_NAME = "$(TARGET_NAME)";
379 | SWIFT_EMIT_LOC_STRINGS = YES;
380 | SWIFT_VERSION = 5.0;
381 | };
382 | name = Release;
383 | };
384 | /* End XCBuildConfiguration section */
385 |
386 | /* Begin XCConfigurationList section */
387 | A0107A3E2BA090F300D3A35B /* Build configuration list for PBXProject "NeedleDependencies" */ = {
388 | isa = XCConfigurationList;
389 | buildConfigurations = (
390 | A0107A502BA090F600D3A35B /* Debug */,
391 | A0107A512BA090F600D3A35B /* Release */,
392 | );
393 | defaultConfigurationIsVisible = 0;
394 | defaultConfigurationName = Release;
395 | };
396 | A0107A522BA090F600D3A35B /* Build configuration list for PBXNativeTarget "NeedleDependencies" */ = {
397 | isa = XCConfigurationList;
398 | buildConfigurations = (
399 | A0107A532BA090F600D3A35B /* Debug */,
400 | A0107A542BA090F600D3A35B /* Release */,
401 | );
402 | defaultConfigurationIsVisible = 0;
403 | defaultConfigurationName = Release;
404 | };
405 | /* End XCConfigurationList section */
406 |
407 | /* Begin XCLocalSwiftPackageReference section */
408 | A0107A5F2BA09B7D00D3A35B /* XCLocalSwiftPackageReference "../SharedDependencies" */ = {
409 | isa = XCLocalSwiftPackageReference;
410 | relativePath = ../SharedDependencies;
411 | };
412 | /* End XCLocalSwiftPackageReference section */
413 |
414 | /* Begin XCRemoteSwiftPackageReference section */
415 | CAFD9ABF2BB22F2B00B35F4A /* XCRemoteSwiftPackageReference "needle" */ = {
416 | isa = XCRemoteSwiftPackageReference;
417 | repositoryURL = "https://github.com/uber/needle";
418 | requirement = {
419 | branch = master;
420 | kind = branch;
421 | };
422 | };
423 | /* End XCRemoteSwiftPackageReference section */
424 |
425 | /* Begin XCSwiftPackageProductDependency section */
426 | A0107A602BA09B7D00D3A35B /* SharedDependencies */ = {
427 | isa = XCSwiftPackageProductDependency;
428 | productName = SharedDependencies;
429 | };
430 | CAFD9B762BB2445100B35F4A /* NeedleFoundation */ = {
431 | isa = XCSwiftPackageProductDependency;
432 | package = CAFD9ABF2BB22F2B00B35F4A /* XCRemoteSwiftPackageReference "needle" */;
433 | productName = NeedleFoundation;
434 | };
435 | /* End XCSwiftPackageProductDependency section */
436 | };
437 | rootObject = A0107A3B2BA090F300D3A35B /* Project object */;
438 | }
439 |
--------------------------------------------------------------------------------
/ComposableDependencies/ComposableDependencies.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 60;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | A00825C92B9617DD002EBCDF /* ComposableDependenciesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A00825C82B9617DD002EBCDF /* ComposableDependenciesApp.swift */; };
11 | A00825CB2B9617DD002EBCDF /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A00825CA2B9617DD002EBCDF /* ContentView.swift */; };
12 | A00825CD2B9617DF002EBCDF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A00825CC2B9617DF002EBCDF /* Assets.xcassets */; };
13 | A00825D12B9617DF002EBCDF /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A00825D02B9617DF002EBCDF /* Preview Assets.xcassets */; };
14 | A00825D92B9618D3002EBCDF /* ComposableArchitecture in Frameworks */ = {isa = PBXBuildFile; productRef = A00825D82B9618D3002EBCDF /* ComposableArchitecture */; };
15 | A0107A682BA1979900D3A35B /* ReducerReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0107A672BA1979900D3A35B /* ReducerReader.swift */; };
16 | A07AFD3C2B986768004954C9 /* Features.swift in Sources */ = {isa = PBXBuildFile; fileRef = A07AFD3B2B986768004954C9 /* Features.swift */; };
17 | A0A7D8792B9759B8001CE244 /* Dependencies.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A7D8782B9759B8001CE244 /* Dependencies.swift */; };
18 | A0A7D8822B97606B001CE244 /* SharedDependencies in Frameworks */ = {isa = PBXBuildFile; productRef = A0A7D8812B97606B001CE244 /* SharedDependencies */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXFileReference section */
22 | A00825C52B9617DD002EBCDF /* ComposableDependencies.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ComposableDependencies.app; sourceTree = BUILT_PRODUCTS_DIR; };
23 | A00825C82B9617DD002EBCDF /* ComposableDependenciesApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposableDependenciesApp.swift; sourceTree = ""; };
24 | A00825CA2B9617DD002EBCDF /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
25 | A00825CC2B9617DF002EBCDF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
26 | A00825CE2B9617DF002EBCDF /* ComposableDependencies.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ComposableDependencies.entitlements; sourceTree = ""; };
27 | A00825D02B9617DF002EBCDF /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
28 | A0107A672BA1979900D3A35B /* ReducerReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReducerReader.swift; sourceTree = ""; };
29 | A07AFD3B2B986768004954C9 /* Features.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Features.swift; sourceTree = ""; };
30 | A0A7D8782B9759B8001CE244 /* Dependencies.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dependencies.swift; sourceTree = ""; };
31 | /* End PBXFileReference section */
32 |
33 | /* Begin PBXFrameworksBuildPhase section */
34 | A00825C22B9617DD002EBCDF /* Frameworks */ = {
35 | isa = PBXFrameworksBuildPhase;
36 | buildActionMask = 2147483647;
37 | files = (
38 | A0A7D8822B97606B001CE244 /* SharedDependencies in Frameworks */,
39 | A00825D92B9618D3002EBCDF /* ComposableArchitecture in Frameworks */,
40 | );
41 | runOnlyForDeploymentPostprocessing = 0;
42 | };
43 | /* End PBXFrameworksBuildPhase section */
44 |
45 | /* Begin PBXGroup section */
46 | A00825BC2B9617DD002EBCDF = {
47 | isa = PBXGroup;
48 | children = (
49 | A00825C72B9617DD002EBCDF /* ComposableDependencies */,
50 | A00825C62B9617DD002EBCDF /* Products */,
51 | );
52 | sourceTree = "";
53 | };
54 | A00825C62B9617DD002EBCDF /* Products */ = {
55 | isa = PBXGroup;
56 | children = (
57 | A00825C52B9617DD002EBCDF /* ComposableDependencies.app */,
58 | );
59 | name = Products;
60 | sourceTree = "";
61 | };
62 | A00825C72B9617DD002EBCDF /* ComposableDependencies */ = {
63 | isa = PBXGroup;
64 | children = (
65 | A0107A662BA1978B00D3A35B /* ReducerReader */,
66 | A00825C82B9617DD002EBCDF /* ComposableDependenciesApp.swift */,
67 | A00825CA2B9617DD002EBCDF /* ContentView.swift */,
68 | A00825CC2B9617DF002EBCDF /* Assets.xcassets */,
69 | A00825CE2B9617DF002EBCDF /* ComposableDependencies.entitlements */,
70 | A00825CF2B9617DF002EBCDF /* Preview Content */,
71 | A0A7D8782B9759B8001CE244 /* Dependencies.swift */,
72 | A07AFD3B2B986768004954C9 /* Features.swift */,
73 | );
74 | path = ComposableDependencies;
75 | sourceTree = "";
76 | };
77 | A00825CF2B9617DF002EBCDF /* Preview Content */ = {
78 | isa = PBXGroup;
79 | children = (
80 | A00825D02B9617DF002EBCDF /* Preview Assets.xcassets */,
81 | );
82 | path = "Preview Content";
83 | sourceTree = "";
84 | };
85 | A0107A662BA1978B00D3A35B /* ReducerReader */ = {
86 | isa = PBXGroup;
87 | children = (
88 | A0107A672BA1979900D3A35B /* ReducerReader.swift */,
89 | );
90 | path = ReducerReader;
91 | sourceTree = "";
92 | };
93 | /* End PBXGroup section */
94 |
95 | /* Begin PBXNativeTarget section */
96 | A00825C42B9617DD002EBCDF /* ComposableDependencies */ = {
97 | isa = PBXNativeTarget;
98 | buildConfigurationList = A00825D42B9617DF002EBCDF /* Build configuration list for PBXNativeTarget "ComposableDependencies" */;
99 | buildPhases = (
100 | A00825C12B9617DD002EBCDF /* Sources */,
101 | A00825C22B9617DD002EBCDF /* Frameworks */,
102 | A00825C32B9617DD002EBCDF /* Resources */,
103 | );
104 | buildRules = (
105 | );
106 | dependencies = (
107 | );
108 | name = ComposableDependencies;
109 | packageProductDependencies = (
110 | A00825D82B9618D3002EBCDF /* ComposableArchitecture */,
111 | A0A7D8812B97606B001CE244 /* SharedDependencies */,
112 | );
113 | productName = ComposableDependencies;
114 | productReference = A00825C52B9617DD002EBCDF /* ComposableDependencies.app */;
115 | productType = "com.apple.product-type.application";
116 | };
117 | /* End PBXNativeTarget section */
118 |
119 | /* Begin PBXProject section */
120 | A00825BD2B9617DD002EBCDF /* Project object */ = {
121 | isa = PBXProject;
122 | attributes = {
123 | BuildIndependentTargetsInParallel = 1;
124 | LastSwiftUpdateCheck = 1520;
125 | LastUpgradeCheck = 1520;
126 | TargetAttributes = {
127 | A00825C42B9617DD002EBCDF = {
128 | CreatedOnToolsVersion = 15.2;
129 | };
130 | };
131 | };
132 | buildConfigurationList = A00825C02B9617DD002EBCDF /* Build configuration list for PBXProject "ComposableDependencies" */;
133 | compatibilityVersion = "Xcode 14.0";
134 | developmentRegion = en;
135 | hasScannedForEncodings = 0;
136 | knownRegions = (
137 | en,
138 | Base,
139 | );
140 | mainGroup = A00825BC2B9617DD002EBCDF;
141 | packageReferences = (
142 | A00825D72B9618D3002EBCDF /* XCRemoteSwiftPackageReference "swift-composable-architecture" */,
143 | A0A7D8802B97606B001CE244 /* XCLocalSwiftPackageReference "../SharedDependencies" */,
144 | );
145 | productRefGroup = A00825C62B9617DD002EBCDF /* Products */;
146 | projectDirPath = "";
147 | projectRoot = "";
148 | targets = (
149 | A00825C42B9617DD002EBCDF /* ComposableDependencies */,
150 | );
151 | };
152 | /* End PBXProject section */
153 |
154 | /* Begin PBXResourcesBuildPhase section */
155 | A00825C32B9617DD002EBCDF /* Resources */ = {
156 | isa = PBXResourcesBuildPhase;
157 | buildActionMask = 2147483647;
158 | files = (
159 | A00825D12B9617DF002EBCDF /* Preview Assets.xcassets in Resources */,
160 | A00825CD2B9617DF002EBCDF /* Assets.xcassets in Resources */,
161 | );
162 | runOnlyForDeploymentPostprocessing = 0;
163 | };
164 | /* End PBXResourcesBuildPhase section */
165 |
166 | /* Begin PBXSourcesBuildPhase section */
167 | A00825C12B9617DD002EBCDF /* Sources */ = {
168 | isa = PBXSourcesBuildPhase;
169 | buildActionMask = 2147483647;
170 | files = (
171 | A07AFD3C2B986768004954C9 /* Features.swift in Sources */,
172 | A0A7D8792B9759B8001CE244 /* Dependencies.swift in Sources */,
173 | A0107A682BA1979900D3A35B /* ReducerReader.swift in Sources */,
174 | A00825CB2B9617DD002EBCDF /* ContentView.swift in Sources */,
175 | A00825C92B9617DD002EBCDF /* ComposableDependenciesApp.swift in Sources */,
176 | );
177 | runOnlyForDeploymentPostprocessing = 0;
178 | };
179 | /* End PBXSourcesBuildPhase section */
180 |
181 | /* Begin XCBuildConfiguration section */
182 | A00825D22B9617DF002EBCDF /* Debug */ = {
183 | isa = XCBuildConfiguration;
184 | buildSettings = {
185 | ALWAYS_SEARCH_USER_PATHS = NO;
186 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
187 | CLANG_ANALYZER_NONNULL = YES;
188 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
189 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
190 | CLANG_ENABLE_MODULES = YES;
191 | CLANG_ENABLE_OBJC_ARC = YES;
192 | CLANG_ENABLE_OBJC_WEAK = YES;
193 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
194 | CLANG_WARN_BOOL_CONVERSION = YES;
195 | CLANG_WARN_COMMA = YES;
196 | CLANG_WARN_CONSTANT_CONVERSION = YES;
197 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
198 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
199 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
200 | CLANG_WARN_EMPTY_BODY = YES;
201 | CLANG_WARN_ENUM_CONVERSION = YES;
202 | CLANG_WARN_INFINITE_RECURSION = YES;
203 | CLANG_WARN_INT_CONVERSION = YES;
204 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
205 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
206 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
207 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
208 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
209 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
210 | CLANG_WARN_STRICT_PROTOTYPES = YES;
211 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
212 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
213 | CLANG_WARN_UNREACHABLE_CODE = YES;
214 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
215 | COPY_PHASE_STRIP = NO;
216 | DEBUG_INFORMATION_FORMAT = dwarf;
217 | ENABLE_STRICT_OBJC_MSGSEND = YES;
218 | ENABLE_TESTABILITY = YES;
219 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
220 | GCC_C_LANGUAGE_STANDARD = gnu17;
221 | GCC_DYNAMIC_NO_PIC = NO;
222 | GCC_NO_COMMON_BLOCKS = YES;
223 | GCC_OPTIMIZATION_LEVEL = 0;
224 | GCC_PREPROCESSOR_DEFINITIONS = (
225 | "DEBUG=1",
226 | "$(inherited)",
227 | );
228 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
229 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
230 | GCC_WARN_UNDECLARED_SELECTOR = YES;
231 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
232 | GCC_WARN_UNUSED_FUNCTION = YES;
233 | GCC_WARN_UNUSED_VARIABLE = YES;
234 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
235 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
236 | MTL_FAST_MATH = YES;
237 | ONLY_ACTIVE_ARCH = YES;
238 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
239 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
240 | SWIFT_STRICT_CONCURRENCY = complete;
241 | };
242 | name = Debug;
243 | };
244 | A00825D32B9617DF002EBCDF /* Release */ = {
245 | isa = XCBuildConfiguration;
246 | buildSettings = {
247 | ALWAYS_SEARCH_USER_PATHS = NO;
248 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
249 | CLANG_ANALYZER_NONNULL = YES;
250 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
251 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
252 | CLANG_ENABLE_MODULES = YES;
253 | CLANG_ENABLE_OBJC_ARC = YES;
254 | CLANG_ENABLE_OBJC_WEAK = YES;
255 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
256 | CLANG_WARN_BOOL_CONVERSION = YES;
257 | CLANG_WARN_COMMA = YES;
258 | CLANG_WARN_CONSTANT_CONVERSION = YES;
259 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
260 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
261 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
262 | CLANG_WARN_EMPTY_BODY = YES;
263 | CLANG_WARN_ENUM_CONVERSION = YES;
264 | CLANG_WARN_INFINITE_RECURSION = YES;
265 | CLANG_WARN_INT_CONVERSION = YES;
266 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
267 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
268 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
269 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
270 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
271 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
272 | CLANG_WARN_STRICT_PROTOTYPES = YES;
273 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
274 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
275 | CLANG_WARN_UNREACHABLE_CODE = YES;
276 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
277 | COPY_PHASE_STRIP = NO;
278 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
279 | ENABLE_NS_ASSERTIONS = NO;
280 | ENABLE_STRICT_OBJC_MSGSEND = YES;
281 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
282 | GCC_C_LANGUAGE_STANDARD = gnu17;
283 | GCC_NO_COMMON_BLOCKS = YES;
284 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
285 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
286 | GCC_WARN_UNDECLARED_SELECTOR = YES;
287 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
288 | GCC_WARN_UNUSED_FUNCTION = YES;
289 | GCC_WARN_UNUSED_VARIABLE = YES;
290 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
291 | MTL_ENABLE_DEBUG_INFO = NO;
292 | MTL_FAST_MATH = YES;
293 | SWIFT_COMPILATION_MODE = wholemodule;
294 | SWIFT_STRICT_CONCURRENCY = complete;
295 | };
296 | name = Release;
297 | };
298 | A00825D52B9617DF002EBCDF /* Debug */ = {
299 | isa = XCBuildConfiguration;
300 | buildSettings = {
301 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
302 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
303 | CODE_SIGN_ENTITLEMENTS = ComposableDependencies/ComposableDependencies.entitlements;
304 | CODE_SIGN_STYLE = Automatic;
305 | CURRENT_PROJECT_VERSION = 1;
306 | DEVELOPMENT_ASSET_PATHS = "\"ComposableDependencies/Preview Content\"";
307 | DEVELOPMENT_TEAM = 79L7M968L6;
308 | ENABLE_HARDENED_RUNTIME = YES;
309 | ENABLE_PREVIEWS = YES;
310 | GENERATE_INFOPLIST_FILE = YES;
311 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
312 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
313 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
314 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES;
315 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES;
316 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES;
317 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault;
318 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
319 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
320 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
321 | IPHONEOS_DEPLOYMENT_TARGET = 17.2;
322 | LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
323 | "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
324 | MACOSX_DEPLOYMENT_TARGET = 14.2;
325 | MARKETING_VERSION = 1.0;
326 | PRODUCT_BUNDLE_IDENTIFIER = dev.lucasvandongen.ComposableDependencies;
327 | PRODUCT_NAME = "$(TARGET_NAME)";
328 | SDKROOT = auto;
329 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
330 | SWIFT_EMIT_LOC_STRINGS = YES;
331 | SWIFT_VERSION = 5.0;
332 | TARGETED_DEVICE_FAMILY = "1,2";
333 | };
334 | name = Debug;
335 | };
336 | A00825D62B9617DF002EBCDF /* Release */ = {
337 | isa = XCBuildConfiguration;
338 | buildSettings = {
339 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
340 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
341 | CODE_SIGN_ENTITLEMENTS = ComposableDependencies/ComposableDependencies.entitlements;
342 | CODE_SIGN_STYLE = Automatic;
343 | CURRENT_PROJECT_VERSION = 1;
344 | DEVELOPMENT_ASSET_PATHS = "\"ComposableDependencies/Preview Content\"";
345 | DEVELOPMENT_TEAM = 79L7M968L6;
346 | ENABLE_HARDENED_RUNTIME = YES;
347 | ENABLE_PREVIEWS = YES;
348 | GENERATE_INFOPLIST_FILE = YES;
349 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
350 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
351 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
352 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES;
353 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES;
354 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES;
355 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault;
356 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
357 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
358 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
359 | IPHONEOS_DEPLOYMENT_TARGET = 17.2;
360 | LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
361 | "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
362 | MACOSX_DEPLOYMENT_TARGET = 14.2;
363 | MARKETING_VERSION = 1.0;
364 | PRODUCT_BUNDLE_IDENTIFIER = dev.lucasvandongen.ComposableDependencies;
365 | PRODUCT_NAME = "$(TARGET_NAME)";
366 | SDKROOT = auto;
367 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
368 | SWIFT_EMIT_LOC_STRINGS = YES;
369 | SWIFT_VERSION = 5.0;
370 | TARGETED_DEVICE_FAMILY = "1,2";
371 | };
372 | name = Release;
373 | };
374 | /* End XCBuildConfiguration section */
375 |
376 | /* Begin XCConfigurationList section */
377 | A00825C02B9617DD002EBCDF /* Build configuration list for PBXProject "ComposableDependencies" */ = {
378 | isa = XCConfigurationList;
379 | buildConfigurations = (
380 | A00825D22B9617DF002EBCDF /* Debug */,
381 | A00825D32B9617DF002EBCDF /* Release */,
382 | );
383 | defaultConfigurationIsVisible = 0;
384 | defaultConfigurationName = Release;
385 | };
386 | A00825D42B9617DF002EBCDF /* Build configuration list for PBXNativeTarget "ComposableDependencies" */ = {
387 | isa = XCConfigurationList;
388 | buildConfigurations = (
389 | A00825D52B9617DF002EBCDF /* Debug */,
390 | A00825D62B9617DF002EBCDF /* Release */,
391 | );
392 | defaultConfigurationIsVisible = 0;
393 | defaultConfigurationName = Release;
394 | };
395 | /* End XCConfigurationList section */
396 |
397 | /* Begin XCLocalSwiftPackageReference section */
398 | A0A7D8802B97606B001CE244 /* XCLocalSwiftPackageReference "../SharedDependencies" */ = {
399 | isa = XCLocalSwiftPackageReference;
400 | relativePath = ../SharedDependencies;
401 | };
402 | /* End XCLocalSwiftPackageReference section */
403 |
404 | /* Begin XCRemoteSwiftPackageReference section */
405 | A00825D72B9618D3002EBCDF /* XCRemoteSwiftPackageReference "swift-composable-architecture" */ = {
406 | isa = XCRemoteSwiftPackageReference;
407 | repositoryURL = "https://github.com/pointfreeco/swift-composable-architecture";
408 | requirement = {
409 | kind = upToNextMajorVersion;
410 | minimumVersion = 1.9.1;
411 | };
412 | };
413 | /* End XCRemoteSwiftPackageReference section */
414 |
415 | /* Begin XCSwiftPackageProductDependency section */
416 | A00825D82B9618D3002EBCDF /* ComposableArchitecture */ = {
417 | isa = XCSwiftPackageProductDependency;
418 | package = A00825D72B9618D3002EBCDF /* XCRemoteSwiftPackageReference "swift-composable-architecture" */;
419 | productName = ComposableArchitecture;
420 | };
421 | A0A7D8812B97606B001CE244 /* SharedDependencies */ = {
422 | isa = XCSwiftPackageProductDependency;
423 | productName = SharedDependencies;
424 | };
425 | /* End XCSwiftPackageProductDependency section */
426 | };
427 | rootObject = A00825BD2B9617DD002EBCDF /* Project object */;
428 | }
429 |
--------------------------------------------------------------------------------