MapKit (12)
Profile View Checked In/Out 구현
현재는 어떤 가게에 들어가야만 checked in/out에 대한 정보를 확인 할 수 있다. (설령 본인일지라도)
그래서 이제는 본인이 체크인을 했다면 프로필에서 체크인 상태를 확인 및 거기서도 체크 아웃할수있게 기능을 구현해본다.
버튼 디자인
우선 ProfileView에서 체크아웃 버튼을 디자인 해보도록 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
VStack(alignment: .leading, spacing: 8) {
HStack { // new
CharactersRemainView(currentCount: viewModel.bio.count)
Spacer()
Button { // new
} label: {
Label("Check Out", systemImage: "mappin.and.ellipse")
.font(.system(size: 12, weight: .semibold))
.foregroundColor(.white)
.padding(10)
.frame(height: 28)
.background(Color.grubRed)
.cornerRadius(8)
}
}
}
우선 버튼을 하나 만들어 주었다. 버튼 디자인은 위와 같다.
그렇게해서 실행을 해보면
이렇게 우측에 작게 체크아웃 버튼이 생긴걸 알 수 있다.
체크인/아웃시 버튼 다르게 하기
계속 체크아웃버튼만 나오게 할 수 없기에 유져의 체크인 상태를 확인하여 다르게 보이도록 한다.
우선 LocationDetailVM에있는 getCheckedInStatus 함수를 ProfileVM에 가져온다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
func getCheckedInStatus() {
guard let profileRecordID = CloudKitManager.shared.profileRecordID else { return }
CloudKitManager.shared.fetchRecord(with: profileRecordID) { [self] result in
DispatchQueue.main.async {
switch result {
case .success(let record):
if let _ = record[DDGProfile.kIsCheckedIn] as? CKRecord.Reference { // modifed
isCheckedIn = true // modifed
} else {
isCheckedIn = false // modifed
}
case .failure(_):
break // modifed
}
}
}
}
우선 isCheckedIn 부분을 기존의 방식에서 간단하게 바꾸었고, 그에따라 if let의 변수로 사용되었던 reference가 필요가 없어졌으므로 _로 바꿔주었다.
현재 failure 부분은 break로 간단하게 처리해둔상태
그리고 onAppear 부분에 뷰가 렌더링 될때마다 상태를 확인하도록하기 위헤 코드를 추가한다.
1
2
3
4
.onAppear {
viewModel.getProfile()
viewModel.getCheckedInStatus() // new
}
그리고 체크인 상태일때 버튼이 보여져야 하기에
1
2
3
4
5
6
7
if viewModel.isCheckedIn {
Button {
} label: {
// 생략
}
}
이렇게 if로 감싸준다.
우선 이렇게하고 실행하여 체크인 버튼이 보이는지 확인해보도록 한다.
우선 잘 되는걸 알 수 있다.
Profile에서 체크아웃 구현
이제 굳이 해당 가게로 가서 체크아웃을 하는게 아닌, 프로필에서 바로 체크아웃을 구현해보도록 한다.
먼저 profilevm에서 해당 기능을 담당할 함수를 만들어보도록 한다.
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
func checkOut() {
guard let profileID = CloudKitManager.shared.profileRecordID else {
alertItem = AlertContext.unableToGetProfile
return
}
CloudKitManager.shared.fetchRecord(with: profileID) { result in
switch result {
case .success(let record):
record[DDGProfile.kIsCheckedIn] = nil
CloudKitManager.shared.save(record: record) { [self] result in
DispatchQueue.main.async {
switch result {
case .success(_):
isCheckedIn = false
case .failure(_):
alertItem = AlertContext.unableToCheckInOrOut
}
}
}
case .failure(_):
DispatchQueue.main.async {
self.alertItem = AlertContext.unableToCheckInOrOut
}
}
}
}
매커니즘은 간단하다 먼저 profileID를 가져오고 해당 id에 한해서 레코드를 조회하여 checkedin에 대한 값을 없애주고(클라우드), 이후 앱 내에서 해당 유저의 ischeckedIn 상태에 대해 변경을 해주는 것 이다.
이때 alert가 MainThread에서 작동해야 하므로 DispatchQueue를 사용해주었다.
다시 버튼에서 구현한 체크아웃 기능을 달아준다.
1
2
3
Button {
viewModel.checkOut()
}
이제 실행을 해보면
체크아웃이 되는걸 알 수 있다.
Github: Dub-Dub-Grub Repository