포스트

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를 호출하는 함수를 불러왔다.

Jun-09-2024 17-57-04

Jun-09-2024 17-54-43

로그아웃하고 로그인하면 유져 정보가 새롭게 씌워져서 프로필 이미지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) 이게 없어서 안되었다.

Jun-09-2024 21-49-38

애플 로그아웃이 뭔가 제대로 안되어서 수정

여기는 솔직히 지피티의 의존도가 있다 ㅠ

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 라이센스를 따릅니다.