Skip to content

Commit

Permalink
243
Browse files Browse the repository at this point in the history
  • Loading branch information
stephencelis committed Aug 1, 2023
1 parent 14a095e commit 68eb460
Showing 15 changed files with 949 additions and 0 deletions.
503 changes: 503 additions & 0 deletions 0243-tca-tour-pt1/Counter/Counter.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1500"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CA6D661A2A66D3D000B2A77A"
BuildableName = "Counter.app"
BlueprintName = "Counter"
ReferencedContainer = "container:Counter.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<TestPlans>
<TestPlanReference
reference = "container:CounterTests/Counter.xctestplan"
default = "YES">
</TestPlanReference>
</TestPlans>
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CA6D662A2A66D3D300B2A77A"
BuildableName = "CounterTests.xctest"
BlueprintName = "CounterTests"
ReferencedContainer = "container:Counter.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CA6D66342A66D3D300B2A77A"
BuildableName = "CounterUITests.xctest"
BlueprintName = "CounterUITests"
ReferencedContainer = "container:Counter.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CA6D661A2A66D3D000B2A77A"
BuildableName = "Counter.app"
BlueprintName = "Counter"
ReferencedContainer = "container:Counter.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CA6D661A2A66D3D000B2A77A"
BuildableName = "Counter.app"
BlueprintName = "Counter"
ReferencedContainer = "container:Counter.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"images" : [
{
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
142 changes: 142 additions & 0 deletions 0243-tca-tour-pt1/Counter/Counter/ContentView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import ComposableArchitecture
import SwiftUI

struct NumberFactClient {
var fetch: @Sendable (Int) async throws -> String
}
extension NumberFactClient: DependencyKey {
static let liveValue = Self { number in
let (data, _) = try await URLSession.shared.data(
from: URL(string: "http://www.numbersapi.com/\(number)")!
)
return String(decoding: data, as: UTF8.self)
}
}
extension DependencyValues {
var numberFact: NumberFactClient {
get { self[NumberFactClient.self] }
set { self[NumberFactClient.self] = newValue }
}
}

struct CounterFeature: Reducer {
struct State: Equatable {
var count = 0
var fact: String?
var isLoadingFact = false
var isTimerOn = false
}
enum Action: Equatable {
case decrementButtonTapped
case factResponse(String)
case getFactButtonTapped
case incrementButtonTapped
case timerTicked
case toggleTimerButtonTapped
}
private enum CancelID {
case timer
}
@Dependency(\.continuousClock) var clock
@Dependency(\.numberFact) var numberFact
var body: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case .decrementButtonTapped:
state.count -= 1
state.fact = nil
return .none

case let .factResponse(fact):
state.fact = fact
state.isLoadingFact = false
return .none

case .getFactButtonTapped:
state.fact = nil
state.isLoadingFact = true
return .run { [count = state.count] send in
try await send(.factResponse(self.numberFact.fetch(count)))
}

case .incrementButtonTapped:
state.count += 1
state.fact = nil
return .none

case .timerTicked:
state.count += 1
return .none

case .toggleTimerButtonTapped:
state.isTimerOn.toggle()
if state.isTimerOn {
return .run { send in
for await _ in self.clock.timer(interval: .seconds(1)) {
await send(.timerTicked)
}
}
.cancellable(id: CancelID.timer)
} else {
return .cancel(id: CancelID.timer)
}
}
}
}
}

struct ContentView: View {
let store: StoreOf<CounterFeature>

var body: some View {
WithViewStore(self.store, observe: { $0 }) { viewStore in
Form {
Section {
Text("\(viewStore.count)")
Button("Decrement") {
viewStore.send(.decrementButtonTapped)
}
Button("Increment") {
viewStore.send(.incrementButtonTapped)
}
}
Section {
Button {
viewStore.send(.getFactButtonTapped)
} label: {
HStack {
Text("Get fact")
if viewStore.isLoadingFact {
Spacer()
ProgressView()
}
}
}
if let fact = viewStore.fact {
Text(fact)
}
}
Section {
if viewStore.isTimerOn {
Button("Stop timer") {
viewStore.send(.toggleTimerButtonTapped)
}
} else {
Button("Start timer") {
viewStore.send(.toggleTimerButtonTapped)
}
}
}
}
}
}
}

#Preview {
ContentView(
store: Store(initialState: CounterFeature.State()) {
CounterFeature()
._printChanges()
}
)
}
15 changes: 15 additions & 0 deletions 0243-tca-tour-pt1/Counter/Counter/CounterApp.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import ComposableArchitecture
import SwiftUI

@main
struct CounterApp: App {
var body: some Scene {
WindowGroup {
ContentView(
store: Store(initialState: CounterFeature.State()) {
CounterFeature()
}
)
}
}
}
11 changes: 11 additions & 0 deletions 0243-tca-tour-pt1/Counter/Counter/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
28 changes: 28 additions & 0 deletions 0243-tca-tour-pt1/Counter/CounterTests/Counter.xctestplan
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"configurations" : [
{
"id" : "8D5702CD-E99C-4230-92F1-DDEC4444A6B2",
"name" : "Test Scheme Action",
"options" : {

}
}
],
"defaultOptions" : {
"targetForVariableExpansion" : {
"containerPath" : "container:Counter.xcodeproj",
"identifier" : "CA6D661A2A66D3D000B2A77A",
"name" : "Counter"
}
},
"testTargets" : [
{
"target" : {
"containerPath" : "container:Counter.xcodeproj",
"identifier" : "CA6D662A2A66D3D300B2A77A",
"name" : "CounterTests"
}
}
],
"version" : 1
}
Loading

0 comments on commit 68eb460

Please sign in to comment.