Как получить массив array?
коллеги! Я начинающий разработчик, поэтому прошу с пониманием относиться к моему, возможно, банальному вопросу. Так же прошу отнестись и к формату вопроса - я сейчас пишу первичный в жизни этот вопрос и в целом. Посмотрите, что у меня есть: 1. Существующий класс «Продукт»:
import Foundation
import UIKit
protocol arrayProductsProtocol {
init? (productDict: [String: Any])
}
struct Product {
init(store: String?,
productPostArticle: String?,
productPostTitle: String?,
productPostDescription: String?,
productPostImageCount: Int?,
productPostPrice: Double?,
productPostDiscont: Double?,
productPostFinalPrice: Double?,
productPostSex: String?,
productPostSeason: String?,
productPostPublicationDate: Date,
productPostLikesCount: Int?,
productPostIsLiked: Bool?,
productPostViewsCount: Int?,
productPostPhotoCount: Int?,
productPostIsNew: String?,
productPostArrayPhotos: [URL]?) {
self.store = store ?? "Название магазина"
self.productPostArticle = productPostArticle ?? "0000000000"
self.productPostTitle = productPostTitle ?? "Название продукта"
self.productPostDescription = productPostDescription ?? "Описание продукта"
self.productPostImageCount = productPostImageCount ?? 0
self.productPostPrice = productPostPrice ?? 0
self.productPostDiscont = productPostDiscont ?? 0
self.productPostFinalPrice = productPostFinalPrice ?? 0
self.productPostSex = productPostSex ?? Product.Sex.unisex.rawValue
self.productPostSeason = productPostSeason ?? Product.Season.autumn.rawValue
self.productPostPublicationDate = productPostPublicationDate
self.productPostLikesCount = productPostLikesCount ?? 0
self.productPostIsLiked = productPostIsLiked ?? false
self.productPostViewsCount = productPostViewsCount ?? 0
self.productPostPhotoCount = productPostPhotoCount ?? 0
self.productPostIsNew = productPostIsNew ?? Product.New.normal.rawValue
self.productPostArrayPhotos = productPostArrayPhotos ?? []
}
var productDict: [String: Any] {
return [
"productPostArticle" : productPostArticle,
"productPostTitle" : productPostTitle,
"productPostDescription" : productPostDescription,
"productPostPrice" : productPostPrice,
"productPostDiscont" : productPostDiscont,
"productPostFinalPrice" : productPostFinalPrice,
"productPostSex" : productPostSex,
"productPostSeason" : productPostSeason,
"productPostPublicationDate" : productPostPublicationDate,
"productPostLikesCount" : productPostLikesCount,
"productPostIsLiked" : productPostIsLiked,
"productPostViewsCount" : productPostViewsCount,
"productPostIsNew" : productPostIsNew,
"productPostImageCount" : productPostImageCount,
"store" : store,
"productPostPhotoCount" : productPostPhotoCount
]
}
//магазин
var store: String = ""
//артукул
var productPostArticle: String
//описание товара
var productPostArrayPhotos: [URL]?
var productPostTitle: String
var productPostDescription: String
var productPostImageCount: Int
//стоимость товара
var productPostPrice: Double
var productPostDiscont: Double
var productPostFinalPrice: Double
//параметры товара
var productPostSex: String
var productPostSeason: String
//параметры поста
var productPostPublicationDate: Date
var productPostLikesCount: Int
var productPostIsLiked: Bool
var productPostViewsCount: Int
var productPostPhotoCount: Int
//новизна товара
var productPostIsNew: String
//параментры товара
enum Sex: String {
case man = "Для мужчин"
case woman = "Для женщин"
case unisex = "Унисекс"
}
enum Season: String{
case winter = "Зима"
case spring = "Весна"
case summer = "Лето"
case autumn = "Осень"
}
enum New: String {
case isNew = "Новинка"
case normal = ""
case sale = "Скидки"
}
extension Product: arrayProductsProtocol {
init? (productDict: [String : Any]) {
guard let productPostArticle = productDict["productPostArticle"] as? String,
let productPostTitle = productDict["productPostTitle"] as? String,
let productPostDescription = productDict["productPostDescription"] as? String,
let productPostPrice = productDict["productPostPrice"] as? Double,
let productPostDiscont = productDict["productPostDiscont"] as? Double,
let productPostFinalPrice = productDict["productPostFinalPrice"] as? Double,
let productPostSex = productDict["productPostSex"] as? String,
let productPostSeason = productDict["productPostSeason"] as? String,
let productPostPublicationDate = productDict["productPostPublicationDate"] as? Date,
let productPostLikesCount = productDict["productPostLikesCount"] as? Int,
let productPostIsLiked = productDict["productPostIsLiked"] as? Bool,
let productPostViewsCount = productDict["productPostViewsCount"] as? Int,
let store = productDict["store"] as? String,
let productPostIsNew = productDict["productPostIsNew"] as? String,
let productPostImageCount = productDict["productPostImageCount"] as? Int,
let productPostPhotoCount = productDict["productPostPhotoCount"] as? Int,
let productPostArrayPhotos = productDict["productPostArrayPhotos"] as? [URL]
else { return nil }
self.init(
store: store,
productPostArticle: productPostArticle,
productPostTitle: productPostTitle,
productPostDescription: productPostDescription,
productPostImageCount: productPostImageCount,
productPostPrice: productPostPrice,
productPostDiscont: productPostDiscont,
productPostFinalPrice: productPostFinalPrice,
productPostSex: productPostSex,
productPostSeason: productPostSeason,
productPostPublicationDate: productPostPublicationDate,
productPostLikesCount: productPostLikesCount,
productPostIsLiked: productPostIsLiked,
productPostViewsCount: productPostViewsCount,
productPostPhotoCount: productPostPhotoCount,
productPostIsNew: productPostIsNew,
productPostArrayPhotos: productPostArrayPhotos
)
}
}
Вышеописанным способом я пытаюсь создавать Продукты.
Далее у меня есть файл с функциями для Firebase. Вот он:
import Foundation
import Firebase
struct FBDataBase {
static func creatDB(completion: @escaping (([Product]) -> ())) {
// переходим к списку продуктов (1, 2, 3, 4, 5, ...)
var array: [Product] = []
let ref = Firestore.firestore().collection("stores").document((Auth.auth().currentUser?.email)!).collection("products")
ref.addSnapshotListener { (products, error) in
array = (products?.documents.compactMap({Product(productDict: $0.data())}))!
}
completion(array)
}
}
Затем я вызываю это из ViewController'a следующим образом:
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of items
FBDataBase.creatDB(completion: { (array) in
self.prodArray = array
print("self.prodArray: \(self.prodArray)")
print("array: \(array)")
})
print("prodArray count: \(self.prodArray.count)")
return self.prodArray.count
}
Проблема в том, что у меня в struct FBDataBase array всегда равен нулю. Я, признаюсь, пробовал различные методы уже неделю как, но ничего не получилось в итоге. Прошу помощи, коллеги. Очень благодарю за помощь, ибо знаний не хватает, а мечта - свой проект - стоит на месте и мотивация падает. Спасибо.
P.S.: прошу прощения за форматирование поста, но не знаю пока как это делать корректно. Вроде ввожу код через соответствующую кнопку и появляющийся блок, но в предпросмотре поста отображается все "криво".
Вот фото моей базы данных: первая страница, далее раскрываю "products" "до дна", так сказать
Ответы (1 шт):
Попробуйте разобраться с асинхронными коллбэками, у вас данные судя по всему приходят позже, чем Вы их используете.
ref.addSnapshotListener { (products, error) in
array = (products?.documents.compactMap({Product(productDict: $0.data())}))!
completion(array)
}
Подобным же образом вам нужно поступить при выводе данных во вью контроллере - сначала загрузить данные, а потом уже выводить в коллекшен вью
FBDataBase.creatDB(completion: { (array) in
self.prodArray = array
print("self.prodArray: \(self.prodArray)")
print("array: \(array)")
self.collectionView.reloadData()
})
При reloadData как раз будут вызывается уже методы UICollectionView с подготовленными данными
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
self.prodArray.count
}