업로드했던 이미지를 다시 불러오는 작업을 해보겠습니다.
이에 앞서 이미지가 업로드 될 때까지 어떤 작업들이 이루어지는 지 정리해보겠습니다.
일기 리스트를 가져올 때 이미지를 로드하지 않은 이유는 이미지를 가져오는 작업이 너무 느려서 동기적으로 리스트를 구성하지 않고 셀을 인스턴스화 할 때 비동기적으로 이미지를 불러오게 하기 위함입니다.
이런 식으로 로드되지 않은 이미지는 기본(로딩) 이미지로 대체하고 로드된 이미지는 원본 이미지가 되도록.
import Foundation
import FirebaseStorage
class StorageViewModel : NSObject {
let storage = Storage.storage()
...
func getImage(uID:String, docID: String, completion: @escaping (Data?) -> Void){
let storagePath = "gs://futurediary-12345.appspot.com/\(uID)/\(docID).jpg"
let storageRef = storage.reference(forURL: storagePath)
storageRef.getData(maxSize: Int64(100 * 1024 * 1024)){(data, error) in
if let error = error{
print("Error Occured in getting image : \(error)")
completion(nil)
}
else{
completion(data!)
}
}
}
...
}
func getImage
: uID와 docID를 통해서 유저의 일기 하나에 할당된 이미지를 불러오는 합수입니다.let storagePath = "gs://futurediary-12345.appspot.com/\(uID)/\(docID).jpg"
: 이미지의 경로입니다. 이 경로로 레퍼런스를 얻고 getData(maxSize:..
를 통해 이미지 데이터를 받습니다.이 뷰모델을 수정하는 이유는 사진이 포함된 일기는 메인 화면으로 전환되기 전에 "일단" 로딩 이미지로 바꾸기 위함입니다.
import Foundation
import FirebaseFirestore
class DBViewModel : NSObject {
...
func getDiaryList(uID:String, addingClosure:@escaping (Diary) -> Void, completeClosure:@escaping ()->Void){
db.collection("users").document(uID).collection("diarys").getDocuments(completion:{ (querySnapshot, error) in
if let error = error {...}
else {
if let querySnapshot = querySnapshot {
...
for i in 0 ..< querySnapshot.documents.count{
...
if docData["haveImage"] as! Bool {
...
let loadImg = UIImage(named: "load-icon-png-8")!.pngData()!
...
}
else{
...
}
...
}
let loadImg = UIImage(named: "load-icon-png-8")!.pngData()!
: 프로젝트 내부에 저장한 이미지를 pngData로 변형시킵니다. 어느 위치에서든 저 파일을 가져오는게 신기합니다....
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "diaryCell", for: indexPath) as? DiaryTableViewCell else {return UITableViewCell()}
...
if let imageData = cell.cellData.imageData{
cell.diaryTableViewCellImage.isHidden = false
cell.diaryTableViewCellImage.image = UIImage(data: imageData)
storageViewModel.getImage(uID:self.uid, docID:cell.cellData.docID){(img) in
self.diaryListViewModel.diaryList[indexPath.row].imageData = img
cell.diaryTableViewCellImage.image = UIImage(data: img!)
}
}
else{
cell.diaryTableViewCellImage.isHidden = true
cell.diaryTableViewCellImage.image = nil
}
return cell
}
...
if let imageData = cell.cellData.imageData
: 만약 이미지가 nil이 아니라면, 그러니까 현재 로딩 이미지 데이터가 있다면 storageVM을 통해 이미지를 로드하고 아니라면 이미지 뷰를 히든으로 만듭니다.cell.diaryTableViewCellImage.image = UIImage(data: imageData)
: 이미지를 가져오는 건 굉장히 오래걸리는 일이므로 일단 로딩 이미지로 보여줍니다.storageViewModel.getImage(uID:self.uid, docID:cell.cellData.docID){
: 이미지를 가져오는 StorageVM의 메서드입니다. self.diaryListViewModel.diaryList[indexPath.row].imageData = img
: 현재 Diary의 이미지를 갱신합니다.cell.diaryTableViewCellImage.image = UIImage(data: img!)
: UI를 원본이미지로 교체합니다.제 나름대로 방법으로 해봤는데 혹시 더 빠르고 괜찮은 방법이 있다면 공유해주시면 감사하겠습니다
로그인 후 메인 화면에 이미지가 로드되는 상황입니다.