Во-первых, ответ Алекса на 100% правильный.
Я хочу добавить несколько дополнительных точек данных, которые могут помочь вам в долгосрочной перспективе.
Первый элемент - массивы. Массивы очень сложны в базах данных NoSQL - хотя они предоставляют данные логической последовательности через индекс, 0, 1, 2 они не ведут себя как массив в коде - так, например; Предположим, вы хотите вставить элемент в индекс. Ну, вы не можете (* вы можете, но это не просто вызов 'insert'). Кроме того, вы не можете нацеливать элементы массива в запросах, что ограничивает их полезность. Наименьшей единицей изменения в поле массива Firestore является все поле - меньшие изменения в отдельных элементах поля не могут быть внесены. Исправление состоит в том, чтобы не использовать массивы и позволить FireStore создавать идентификаторы документов для ваших «объектов» данных на лету, например. «ключи» к узлу
Вторая проблема - (которая может не быть проблемой в настоящее время) - как обрабатываются данные. Предположим, что вы выпустили свое приложение, и у пользователя есть 2 миллиона художников в их коллекции - с вашим кодом, как есть, все эти данные загружаются за один раз, что, вероятно, будет не лучшим интерфейсом, но, кроме того, это может привести к переполнению памяти устройство. Поэтому работать с «кусками» данных намного проще как на устройстве, так и на пользователе.
Итак, я собрал пример кода, чтобы помочь с этим.
Первый класс для хранения данных об исполнителе. Просто отслеживайте идентификатор документа и имя исполнителя.
class ArtistClass {
var docId = ""
var name = ""
init(aDocId: String, aName: String) {
self.docId = aDocId
self.name = aName
}
}
и массив классов, в котором могут находиться художники. Это будет потенциальный источник данных для tableView
var artistArray = [ArtistClass]()
Это означает, что художник должен быть записан как документ, а не как массив. DocumentID - это «ключ», сгенерированный FireStore, который создается для каждого исполнителя.
func writeArtists() {
let artistsRef = self.db.collection("artists")
let floyd = [
"name": "Pink Floyd"
]
let zep = [
"name": "Led Zeppelin"
]
let who = [
"name": "The Who"
]
artistsRef.addDocument(data: floyd)
artistsRef.addDocument(data: zep)
artistsRef.addDocument(data: who)
}
, а затем функция для чтения всех художников.
func readArtists() {
let artistsRef = self.db.collection("artists")
artistsRef.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
let docId = document.documentID
let name = document.get("name") as! String
let artist = ArtistClass(aDocId: docId, aName: name)
self.artistArray.append(artist)
}
for a in self.artistArray { //prints the artists to console
print(a.docId, a.name)
}
}
}
}
Итак, ваши данные в Firestore выглядят так
artists (collection)
8lok0a0ksodPSSKS
name: "Let Zeppelin"
WKkookokopkdokas
name: "The Who"
uh99jkjekkkokoks
name: "Pink Floyd"
так что крутая часть. Предположим, у вас есть tableView, который показывает 10 художников одновременно с кнопкой «вниз», чтобы увидеть следующие 10. Сделайте это изменение
let artistsRef = self.db.collection("artists").order(by: "name").limit(to: 10)
Да, и вы заметите, что теперь функция сортировки идет по серверу, а не по устройству - поэтому, если есть миллион исполнителей, она сортируется на сервере перед доставкой на устройство, что будет значительно быстрее.
Вы также можете легче выполнять запросы для определенных данных об исполнителе, и вам не нужно заботиться о хранении, поскольку каждый исполнитель является собственным документом вместо всех исполнителей в одном.
Надеюсь, это поможет!