-
Notifications
You must be signed in to change notification settings - Fork 0
/
EnumListController.swift
134 lines (104 loc) · 4.08 KB
/
EnumListController.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//
// EnumListController.swift
// BlogShowcase
//
// Created by ios_dev on 2020/11/09.
// Copyright © 2020 wonkwh. All rights reserved.
//
import UIKit
enum DataState {
case loading
case paging([Result])
case populated([Result])
case empty
case error(Error)
var currentResults: [Result] {
switch self {
case .paging(let results):
return results
case .populated(let results):
return results
default:
return []
}
}
}
class EnumListController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
fileprivate let cellId = "cellId"
fileprivate let footerId = "footerId"
var state = DataState.loading {
didSet {
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
collectionView.backgroundColor = .white
collectionView.register(ListCell.self, forCellWithReuseIdentifier: cellId)
collectionView.register(LoadingFooter.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: footerId)
fetchData()
}
fileprivate let searchTerm = "BTS"
fileprivate func fetchData() {
state = .loading
let urlString = "https://itunes.apple.com/search?term=\(searchTerm)&offset=0&limit=20"
Service.shared.fetchGenericJSONData(urlString: urlString) { (searchResult: SearchResult?, err) in
if let err = err {
print("Failed to paginate data:", err)
return
}
if let results = searchResult?.results {
self.state = .populated(results)
} else {
self.state = .empty
}
}
}
fileprivate func loadPage() {
state = .paging(state.currentResults)
let urlString = "https://itunes.apple.com/search?term=\(searchTerm)&offset=\(state.currentResults.count)&limit=20"
Service.shared.fetchGenericJSONData(urlString: urlString) { (searchResult: SearchResult?, err) in
if let err = err {
self.state = .error(err)
return
}
if searchResult?.results.count == 0 {
self.state = .empty
return
}
sleep(2)
var allResults = self.state.currentResults
allResults += searchResult?.results ?? []
self.state = .populated(allResults)
}
}
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let footer = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: footerId, for: indexPath)
return footer
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
var height: CGFloat = 0
if case .paging(_) = state {
height = 100
}
return .init(width: view.frame.width, height: height)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return state.currentResults.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! ListCell
let track = state.currentResults[indexPath.item]
cell.configure(viewData: track)
if case .populated(_) = state,
indexPath.item == state.currentResults.count - 1 {
loadPage()
}
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return .init(width: view.frame.width, height: 100)
}
}