-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add single store example. Feedback and Reduce composition. (#49)
* Add pullbacks, Store, Context, reducer composition * Add counter example * Add single store example * Add Picker example and parent child state composition * Update Example/AppDelegate.swift Co-Authored-By: Michael Brown <[email protected]> * Remove SwiftUI 🙈 * Use Xcode 11.1 * update .circleci/config.yml * Update kingsfisher * Rename to forward * Remove Kingfisher * Implement single store example with new Feedback loops * Typos Co-authored-by: Michael Brown <[email protected]> Co-authored-by: Ilya Puchka <[email protected]>
- Loading branch information
1 parent
20514bb
commit de7454c
Showing
29 changed files
with
1,295 additions
and
602 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 |
---|---|---|
@@ -1,6 +1,5 @@ | ||
# Example app. | ||
github "ReactiveCocoa/ReactiveCocoa" ~> 10.0.0 | ||
github "onevcat/Kingfisher" ~> 5.2 | ||
|
||
# Tests | ||
github "Quick/Nimble" ~> 8.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
129 changes: 129 additions & 0 deletions
129
Example/MultiStoreExample/PaginationViewController.swift
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 |
---|---|---|
@@ -0,0 +1,129 @@ | ||
import UIKit | ||
import ReactiveSwift | ||
import ReactiveCocoa | ||
import ReactiveFeedback | ||
|
||
final class PaginationViewController: UIViewController { | ||
private lazy var contentView = MoviesView.loadFromNib() | ||
private let viewModel = Movies.ViewModel() | ||
|
||
override func loadView() { | ||
self.view = contentView | ||
} | ||
|
||
override func viewDidLoad() { | ||
super.viewDidLoad() | ||
viewModel.state.producer.startWithValues(contentView.render) | ||
} | ||
} | ||
|
||
extension Movies { | ||
final class ViewModel: Store<State, Event> { | ||
init() { | ||
super.init( | ||
initial: Movies.State(), | ||
reducer: Movies.reduce, | ||
feedbacks: [Movies.feedback] | ||
) | ||
} | ||
} | ||
} | ||
|
||
// Key for https://www.themoviedb.org API | ||
let correctKey = "d4f0bdb3e246e2cb3555211e765c89e3" | ||
|
||
struct Results: Codable { | ||
let page: Int | ||
let totalResults: Int | ||
let totalPages: Int | ||
let results: [Movie] | ||
|
||
static func empty() -> Results { | ||
return Results.init(page: 0, totalResults: 0, totalPages: 0, results: []) | ||
} | ||
|
||
enum CodingKeys: String, CodingKey { | ||
case page | ||
case totalResults = "total_results" | ||
case totalPages = "total_pages" | ||
case results | ||
} | ||
} | ||
|
||
struct Movie: Codable { | ||
let id: Int | ||
let overview: String | ||
let title: String | ||
let posterPath: String? | ||
|
||
var posterURL: URL? { | ||
return posterPath | ||
.map { | ||
"https://image.tmdb.org/t/p/w342/\($0)" | ||
} | ||
.flatMap(URL.init(string:)) | ||
} | ||
|
||
enum CodingKeys: String, CodingKey { | ||
case id | ||
case overview | ||
case title | ||
case posterPath = "poster_path" | ||
} | ||
} | ||
|
||
extension URLSession { | ||
func fetchMovies(page: Int) -> SignalProducer<Results, NSError> { | ||
return SignalProducer.init({ (observer, lifetime) in | ||
let url = URL(string: "https://api.themoviedb.org/3/discover/movie?api_key=\(correctKey)&sort_by=popularity.desc&page=\(page)")! | ||
let task = self.dataTask(with: url, completionHandler: { (data, response, error) in | ||
if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 401 { | ||
let error = NSError(domain: "come.reactivefeedback", | ||
code: 401, | ||
userInfo: [NSLocalizedDescriptionKey: "Forced failure to illustrate Retry"]) | ||
observer.send(error: error) | ||
} else if let data = data { | ||
do { | ||
let results = try JSONDecoder().decode(Results.self, from: data) | ||
observer.send(value: results) | ||
} catch { | ||
observer.send(error: error as NSError) | ||
} | ||
} else if let error = error { | ||
observer.send(error: error as NSError) | ||
observer.sendCompleted() | ||
} else { | ||
observer.sendCompleted() | ||
} | ||
}) | ||
|
||
lifetime += AnyDisposable(task.cancel) | ||
task.resume() | ||
}) | ||
} | ||
} | ||
|
||
final class ArrayCollectionViewDataSource<T>: NSObject, UICollectionViewDataSource { | ||
typealias CellFactory = (UICollectionView, IndexPath, T) -> UICollectionViewCell | ||
|
||
private(set) var items: [T] = [] | ||
var cellFactory: CellFactory! | ||
|
||
func update(with items: [T]) { | ||
self.items = items | ||
} | ||
|
||
func item(atIndexPath indexPath: IndexPath) -> T { | ||
return items[indexPath.row] | ||
} | ||
|
||
// MARK: UICollectionViewDataSource | ||
|
||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { | ||
return items.count | ||
} | ||
|
||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { | ||
return cellFactory(collectionView, indexPath, item(atIndexPath: indexPath)) | ||
} | ||
} |
File renamed without changes.
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 |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import UIKit | ||
import ReactiveSwift | ||
import ReactiveCocoa | ||
import ReactiveFeedback | ||
|
||
class ViewController: UIViewController { | ||
@IBOutlet weak var plusButton: UIButton! | ||
@IBOutlet weak var minusButton: UIButton! | ||
@IBOutlet weak var label: UILabel! | ||
private lazy var contentView = CounterView.loadFromNib() | ||
private let viewModel = Counter.ViewModel() | ||
|
||
override func loadView() { | ||
self.view = contentView | ||
} | ||
|
||
override func viewDidLoad() { | ||
super.viewDidLoad() | ||
viewModel.state.producer.startWithValues(contentView.render) | ||
} | ||
} | ||
|
||
extension Counter { | ||
final class ViewModel: Store<State, Event> { | ||
init() { | ||
super.init( | ||
initial: State(), | ||
reducer: Counter.reduce, | ||
feedbacks: [] | ||
) | ||
} | ||
} | ||
} |
Oops, something went wrong.