포스트

Final (7)

현재 로그인 된 유져의 프로필사진과 프로필 명 변경.

우선 realtimeDatabase의 user안에 유져의 uid 안에 내용이 있다.

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
func updateProfile(uid: String, nickName: String, profile: UIImage, completion: @escaping (Error) -> Void) {
        
        let ref = Database.database().reference()
        let storageRef = Storage.storage().reference(forURL: "gs://tteoppokki4u.appspot.com")
        let storageProfileRef = storageRef.child("profile").child(uid)
        guard let imageData = profile.jpegData(compressionQuality: 0.8) else { return }
        
        let metaData = StorageMetadata()
        metaData.contentType = "image/jpg"
        
        storageProfileRef.putData(imageData, metadata: metaData) { (metadata, error) in
            if let error = error {
                completion(error)
                return
            }
            
            storageProfileRef.downloadURL { (url, error) in
                if let error = error {
                    completion(error)
                    return
                }
                
                guard let downloadURL = url else { return }
                ref.child("users").child(uid).setValue(["nickName": nickName, "profileImageUrl": downloadURL])
            }
        }
        
        
        
    }

UserManager를 다음과 같이 구현한다.

그리고 VC로 가서

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 picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        picker.dismiss(animated: true, completion: nil)
        
        guard let result = results.first else { return }
        
        if result.itemProvider.canLoadObject(ofClass: UIImage.self) {
            result.itemProvider.loadObject(ofClass: UIImage.self) { [weak self] (image, error) in
                guard let self = self else { return }
                if let image = image as? UIImage {
                    DispatchQueue.main.async {
                        self.profileImage = image
                        self.profileImageView.image = image
                    }
                }
            }
        }
    }
    
    @objc func saveChanges() {
        guard let uid = Auth.auth().currentUser?.uid else { return }
        guard let image = profileImage else { return }
        let userName = userNameTextField.text ?? ""
        
        userManager.updateProfile(uid: uid, nickName: userName, profile: image) { error in
            print(error)
        }
        
        
    }

이렇게 추가로 적어주었다.

하지만 이미지를 선택하니

1
3E5B4347-8A53-4164-A84C-FC47F4C2366E grantAccessClaim reply is an error: Error Domain=NSCocoaErrorDomain Code=4101 "Couldn’t communicate with a helper application." UserInfo={NSUnderlyingError=0x600000cf7510 {Error Domain=PHAssetExportRequestErrorDomain Code=4 "작업을 완료할 수 없습니다.(PHAssetExportRequestErrorDomain 오류 4.)" UserInfo={NSLocalizedDescription=작업을 완료할 수 없습니다.(PHAssetExportRequestErrorDomain 오류 4.), NSUnderlyingError=0x600000cf6520 {Error Domain=CloudPhotoLibraryErrorDomain Code=1006 "작업을 완료할 수 없습니다.(CloudPhotoLibraryErrorDomain 오류 1006.)" UserInfo={NSLocalizedDescription=작업을 완료할 수 없습니다.(CloudPhotoLibraryErrorDomain 오류 1006.)}}}}}

이런 오류가 발생.

아무래도 사진첩에 대한 권한이 없어서 발생한 문제가 아닐까라고 생각이된다.

우선 클라우드 사진을 다 빼니 해결.

아마 사진 권한이 제대로 되어있지 않아서 생긴 문제가 맞아보인다.

그리고 저장하려니 에러가 또 발생.

알고보니 url을 그대로 써서 생긴문제.

downloadURL.absoluteString로 바꿔서 해결.

MyPageVC에서 데이터 로드

1
2
3
func fetchUserData(uid: String, completion: @escaping((Error)?, DataSnapshot?) -> Void) {
        ref.child("users").child(uid).getData(completion: completion)
    }

우선은 이렇게 로드하는걸 간단하게 적었다.

이미지 로드도 우선은 간단하게 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private func fetchUser() {
        guard let uid = Auth.auth().currentUser?.uid else { return }
        userManager.fetchUserData(uid: uid) { [self] error, snapshot in
            if let error = error {
                print(error)
            }
            
            guard let dictionary = snapshot?.value as? [String: Any] else { return }
           
            myPageView.userProfile.kf.setImage(with: URL(string: dictionary["profileImageUrl"] as! String))
          
            
        }
}

CleanShot 2024-06-07 at 06 29 07@2x

simulator_screenshot_6A0F5FA0-AD1B-4D19-B237-1FEA7738FF90

우선은 로드가 되나 위의 사진과 같이 field가 수정되었음.

생각 해보니 email, uid는 저장할 필요가 없어보이기도하다…

realtimedatabase는 merge가 없어서 update를 사용한다.

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
    func updateProfile(uid: String, nickName: String, profile: UIImage, completion: @escaping (Error) -> Void) {
        
        
        let storageRef = Storage.storage().reference(forURL: "gs://tteoppokki4u.appspot.com")
        let storageProfileRef = storageRef.child("profile").child(uid)
        guard let imageData = profile.jpegData(compressionQuality: 0.8) else { return }
        
        let metaData = StorageMetadata()
        metaData.contentType = "image/jpg"
        
        storageProfileRef.putData(imageData, metadata: metaData) { (metadata, error) in
            if let error = error {
                completion(error)
                return
            }
            
            storageProfileRef.downloadURL { (url, error) in
                if let error = error {
                    completion(error)
                    return
                }
                
                guard let downloadURL = url else { return }
                let values = ["nickName": nickName, "profileImageUrl": downloadURL.absoluteString]
                self.ref.child("users").child(uid).updateChildValues(values) { error, reference in
                    if let error = error {
                        completion(error)
                        return
                    }
                }
            }
        }
        
    }
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.