티스토리 뷰

나만의 그림 일기 앱을 만들다가 생겨난 버그인데

그림을 그리고, 내용을 작성하고 추가 버튼을 누르면 파이어베이스 Storage에는 그림 사진이,

그린 그림을 사진으로 변환하고, 변환한 사진을 Firebase Storage에 업로드.

작성한 내용과 사진에 대한 경로를 Firebase Firestore에 추가.

그 후 업로드가 되면 해당 FullScreen 모달 시트 창을 닫는다. 까지가 버튼에 대한 액션이고,

시트 창이 꺼지면 onDIsmiss에서 데이터를 다시 불러와 뷰를 새로 그려주게끔 코드를 구현했다.

 

그런데 새로 추가된 게시글의 사진만 불러오지 못하는 현상이 생겼다.

함수가 진행되는 모든 곳에 브레이크 포인트를 찍어 확인해보았는데 스토리지에 올라와있는데 못불러온다.

 

그 짧은 찰나에 아직 내부적으로 task를 완료하지 않은 상태라 다운로드가 안되는 것으로 추정했다.

 

해결 방법

1. Task를 다 수행하면 모달 시트 창을 닫는다.

Firebase Storage의 사진 업로드, 다운로드하는 메소드는 기본적으로 Async Await를 제공하지 않는다.

그래서 Async Await을 사용하려면 후행 클로저를 사용하지 않아야 하는데 getData는 후행 클로저를 반드시 써야하고, listAll()은 비동기 처리가 가능하다.

 

따라서 비동기처리로 하려면 경로에 있는 모든 리스트들을 불러와서 필요한 UIImage를 반환해야한다.

그런데 나는 여러 개의 사진을 업로드하고 불러오는 것이 아니라 최근 저장된 사진 하나의 데이터를 불러오지 못하는 거라 listAll이라는 메소드를 사용하기보다는 더 적절한 방법을 찾고 싶었다.

 

2. 글을 작성하고 추가할 때 미리 image를 관리하는 myPictureImages 배열에 넣는다.

글을 작성하고 추가버튼을 누를 때 해당 포스트잇과 UIImage 자체를 넘겨주니까 그것을 사용하여 download를 할 수 있게끔 한 것이다.

//MARK: - Add MyPetDiary(글 추가)
    @MainActor
    func addMyPetDiary(myPetDiary: MyPetDiary, image: UIImage) async {
        do {
            await self.uploadImage(image: image, userId: id)
            try await database.document(id).collection("PetDiary").document(myPetDiary.id)
                .setData([
                    "id": myPetDiary.id,
                    "date": myPetDiary.date,
                    "drawImageURL": myPetDiary.drawImageURL,
                    "content": myPetDiary.content
                ])
            
            // #1. 글을 작성하고 추가할 때 미리 image를 관리하는 myPictureImages 배열에 넣는다.
            // #2. OnDismiss이후 MainView가 다시 그려지고, MainMyDiaryListCell을 그릴 때,
            // downloadImage 함수에서 myPictureImages에 mydiaryPostId == myPetDiary.id 있다면 제외하고 append를 시켜주기 위한 용도 코드
            myPictureImages.append(MyPictureImage(mydiaryPostId: myPetDiary.id, image: image))
        } catch {
            print(error.localizedDescription)
        }
    }
   //MARK: - Download Draw Image
    @MainActor
    func downloadImage(_ myDiary: MyPetDiary) {
        let storageReference = Storage.storage().reference()
        let fileName = storageReference.child(myDiary.drawImageURL)
        
        // myPictureImages 배열에 myDiaryPostId == myDiary.id인 것만 필터링
        let existImages = myPictureImages.filter { picture in
            picture.mydiaryPostId == myDiary.id
        }
        
        // 필터링된 이미지가 없으면 append
        if existImages.isEmpty {
            //  이미지 로드 필요
            fileName.getData(maxSize: 5 * 1024 * 1024) { data, error in
                if (error != nil) {
                    print(error?.localizedDescription)
                }
                print("getData id: \(myDiary.id)")
                let image = UIImage(data: data!)!
                self.myPictureImages.append(MyPictureImage(mydiaryPostId: myDiary.id, image: image))
            }
        } else {
            //  이미지 로드 이미 함
        }
    }

OnDismiss이후 MainView가 다시 그려지고, MainMyDiaryListCell을 그릴 때,

task에서 downloadImage 함수가 실행되게끔 코드를 짰다.

 

downloadImage 함수에서 myPictureImages에 mydiaryPostId == myPetDiary.id 있다면 넘어가고

아니면 download 시켜줘 라는 의미이다. 앱을 껐다 킬 때 외에는 isEmpty 구문이 실행되지는 않을 것 같다.. 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
링크
TAG more
«   2025/05   »
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
글 보관함