Final (10)
로그인 상태에따라 다른 페이지 보여주기.
SceneDelegate에서 함수를 하나 만들어서 실행하면 문제가 해결될걸로 보인다.
1
2
3
4
5
if Auth.auth().currentUser != nil {
window.rootViewController = tabbarController
} else {
window.rootViewController = greetingVC
}
SceneDelegate 전면 수정
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
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
configureInitialViewController()
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
self.window = window
window.makeKeyAndVisible()
configureInitialViewController()
}
func configureInitialViewController() {
if Auth.auth().currentUser != nil {
switchToMainTabBarController()
} else {
switchToGreetingViewController()
}
}
func switchToMainTabBarController() {
let tabbarController = UITabBarController()
greetingVC = GreetingViewController(
appleTapped: { [weak signViewModel] in
signViewModel?.appleLoginDidTapped()
},
kakaoTapped: { [weak signViewModel] in
signViewModel?.kakaoLoginDidTapped()
},
googleTapped: { [weak signViewModel] in
signViewModel?.googleLoginDidTapped(presentViewController: self.greetingVC)},
viewModel: signViewModel)
let mapVC = MapViewController()
let recommendVC = UINavigationController(rootViewController: RecommendViewController())
let communityVC = UINavigationController(rootViewController: CommunityViewController())
let mypageVC = UINavigationController(rootViewController: MyPageViewController(signOutTapped: { [weak signViewModel, weak self] in
signViewModel?.signOut()
self?.configureInitialViewController()
}, viewModel: signViewModel))
greetingVC.tabBarItem = UITabBarItem(
title: "로그인테스트",
image: UIImage(systemName: "magnifyingglass.circle"),
selectedImage: UIImage(systemName: "magnifyingglass.circle.fill"))
mapVC.tabBarItem = UITabBarItem(
title: "지도",
image: UIImage(systemName: "map.circle"),
selectedImage: UIImage(systemName: "map.circle.fill"))
recommendVC.tabBarItem = UITabBarItem(
title: "추천",
image: UIImage(systemName: "hand.thumbsup"),
selectedImage: UIImage(systemName: "hand.thumbsup.fill"))
communityVC.tabBarItem = UITabBarItem(
title: "커뮤니티",
image: UIImage(systemName: "person.3"),
selectedImage: UIImage(systemName: "person.3.fill"))
mypageVC.tabBarItem = UITabBarItem(
title: "마이페이지",
image: UIImage(systemName: "person.crop.circle"),
selectedImage: UIImage(systemName: "person.crop.circle.fill"))
tabbarController.viewControllers = [recommendVC, mapVC, communityVC, mypageVC]
window?.rootViewController = tabbarController
}
func switchToGreetingViewController() {
greetingVC = GreetingViewController(
appleTapped: { [weak signViewModel] in
signViewModel?.appleLoginDidTapped()
},
kakaoTapped: { [weak signViewModel] in
signViewModel?.kakaoLoginDidTapped()
},
googleTapped: { [weak signViewModel] in
signViewModel?.googleLoginDidTapped(presentViewController: self.greetingVC)},
viewModel: signViewModel)
window?.rootViewController = greetingVC
}
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
if let url = URLContexts.first?.url {
if (AuthApi.isKakaoTalkLoginUrl(url)) {
_ = AuthController.handleOpenUrl(url: url)
}
}
}
아예 로그인 이후에 나오는 탭바 호출 함수, 로그인화면 호출 함수를 나누었고
configureInitialViewController
메서드를 통해서 현재 로그인되어있는지 아닌지로 판단한다.
그리고 로그아웃을 눌렀을때도 다시 첫화면으로 돌아가게 하기 위해서
1
2
3
4
let mypageVC = UINavigationController(rootViewController: MyPageViewController(signOutTapped: { [weak signViewModel, weak self] in
signViewModel?.signOut()
self?.configureInitialViewController() // added
}, viewModel: signViewModel))
여기를 추가하여 메인페이지로 돌아가게끔 했다.
이후 GreetingVC 바인드 함수를 조금 수정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private func bind() {
viewModel.loginPublisher.sink { [weak self] completion in
switch completion {
case .finished:
return
case .failure(let error):
let alert = UIAlertController(title: "에러 발생", message: "\(error.localizedDescription)이 발생했습니다.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "확인", style: .default))
self?.present(alert, animated: true)
}
} receiveValue: { _ in
let scene = UIApplication.shared.connectedScenes.first
if let sd: SceneDelegate = (scene?.delegate as? SceneDelegate) {
sd.switchToMainTabBarController()
}
}.store(in: &cancellables)
}
receiveValue
쪽에 print("로그인")
만 되어있었는데
sceneDelegate를 호출하면서 tabbarVC를 호출하는 함수를 불러왔다.
로그아웃하고 로그인하면 유져 정보가 새롭게 씌워져서 프로필 이미지url이 날아가는 문제가 생기는데 이부분은 이따 고민해보는걸로
가게에 대한 리뷰 표시
StoreVC에 보여줄 Cell에 대해서 작성을 해보려한다.
우선 StoreManager를 하나 만들어 주었다.
1
2
3
4
5
6
7
8
class StoreManager {
func reqeustStore(storeAddress: String, completion: @escaping(QuerySnapshot?, (Error)?) -> Void) {
reviewCollection.whereField(db_storeAddress, isEqualTo: storeAddress).getDocuments(completion: completion)
}
}
Viewmodel 생성
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
func getStoreReview(storeAddress: String) {
storeManager.reqeustStore(storeAddress: storeAddress) { [weak self] querySnapshot, error in
self?.userReview.removeAll()
if let error = error {
self?.reviewPublisher.send(completion: .failure(error))
}
if let snapshotDocuments = querySnapshot?.documents {
if !snapshotDocuments.isEmpty {
for doc in snapshotDocuments {
let data = doc.data()
guard
let uid = data["uid"] as? String,
let title = data["title"] as? String,
let storeName = data["storeName"] as? String,
let storeAddress = data["storeAddress"] as? String,
let content = data["content"] as? String,
let rating = data["rating"] as? Float,
let imageURL = data["imageURL"] as? [String],
let isActive = data["isActive"] as? Bool,
let createdAt = data["createdAt"] as? Timestamp,
let updatedAt = data["updatedAt"] as? Timestamp
else {
print("error")
return
}
let reviewData = ReviewModel(uid: uid, title: title, storeAddress: storeAddress, storeName: storeName, content: content, rating: rating, imageURL: imageURL, isActive: isActive, createdAt: createdAt, updatedAt: updatedAt)
self?.userReview.append(reviewData)
self?.reviewPublisher.send(())
}
}
}
}
}
VC에 함수 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private func fetchRequest() {
viewModel.getStoreReview(storeAddress: addressText!)
}
private func bind() {
viewModel.$userReview
.receive(on: DispatchQueue.main)
.sink { _ in
self.tableView.reloadData()
}.store(in: &cancellables)
viewModel.reviewPublisher.sink { completion in
switch completion {
case .finished:
return
case .failure(let error):
print(error)
}
} receiveValue: { _ in
}.store(in: &cancellables)
}
로드가 안되어서 생각해보니 .receive(on: DispatchQueue.main)
이게 없어서 안되었다.
애플 로그아웃이 뭔가 제대로 안되어서 수정
여기는 솔직히 지피티의 의존도가 있다 ㅠ
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
func signOutApple(completion: @escaping (Error?) -> Void) {
guard let userID = UserDefaults.standard.string(forKey: "appleAuthorizedUserIdKey") else {
let error = NSError(domain: "AppleSignOut", code: -1, userInfo: [NSLocalizedDescriptionKey: "No Apple ID user ID found."])
completion(error)
return
}
let appleIDProvider = ASAuthorizationAppleIDProvider()
appleIDProvider.getCredentialState(forUserID: userID) { (credentialState, error) in
if let error = error {
completion(error)
return
}
switch credentialState {
case .authorized:
completion(nil)
case .revoked, .notFound:
// Consider the user logged out if the credential is revoked or not found
completion(nil)
default:
let unknownError = NSError(domain: "AppleSignOut", code: -1, userInfo: [NSLocalizedDescriptionKey: "Unknown Apple credential state."])
completion(unknownError)
}
}
}
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
guard let credential = authorization.credential as? ASAuthorizationAppleIDCredential else { return }
let userID = credential.user
if UserDefaults.standard.string(forKey: "appleAuthorizedUserIdKey") == nil {
UserDefaults.standard.set(userID, forKey: "appleAuthorizedUserIdKey")
}
let nonce = currentNonce
signManager.saveApple(appleCredential: credential, nonce: nonce!) { [weak self] result in
switch result {
case .success(let result):
if let user = result?.user {
let email = credential.email ?? ""
self?.signManager.fetchUserData(uid: user.uid) { error, snapshot in
if let error = error {
self?.loginPublisher.send(completion: .failure(error))
}
if let snapshot = snapshot {
if snapshot.exists() {
self?.loginPublisher.send(())
} else {
let model = UserModel(uid: user.uid, email: email, isBlock: false, nickName: "", profileImageUrl: "https://firebasestorage.googleapis.com/v0/b/tteoppokki4u.appspot.com/o/dummyProfile%2FdefaultImage.png?alt=media&token=b4aab21e-e19a-42b7-9d17-d92a3801a327")
self?.signManager.saveUserData(user: model)
}
}
}
}
case .failure(let error):
self?.loginPublisher.send(completion: .failure(error))
}
}
}
이젠 로그아웃도 잘된다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.