forked from Hackingwithswift/100-days-of-swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathViewController.swift
131 lines (102 loc) · 4.58 KB
/
ViewController.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
//
// ViewController.swift
// Project9-Challenge3
//
import UIKit
class ViewController: UITableViewController {
var petitions = [Petition]()
var filteredPetitions = [Petition]()
// use empty string for no filter
var filterKeyword: String = ""
override func viewDidLoad() {
super.viewDidLoad()
let urlString: String
if navigationController?.tabBarItem.tag == 0 {
urlString = "https://api.whitehouse.gov/v1/petitions.json?limit=100"
}
else {
urlString = "https://api.whitehouse.gov/v1/petitions.json?signatureCountFloor=10000&limit=100"
}
title = "White House petitions"
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Credits", style: .plain, target: self, action: #selector(showCredits))
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Filter", style: .plain, target: self, action: #selector(askFilter))
if let url = URL(string: urlString) {
if let data = try? Data(contentsOf: url) {
parse(json: data)
return
}
}
showError()
}
@objc func showCredits() {
let ac = UIAlertController(title: "Credits", message: "Petitions from WE the PEOPLE at petitions.whitehouse.gov", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
}
@objc func askFilter() {
let ac = UIAlertController(title: "Filter", message: "Filter the petitions on the following keyword (leave empty to reset filtering)", preferredStyle: .alert)
ac.addTextField()
ac.addAction(UIAlertAction(title: "Cancel", style: .cancel))
ac.addAction(UIAlertAction(title: "OK", style: .default) {
[weak self, weak ac] _ in
self?.filterKeyword = ac?.textFields?[0].text ?? ""
// project 9 challenge 3
// no need for weak self (already weak as per above)
DispatchQueue.global().async {
self?.filterData()
DispatchQueue.main.async {
self?.tableView.reloadData()
}
}
})
present(ac, animated: true)
}
@objc func filterData() {
if filterKeyword.isEmpty {
filteredPetitions = petitions
navigationItem.leftBarButtonItem?.title = "Filter"
return
}
navigationItem.leftBarButtonItem?.title = "Filter (current: \(filterKeyword))"
// keep only petition whose title or body contains keyword
filteredPetitions = petitions.filter() { petition in
// use range instead of contains to filter in case insentive manner
// (see https://www.hackingwithswift.com/example-code/strings/how-to-run-a-case-insensitive-search-for-one-string-inside-another)
if let _ = petition.title.range(of: filterKeyword, options: .caseInsensitive) {
return true
}
if let _ = petition.body.range(of: filterKeyword, options: .caseInsensitive) {
return true
}
return false
}
}
func showError() {
let ac = UIAlertController(title: "Loading error", message: "There was a problem loading the feed; please check your connection and try again", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
}
func parse(json: Data) {
let decoder = JSONDecoder()
if let jsonPetitions = try? decoder.decode(Petitions.self, from: json) {
petitions = jsonPetitions.results
filterData()
tableView.reloadData()
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredPetitions.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let petition = filteredPetitions[indexPath.row]
cell.textLabel?.text = petition.title
cell.detailTextLabel?.text = petition.body
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = DetailViewController()
vc.detailItem = filteredPetitions[indexPath.row]
navigationController?.pushViewController(vc, animated: true)
}
}