Эффективное извлечение нескольких изображений из Firebase

# #swift #firebase #image

Вопрос:

В моем приложении будут списки изображений, как показано в приведенном ниже примере:

введите описание изображения здесь

Чтобы получить отдельное изображение из firebase, я определил ViewModel класс с одним изображением в качестве UIImage свойства. Затем соответствующее представление может обновиться с учетом опубликованных изменений ViewModel . Имея несколько-и фактически произвольное количество-изображений в списке, я не думаю, что предоставление каждому из них своего собственного ViewModel будет эффективным, особенно потому, что я представляю, что мне придется ForEach перебирать каждую ссылку на изображение и создавать ViewModel внутри родительского представления. Это кажется проблематичным, потому что всякий раз, когда родительское представление воссоздается, я выполняю операцию O(n) для создания и инициализации моделей представлений для каждого изображения, не говоря уже о времени, необходимом для повторной выборки.

Есть ли способ извлечь несколько изображений из одного ViewModel , сохранив их как [UIImage] ? Я бы, конечно, дал этому ViewModel массив ссылок. В качестве альтернативы, какую архитектуру вы бы предложили для эффективной выборки любого количества изображений из firebase с учетом массива (неизвестного размера) ссылок на хранилище?

Я могу предоставить более подробную информацию / код по мере необходимости.

Кажется, это работает…

 class MultipleImageFetcher: ObservableObject {  var firebaseManager: FirebaseManager  var imageDictionary: [String: UIImage] = [:]  @Published var isReady = false    init(_ firebaseManager: FirebaseManager) {  self.firebaseManager = firebaseManager  }   func fetchAllImages(references: [String]) {  for refID in references {  fetchIndividualImage(id: refID, totalNum:   references.count)  }  }   func fetchIndividualImage(id: String, totalNum: Int) {  let ref = getRefURL(uid: id)  ref.getData(maxSize: 2051240) { data, error in  if let error = error {  print("Error: (error)")  return  }  self.imageDictionary[id] = UIImage(data: data!)  self.checkIsReady(num: totalNum)  }  }   func getRefURL(uid: String) -gt; StorageReference {  return firebaseManager.STORAGE.reference().child(uid)  }   func checkIsReady(num: Int) {  if imageDictionary.count == num {  self.isReady = true  } else {  self.isReady = false  }  } }    struct ImageView: View {  @ObservedObject var fetcher: MultipleImageFetcher   init(_ firebaseManager: FirebaseManager) {  self.fetcher = MultipleImageFetcher(firebaseManager)  }    var body: some View {   Button {  fetcher.fetchAllImages(references:  ["KXKFM94sk5OTyld2VsCQdhijd6m1", "MtgRaKMwyQfYX2uxuHs3iH3pLB52"])  } label: {  Text("Load Image")  }   if fetcher.isReady {  Text("Is Ready")  } else {  Text("Loading...")  }  } }  

Комментарии:

1. Да, вы определенно можете получить несколько изображений в одной модели представления, и да , вы можете сохранить их как [UIImage] , но реально, вы, вероятно, захотите сохранить их как пару ключ/значение, чтобы знать, к какой ячейке они принадлежат. Другими словами, [UUID:UIImage] или что-то в этом роде. Возможно, вы также захотите изучить возможность кэширования результатов ( NSCache ?)

2. Какой вызов функции я должен выполнить в Firebase? Я предполагаю, что это еще не все, ref.getData() но в цикле for… И да, кэширование определенно у меня на уме…

3. Нет, на самом деле в этом нет ничего особенного-есть, если вас волнует, когда данные вернутся (это означает, что должно произойти что-то последовательное).

4. Хорошо, я поиграю с этим подходом

5. Я предлагаю вам изучить Combine-это будет более надежное решение для загрузки конвейера и обработки ошибок