diff --git a/.gitignore b/.gitignore index a4b4a496..3f31654b 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ playground.xcworkspace # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. # Packages/ # Package.pins +Package.resolved .build/ # CocoaPods diff --git a/0068/ComposableArchitecture.playground/Contents.swift b/0068/ComposableArchitecture.playground/Contents.swift deleted file mode 100644 index 290fa72e..00000000 --- a/0068/ComposableArchitecture.playground/Contents.swift +++ /dev/null @@ -1,163 +0,0 @@ -import Combine -import SwiftUI - -class AppState: ObservableObject { - @Published var count = 0 - @Published var favoritePrimes: [Int] = [] - @Published var loggedInUser: User? - @Published var activityFeed: [Activity] = [] - - struct Activity { - let timestamp: Date - let type: ActivityType - - enum ActivityType { - case addedFavoritePrime(Int) - case removedFavoritePrime(Int) - } - } - - struct User { - let id: Int - let name: String - let bio: String - } -} - -struct FavoritePrimesState { - var favoritePrimes: [Int] - var activityFeed: [AppState.Activity] -} - -extension AppState { - var favoritePrimesState: FavoritePrimesState { - get { - FavoritePrimesState( - favoritePrimes: self.favoritePrimes, - activityFeed: self.activityFeed - ) - } - set { - self.favoritePrimes = newValue.favoritePrimes - self.activityFeed = newValue.activityFeed - } - } -} - -struct PrimeAlert: Identifiable { - let prime: Int - var id: Int { self.prime } -} - -struct CounterView: View { - @ObservedObject var state: AppState - @State var isPrimeModalShown = false - @State var alertNthPrime: PrimeAlert? - @State var isNthPrimeButtonDisabled = false - - var body: some View { - VStack { - HStack { - Button("-") { self.state.count -= 1 } - Text("\(self.state.count)") - Button("+") { self.state.count += 1 } - } - Button("Is this prime?") { self.isPrimeModalShown = true } - Button( - "What is the \(ordinal(self.state.count)) prime?", - action: self.nthPrimeButtonAction - ) - .disabled(self.isNthPrimeButtonDisabled) - } - .font(.title) - .navigationBarTitle("Counter demo") - .sheet(isPresented: self.$isPrimeModalShown) { - IsPrimeModalView(state: self.state) - } - .alert(item: self.$alertNthPrime) { alert in - Alert( - title: Text("The \(ordinal(self.state.count)) prime is \(alert.prime)"), - dismissButton: .default(Text("Ok")) - ) - } - } - - func nthPrimeButtonAction() { - self.isNthPrimeButtonDisabled = true - nthPrime(self.state.count) { prime in - self.alertNthPrime = prime.map(PrimeAlert.init(prime:)) - self.isNthPrimeButtonDisabled = false - } - } -} - -struct IsPrimeModalView: View { - @ObservedObject var state: AppState - - var body: some View { - VStack { - if isPrime(self.state.count) { - Text("\(self.state.count) is prime 🎉") - if self.state.favoritePrimes.contains(self.state.count) { - Button("Remove from favorite primes") { - self.state.favoritePrimes.removeAll(where: { $0 == self.state.count }) - self.state.activityFeed.append(.init(timestamp: Date(), type: .removedFavoritePrime(self.state.count))) - } - } else { - Button("Save to favorite primes") { - self.state.favoritePrimes.append(self.state.count) - self.state.activityFeed.append(.init(timestamp: Date(), type: .addedFavoritePrime(self.state.count))) - - } - } - } else { - Text("\(self.state.count) is not prime :(") - } - } - } -} - -struct FavoritePrimesView: View { - @Binding var state: FavoritePrimesState - - var body: some View { - List { - ForEach(self.state.favoritePrimes, id: \.self) { prime in - Text("\(prime)") - } - .onDelete { indexSet in - for index in indexSet { - let prime = self.state.favoritePrimes[index] - self.state.favoritePrimes.remove(at: index) - self.state.activityFeed.append(.init(timestamp: Date(), type: .removedFavoritePrime(prime))) - } - } - } - .navigationBarTitle("Favorite Primes") - } -} - -struct ContentView: View { - @ObservedObject var state: AppState - - var body: some View { - NavigationView { - List { - NavigationLink( - "Counter demo", - destination: CounterView(state: self.state) - ) - NavigationLink( - "Favorite primes", - destination: FavoritePrimesView(state: self.$state.favoritePrimesState) - ) - } - .navigationBarTitle("State management") - } - } -} - -import PlaygroundSupport -PlaygroundPage.current.liveView = UIHostingController( - rootView: ContentView(state: AppState()) -) diff --git a/ComposableArchitecture/ComposableArchitecture.playground/Contents.swift b/ComposableArchitecture/ComposableArchitecture.playground/Contents.swift new file mode 100644 index 00000000..e69de29b diff --git a/0068/ComposableArchitecture.playground/Sources/Util.swift b/ComposableArchitecture/ComposableArchitecture.playground/Sources/Util.swift similarity index 100% rename from 0068/ComposableArchitecture.playground/Sources/Util.swift rename to ComposableArchitecture/ComposableArchitecture.playground/Sources/Util.swift diff --git a/0068/ComposableArchitecture.playground/contents.xcplayground b/ComposableArchitecture/ComposableArchitecture.playground/contents.xcplayground similarity index 100% rename from 0068/ComposableArchitecture.playground/contents.xcplayground rename to ComposableArchitecture/ComposableArchitecture.playground/contents.xcplayground diff --git a/ComposableArchitecture/Package.swift b/ComposableArchitecture/Package.swift new file mode 100644 index 00000000..89f8b7a3 --- /dev/null +++ b/ComposableArchitecture/Package.swift @@ -0,0 +1,9 @@ +// swift-tools-version:4.2 +import PackageDescription + +let package = Package( + name: "ComposableArchitecture", + dependencies: [ + .package(url: "https://github.com/pointfreeco/swift-enum-properties.git", from: "0.1.0") + ] +)