기존에는 Firestore 에서 데이터를 [String: Any] 타입으로 전달 받고, Photo 타입으로 변환 후 사용했다.

private func createPhotoFromData(_ data: [String: Any]) -> Photo? {
    guard
        let documentReference = data["documentReference"] as? String,
        let image = data["image"] as? String,
        let memo = data["memo"] as? String,
        let date = data["date"] as? String,
        let tagData = data["tag"] as? [String: Any],
        let tagLabel = tagData["tagLabel"] as? String,
        let tagImage = tagData["tagImage"] as? String
    else {
        // 필수 필드가 누락되었거나 형식이 맞지 않는 경우 nil 반환
        return nil
    }
    let tag = TagModel(tagLabel: tagLabel, tagImage: tagImage)
    return Photo(documentReference: documentReference, image: image, memo: memo, date: date, tag: tag)
}

Firebase 에서는 swift 에서 정의한 커스텀 타입을 사용할 수 있도록 지원한다.

아래와 같이 기존에는 문서를 불러오는 과정에서 data 상수를 위에서 정의한 createPhotoFromData() 메서드를 호출해서 Photo 타입으로 변환하는 과정이 필요했다.

self.photoList = documents.compactMap { doc -> Photo? in
                // Firestore 스냅샷에서 필요한 데이터를 가져와 Photo 모델에 직접 할당
                let data = doc.data()
                if let photo = self.createPhotoFromData(data) {
                    return photo
                }
                return nil
            }

그리고 아래와 같이 swift에서 정의한 커스텀 타입을 사용해서 코드를 간략하게 변경할 수 있다.

self.photoList = documents.compactMap { document -> Photo? in
                let photoData = try? document.data(as: Photo.self)
                return photoData
            }

Firestore의 문서를 만들 때도 커스텀 타입을 사용할 수 있다.

func createPhotoDocument(photo: Photo, completion: @escaping (Error?) -> Void) {
        do {
            guard let userUID = authManager.currentUserUID else { return }
            let docRef = db.collection("users/\\(userUID)/Photo").document(photo.id)
						// 문서를 만들 때, Photo 객체를 전달할 수 있다.
            try docRef.setData(from: photo)
            print("Document added successfully.")
            completion(nil)
        } catch let error {
            print("Error adding document: \\(error)")
            completion(error)
        }
    }

결론

커스텀 타입을 사용하여 코드를 간략하게 작성할 수 있고, 가독성이 높아졌다.