-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
26 changed files
with
796 additions
and
680 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ | |
252BF08422BAE05700BC4265 /* SignIn.swift in Sources */ = {isa = PBXBuildFile; fileRef = 252BF08322BAE05700BC4265 /* SignIn.swift */; }; | ||
253D324122B185FA002F3B7F /* ViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 253D323F22B1858C002F3B7F /* ViewContext.swift */; }; | ||
254B4DB726755AE200653BB8 /* StoreBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 254B4DB626755AE200653BB8 /* StoreBox.swift */; }; | ||
254B4DBA2676650000653BB8 /* CombineSchedulers in Frameworks */ = {isa = PBXBuildFile; productRef = 254B4DB92676650000653BB8 /* CombineSchedulers */; }; | ||
25C57B2C22BC2C33007CB4D6 /* Activity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25C57B2B22BC2C33007CB4D6 /* Activity.swift */; }; | ||
25EBC08C23FD61B100719826 /* Reducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 585CD878239AC7D3004BE9CC /* Reducer.swift */; }; | ||
25F23C2922CA984E00894863 /* TrafficLight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F23C2822CA984E00894863 /* TrafficLight.swift */; }; | ||
|
@@ -195,6 +196,7 @@ | |
isa = PBXFrameworksBuildPhase; | ||
buildActionMask = 2147483647; | ||
files = ( | ||
254B4DBA2676650000653BB8 /* CombineSchedulers in Frameworks */, | ||
5822A2302434FEB400270514 /* CasePaths in Frameworks */, | ||
); | ||
runOnlyForDeploymentPostprocessing = 0; | ||
|
@@ -307,8 +309,8 @@ | |
5800FFAB22A89C08005A860B /* FlatMapLatest.swift */, | ||
58751A9523EC823C00EEF398 /* Atomic.swift */, | ||
5800FFAC22A89C08005A860B /* System.swift */, | ||
5800FF9422A89BE6005A860B /* Info.plist */, | ||
585CD878239AC7D3004BE9CC /* Reducer.swift */, | ||
5800FF9422A89BE6005A860B /* Info.plist */, | ||
); | ||
path = CombineFeedback; | ||
sourceTree = "<group>"; | ||
|
@@ -522,6 +524,7 @@ | |
name = CombineFeedback; | ||
packageProductDependencies = ( | ||
5822A22F2434FEB400270514 /* CasePaths */, | ||
254B4DB92676650000653BB8 /* CombineSchedulers */, | ||
); | ||
productName = CombineFeedback; | ||
productReference = 5800FF9022A89BE6005A860B /* CombineFeedback.framework */; | ||
|
@@ -669,6 +672,7 @@ | |
mainGroup = 5800FF8622A89BE6005A860B; | ||
packageReferences = ( | ||
5822A22E2434FEB400270514 /* XCRemoteSwiftPackageReference "swift-case-paths" */, | ||
254B4DB82676650000653BB8 /* XCRemoteSwiftPackageReference "combine-schedulers" */, | ||
); | ||
productRefGroup = 5800FF9122A89BE6005A860B /* Products */; | ||
projectDirPath = ""; | ||
|
@@ -1165,6 +1169,7 @@ | |
DEVELOPMENT_TEAM = 3JZ7RUJD4Q; | ||
ENABLE_PREVIEWS = YES; | ||
INFOPLIST_FILE = Example/Info.plist; | ||
IPHONEOS_DEPLOYMENT_TARGET = 15.0; | ||
LD_RUNPATH_SEARCH_PATHS = ( | ||
"$(inherited)", | ||
"@executable_path/Frameworks", | ||
|
@@ -1186,6 +1191,7 @@ | |
DEVELOPMENT_TEAM = 3JZ7RUJD4Q; | ||
ENABLE_PREVIEWS = YES; | ||
INFOPLIST_FILE = Example/Info.plist; | ||
IPHONEOS_DEPLOYMENT_TARGET = 15.0; | ||
LD_RUNPATH_SEARCH_PATHS = ( | ||
"$(inherited)", | ||
"@executable_path/Frameworks", | ||
|
@@ -1306,17 +1312,30 @@ | |
/* End XCConfigurationList section */ | ||
|
||
/* Begin XCRemoteSwiftPackageReference section */ | ||
254B4DB82676650000653BB8 /* XCRemoteSwiftPackageReference "combine-schedulers" */ = { | ||
isa = XCRemoteSwiftPackageReference; | ||
repositoryURL = "https://github.com/pointfreeco/combine-schedulers.git"; | ||
requirement = { | ||
kind = upToNextMajorVersion; | ||
minimumVersion = 0.5.0; | ||
}; | ||
}; | ||
5822A22E2434FEB400270514 /* XCRemoteSwiftPackageReference "swift-case-paths" */ = { | ||
isa = XCRemoteSwiftPackageReference; | ||
repositoryURL = "[email protected]:pointfreeco/swift-case-paths.git"; | ||
requirement = { | ||
kind = upToNextMajorVersion; | ||
minimumVersion = 0.1.0; | ||
minimumVersion = 0.2.0; | ||
}; | ||
}; | ||
/* End XCRemoteSwiftPackageReference section */ | ||
|
||
/* Begin XCSwiftPackageProductDependency section */ | ||
254B4DB92676650000653BB8 /* CombineSchedulers */ = { | ||
isa = XCSwiftPackageProductDependency; | ||
package = 254B4DB82676650000653BB8 /* XCRemoteSwiftPackageReference "combine-schedulers" */; | ||
productName = CombineSchedulers; | ||
}; | ||
5822A22F2434FEB400270514 /* CasePaths */ = { | ||
isa = XCSwiftPackageProductDependency; | ||
package = 5822A22E2434FEB400270514 /* XCRemoteSwiftPackageReference "swift-case-paths" */; | ||
|
20 changes: 19 additions & 1 deletion
20
CombineFeedback.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,30 @@ | ||
{ | ||
"object": { | ||
"pins": [ | ||
{ | ||
"package": "combine-schedulers", | ||
"repositoryURL": "https://github.com/pointfreeco/combine-schedulers.git", | ||
"state": { | ||
"branch": null, | ||
"revision": "c37e5ae8012fb654af776cc556ff8ae64398c841", | ||
"version": "0.5.0" | ||
} | ||
}, | ||
{ | ||
"package": "swift-case-paths", | ||
"repositoryURL": "[email protected]:pointfreeco/swift-case-paths.git", | ||
"state": { | ||
"branch": null, | ||
"revision": "a9c1e05518b6d95cf5844d823020376f2b6ff842", | ||
"revision": "a313f0cc10e07bb5ce7e2ff5da600cce7efa8e8a", | ||
"version": "0.2.0" | ||
} | ||
}, | ||
{ | ||
"package": "xctest-dynamic-overlay", | ||
"repositoryURL": "https://github.com/pointfreeco/xctest-dynamic-overlay", | ||
"state": { | ||
"branch": null, | ||
"revision": "603974e3909ad4b48ba04aad7e0ceee4f077a518", | ||
"version": "0.1.0" | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,81 +1,85 @@ | ||
import Foundation | ||
import CombineFeedback | ||
import Combine | ||
|
||
enum Movies { | ||
struct State: Equatable { | ||
var batch: Results | ||
var movies: [Movie] | ||
var status: Status | ||
struct Dependencies { | ||
var movies: (Int) async throws -> Results | ||
var fetchMovies: (Int) -> AnyPublisher<Results, NSError> | ||
} | ||
|
||
var nextPage: Int? { | ||
switch status { | ||
case .loading: | ||
return batch.page + 1 | ||
case .failed: | ||
return nil | ||
case .idle: | ||
return nil | ||
} | ||
} | ||
struct State: Equatable { | ||
var batch: Results | ||
var movies: [Movie] | ||
var status: Status | ||
|
||
var error: NSError? { | ||
switch status { | ||
case .failed(let error): | ||
return error | ||
default: | ||
return nil | ||
} | ||
} | ||
var nextPage: Int? { | ||
switch status { | ||
case .loading: | ||
return batch.page + 1 | ||
case .failed: | ||
return nil | ||
case .idle: | ||
return nil | ||
} | ||
} | ||
|
||
enum Status: Equatable { | ||
case idle | ||
case loading | ||
case failed(NSError) | ||
} | ||
var error: NSError? { | ||
switch status { | ||
case .failed(let error): | ||
return error | ||
default: | ||
return nil | ||
} | ||
} | ||
|
||
enum Event { | ||
case didLoad(Results) | ||
case didFail(NSError) | ||
case retry | ||
case fetchNext | ||
enum Status: Equatable { | ||
case idle | ||
case loading | ||
case failed(NSError) | ||
} | ||
} | ||
|
||
static func reducer() -> Reducer<State, Event> { | ||
.init { state, event in | ||
switch event { | ||
case .didLoad(let batch): | ||
state.movies += batch.results | ||
state.status = .idle | ||
state.batch = batch | ||
case .didFail(let error): | ||
state.status = .failed(error) | ||
case .retry: | ||
state.status = .loading | ||
case .fetchNext: | ||
state.status = .loading | ||
} | ||
} | ||
enum Event { | ||
case didLoad(Results) | ||
case didFail(NSError) | ||
case retry | ||
case fetchNext | ||
} | ||
|
||
static func reducer() -> Reducer<State, Event> { | ||
.init { state, event in | ||
switch event { | ||
case .didLoad(let batch): | ||
state.movies += batch.results | ||
state.status = .idle | ||
state.batch = batch | ||
case .didFail(let error): | ||
state.status = .failed(error) | ||
case .retry: | ||
state.status = .loading | ||
case .fetchNext: | ||
state.status = .loading | ||
} | ||
} | ||
} | ||
|
||
static var feedback: Feedback<State, Event> { | ||
if #available(iOS 15.0, *) { | ||
return .lensing(state: \.nextPage) { page in | ||
do { | ||
return Event.didLoad(try await URLSession.shared.movies(page: page)) | ||
} catch { | ||
return Event.didFail(error as NSError) | ||
} | ||
} | ||
} else { | ||
return .lensing(state: { $0.nextPage }) { page in | ||
URLSession.shared | ||
.fetchMovies(page: page) | ||
.map(Event.didLoad) | ||
.replaceError(replace: Event.didFail) | ||
.receive(on: DispatchQueue.main) | ||
static var feedback: Feedback<State, Event, Dependencies> { | ||
if #available(iOS 15.0, *) { | ||
return .lensing(state: \.nextPage) { page, dependency in | ||
do { | ||
return Event.didLoad(try await URLSession.shared.movies(page: page)) | ||
} catch { | ||
return Event.didFail(error as NSError) | ||
} | ||
} | ||
} else { | ||
return .lensing(state: { $0.nextPage }) { page, dependency in | ||
dependency.fetchMovies(page) | ||
.map(Event.didLoad) | ||
.replaceError(replace: Event.didFail) | ||
.receive(on: DispatchQueue.main) | ||
} | ||
} | ||
|
||
} | ||
} |
Oops, something went wrong.