#swift #firebase #firebase-realtime-database #sequential
# #быстрый #огневая база #firebase-realtime-database #последовательный
Вопрос:
Ниже приведена моя структура данных:
{
"posts": {
"xyz1": {
"author": "Jan",
"uid": "abc123",
},
"xyz2": {
"author": "Jenny",
"uid": "abc456",
},
}
"users": {
"abc123": {
"email": "Jan@gmail.com",
"profilePicURL": "https://firebasestorage.googleapis.com/v0/b/",
},
"abc456": {
"email": "Jenny@gmail.com",
"profilePicURL": "https://firebasestorage.googleapis.com/v0/c/",
},
}
}
Я хочу отобразить список записей «posts» в tableview.
let postRef = ref.child("posts")
postRef.observe(.childAdded, with: { (snapshot) in
let authorText = snapshot.value!.object(forKey: "author") as! String
let userIDText = snapshot.value!.object(forKey: "uid") as! String
}) { (error) in
print(error.localizedDescription)
}
Как я могу использовать «uid», полученный из приведенного выше запроса, чтобы выполнить последовательный запрос для извлечения «profilePicURL», используя значение «uid» в «users». Конечная цель — отобразить profilePic, хранящийся помимо записи, в tableview.
Спасибо вам за любую оказанную помощь.
Ответ №1:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "HomeCell", for: indexPath) as! HomeTableViewCell
cell.author.text = String(self.author[(indexPath as NSIndexPath).row])
let userIDText = String(self.userID[(indexPath as NSIndexPath).row])
ref.child("users").child(userIDText).observeSingleEvent(of: .value, with: { (snapshot) in
print("snaphot is (snapshot)")
let imageLink = snapshot.value?["profileImageUrl"] as! String
self.storageRef = FIRStorage.storage().reference(forURL: imageLink)
cell.profilePic.loadImageUsingCacheWithUrlString(urlString: imageLink)
}) { (error) in
print(error.localizedDescription)
}
return cell
}
Я использую следующее расширение для UIImageView для загрузки изображения с использованием URL-адреса, и это сработало!!
let imageCache = NSCache<AnyObject, AnyObject>()
extension UIImageView {
func loadImageUsingCacheWithUrlString(urlString: String) {
self.image = nil
//check cache for image first
if let cachedImage = imageCache.object(forKey: urlString) as? UIImage {
self.image = cachedImage
return
}
//otherwise fire off a new download
let url = NSURL(string: urlString)
URLSession.shared.dataTask(with: url! as URL, completionHandler: { (data, response, error) in
//download hit an error so lets return out
if error != nil {
print(error)
return
}
DispatchQueue.main.async(execute: {
if let downloadedImage = UIImage(data: data!) {
imageCache.setObject(downloadedImage, forKey: urlString)
self.image = downloadedImage
}
})
}).resume()
}
}
Ответ №2:
Лучшая идея — хранить разных пользователей в массиве пользователей, в котором User является структурой.
struct User {
var name: String = ""
var id: String = ""
}
Затем в вашем ViewController вы загружаете содержимое из своей Firebase и создаете модели своей пользовательской структуры.
let users: [User] = []
yourFireBaseQueryFunc() {
...
postRef.observe(.childAdded, with: { (snapshot) in
for item in snapshot {
let name = snapshot.value!.object(forKey: "author") as! String
let id = snapshot.value!.object(forKey: "uid") as! String
let user = User(name: name, id: id)
users.append(user)
}
Затем, например, в a tableView
вы берете indexPath и одну модель из своего массива моделей и вызываете функцию, чтобы получить ссылку на изображение из вашей Firebase:
cellForRowAtIndexPath... {
let user = users[indexPath.row]
let image = getImage(user.id)
let imgURL = NSURL(string: post.picture)
cell.yourImageView.sd_setImageWithURL(imgURL)
}
А затем запросить изображение:
func getImage(userID: String) -> String {
var imageLink: String = ""
let ref = firebase.child("users").child(userID)
ref.observeEventType(.Value, withBlock: { snapshot in
if snapshot.exists() {
imageLink = snapshot.value!.valueForKey("profilePicURL") as! String
}
})
return imageLink
}
Комментарии:
1. Привет, Дэвид, спасибо за ваш быстрый ответ. Однако ваш ответ на самом деле не решает мою проблему.
2. Я использовал другой метод, используя кеш для загрузки изображений.