防止偷懶Day25

在完成註冊手續之後

接下來就是讓使用者可以新增隊伍然後在HomeController會去Fetch使用者新增過的隊伍資料

然後用tableView顯示出來

第一步先來看看目前想到在Database儲存資料的形式

User的地方是昨天處理好的部分,當使用者註冊時會將資料儲存在一個uid底下

包含了使用者的email跟name這兩項資訊

而今天要讓使用者在新增球隊資訊之後

會在Team底下創造一個tid,裡面會儲存球隊名稱的字串TeamName

以及這個team屬於哪個使用者的uid

開工第一步先來把該有的工具準備好

在Model裡面新增一個定義User這個class的new file

命名成User.swift

然後修改一下Team.swift這個class的內容

內容如下

Team.swift

1
2
3
4
5
6
import UIKit

class Team: NSObject {
var uid: String?
var teamName: String?
}

User.swift

1
2
3
4
5
6
7
import UIKit

class User: NSObject {
var name: String?
var email: String?
var uid: String?
}

然後來到要處理資料的HomeController

一樣先看看程式碼再來一步一步處理

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
import UIKit
import Firebase

class HomeController: UITableViewController {

let cellId = "cellId"
var teams = [Team]()
var user = User()

override var prefersStatusBarHidden: Bool {
return false
}

override func viewDidLoad() {
super.viewDidLoad()
let newTeamButton = UIBarButtonItem(title: "New Team", style: .plain, target: self, action: #selector(toSetNewTeamController))
navigationItem.rightBarButtonItem = newTeamButton

let logoutButton = UIBarButtonItem(title: "Logout", style: .plain, target: self, action: #selector(handleLogout))
navigationItem.leftBarButtonItem = logoutButton
checkUserIsLogin()
}

func fetchTeam() {
FIRDatabase.database().reference().child("Team").observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let team = Team()
team.setValuesForKeys(dictionary)
if team.uid == self.user.uid {
self.teams.append(team)
}

DispatchQueue.main.async {
self.tableView.reloadData()
}
print(team.teamName as Any, team.uid as Any)
}
}, withCancel: nil)
}

func checkUserIsLogin() {
if FIRAuth.auth()?.currentUser?.uid == nil {
perform(#selector(handleLogout), with: nil, afterDelay: 0)
} else {
fetchUserSetNavBarTitle()
}
}

func fetchUserSetNavBarTitle() {
guard let uid = FIRAuth.auth()?.currentUser?.uid else {
return
}
FIRDatabase.database().reference().child("User").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
print(snapshot)
if let dictionary = snapshot.value as? [String: Any] {
self.user.uid = snapshot.key
self.navigationItem.title = dictionary["name"] as? String
self.fetchTeam()
}
}, withCancel: nil)
}

func handleLogout() {

do {
try FIRAuth.auth()?.signOut()
} catch let logoutError {
print(logoutError)
}
self.teams.removeAll()
let loginController = LoginController()
loginController.homeController = self
present(loginController, animated: true, completion: nil)
}

func toSetNewTeamController() {
let alertController = UIAlertController(title: "Add New Team", message: "", preferredStyle: .alert)

let saveAction = UIAlertAction(title: "OK", style: .default, handler: {
alert -> Void in

let firstTextField = alertController.textFields![0] as UITextField
let controller = SetNewTeamController()

if firstTextField.text! != "" {
controller.teamTitle = firstTextField.text!
let uid = self.user.uid
let ref = FIRDatabase.database().reference().child("Team")
let teamRef = ref.childByAutoId()
let value: [AnyHashable: Any] = ["TeamName": firstTextField.text!, "uid": uid as Any]
teamRef.updateChildValues(value)
self.present(UINavigationController(rootViewController: controller), animated: true, completion: nil)
} else {
return
}

})

let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: {
(action : UIAlertAction!) -> Void in
})

alertController.addTextField { (textField : UITextField!) -> Void in
textField.placeholder = "Enter Team Name"
}

alertController.addAction(saveAction)
alertController.addAction(cancelAction)

self.present(alertController, animated: true, completion: nil)

}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return teams.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellId)

cell.textLabel?.text = teams[indexPath.row].teamName

return cell
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let controller = SetNewTeamController()
controller.teamTitle = teams[indexPath.row].teamName
present(UINavigationController(rootViewController: controller), animated: true, completion: nil)
}

}

第一步當然是實作讓使用者新增資料到Database上

之前在toSetNewTeamController這個function裡面實作了當使用者點擊右上方的Add Member時

會跳出一個AlertController讓使用者輸入新增球隊的名稱

在第87~91行我們讓使用者把現有的uid跟新增的teamName儲存到Database上的Team節點下

並自動產生一個id當子樹,不過這裡的uid怎麼來的?

當然我們就需要剛剛準備好的工具拉

第7, 8行實作一個teams來儲存Fetch到的Team內容

以及一個user來儲存Fetch到的User內容

接下來在fetchUserSetNavBarTitle這個function裡面第56行儲存使用者的uid

這樣就有自己的uid可以使用拉

然後就來實作Fetch隊伍資料的fetchTeam這個function

首先,fetchTeam會在fetchUserSetNavBarTitle拿到使用者的資訊之後執行

以確保自己儲存的uid不會是空值

fetchTeam執行時會去Database觀察Team這個子樹下的資料

如果裡面的uid跟現在使用者的uid是一樣的

就代表這隻Team是這個使用者所創建的

那就把這筆資料儲存到前面創好的teams裡面

最後重新整理現在的tableView內容

p.s.這裡要記得UI必須在主線程裡更新

但我們還沒處理tableView的內容

所以就修改一下numberOfRowsInSection回傳儲存的隊伍數量teams.count

以及cellForRowAt讓cell的文字顯示隊伍名稱teamName

還有didSelectRowAt所傳送的teamTitle

最後要記得處理當使用者登出時要把teams的內容移除

不然登入其他帳號時teams的內容可能還會儲存在裡面

Support

Comments

2017-07-16

⬆︎TOP