Чтение двух моделей данных из Firebase Swift - PullRequest
0 голосов
/ 28 сентября 2019

У меня есть две модели: User модель и книга Review модель.Мой username в Обзоре относится к типу User, поэтому я могу получить данный отзыв и пользователя, который его создал.

Теперь я могу получить обзор, но не Пользовательвозражать с моим кодом.Что я делаю не так?

Класс пользователя

class User: NSObject {
    var id: String?
    var name: String?
    var email: String?
    var profileImageUrl: String?
    init(dictionary: [String: AnyObject]) {
        self.id = dictionary["id"] as? String
        self.name = dictionary["name"] as? String
        self.email = dictionary["email"] as? String
        self.profileImageUrl = dictionary["profileImageUrl"] as? String
    }
}

Структура обзора

struct Review {
    let id: String
    let bookName: String
    let author: String
    let review: String
    let username: User
    let createdAt: Date
    init(id: String, bookName: String, author: String, review: String, username: User, timestamp: Double) {

        self.id = id
        self.bookName = bookName
        self.author = author
        self.review = review
        self.username = username
        self.createdAt = Date(timeIntervalSince1970: timestamp / 1000)
    }
}

ОбзорКонтроллер

 private func fetchReviews() {
    let reviewRef = Database.database().reference().child("reviews")
    let queryRef = reviewRef.queryOrdered(byChild: "timestamp").queryLimited(toLast: 5)

    queryRef.observe(.value, with: { snapshot in

        var temporaryReviews = [Review]()

        for child in snapshot.children {
            if let childSnapshot = child as? DataSnapshot,
                let dictionary = childSnapshot.value as? [String:Any],
                let user = dictionary["user"] as? [String:Any],
                let id = user["id"] as? String,
                let name = user["name"] as? String,
                let profileImageUrl = user["profileImageUrl"] as? String,
                let url = URL(string: profileImageUrl),
                let bookName = dictionary["bookName"] as? String,
                let author = dictionary["author"] as? String,
                let review = dictionary["review"] as? String,
                let timestamp = dictionary["timestamp"] as? Double {

                let user = User(dictionary: <#T##[String : AnyObject]#> ??? // Cannot use a user object

                let review = Review(id: childSnapshot.key, bookName: bookName, author: author, review: review, username: user, timestamp: timestamp)

                DispatchQueue.main.async {
                    temporaryReviews.insert(review, at: 0)
                    self.reviews = temporaryReviews
                    self.tableView.reloadData()
                }
            }
        }
    })
}

Если я удаляю пользователя и связанные с ним значения из цикла, я получаю данные в пользовательском интерфейсе, но не username или photoImageURL, которые я обновляю в своем классе представления,Данные уже в Firebase.Как я могу прочитать данные и пользователя?

1 Ответ

0 голосов
/ 28 сентября 2019

Непонятно, что ожидается от этой строки

let user = User(dictionary: <#T##[String : AnyObject]#> ???

, а также не уверен, почему класс User: NSObject является NSObject, но это будет работать с Swift 5.

class User { //using pure Swift, remove NSObject
    var id: String?
    var name: String?
    var email: String?
    var profileImageUrl: String?
    init(dictionary: [String: Any]) { //change AnyObject to Any
        self.id = dictionary["id"] as? String
        self.name = dictionary["name"] as? String
        self.email = dictionary["email"] as? String
        self.profileImageUrl = dictionary["profileImageUrl"] as? String
    }
}

затем при чтении данных Firebase в замыкании создайте словарь элементов, которые вы хотите заполнить пользовательским классом

let id = user["id"] as? String,
let name = user["name"] as? String,
let profileImageUrl = user["profileImageUrl"] as? String,
let url = URL(string: profileImageUrl),

let dict: [String: Any] = [
    "id": id,
    "name": name,
    "email": email,
    "profileImageUrl": profileImageUrl
]

let aUser = User(dictionary: dict)

Или вы можете просто передать снимок в класс User и позволить ему получить все, что ему нужноиз него

class User {
    var user_id = ""
    var name = ""
    var email = ""
    var profileImageUrl = ""

    init(withSnap: DataSnapshot) {
        self.user_id = withSnap.childSnapshot(forPath: "id").value as? String ?? "No Id"
        self.name = withSnap.childSnapshot(forPath: "name").value as? String ?? "No name"
        self.email = withSnap.childSnapshot(forPath: "email").value as? String ?? "No email"
        self.profileImageUrl = withSnap.childSnapshot(forPath: "profileImageUrl").value as? String ?? "No url"
    }
}

, а затем

let aUser = User(withSnap: snapshot)

Кроме того, в вашем коде tableView перезагружается при каждой итерации цикла, что может вызвать мерцание.Лучше всего переместить self.tableView.reloadData() за пределы цикла for, чтобы он выполнялся только один раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...