【问题标题】:Retrieving image from firebase? (swift)从firebase检索图像? (迅速)
【发布时间】:2016-05-05 16:52:49
【问题描述】:

所以我有一个如下图 的firebase 结构@

现在我想检索我上传的那个图像文件。解码 base64String 并显示它。每个用户都可以发帖,发送到 firebase 的信息有描述等,还有图片。现在我试图用这段代码检索它,但没有任何效果。

var REF_LIST = Firebase(url: "\(URL_BASE)/listItems")

REF_LIST.observeEventType(FEventType.Value, withBlock: { snapshot in
let image = snapshot.value.objectForKey("images") as! String

但这已经在该行上给了我一个 nil 错误,所以我什至无法解码。我想我明白为什么它给我一个 nil 错误,firebase 上的 listItems 中没有图像,你首先有唯一的 ID,然后是带有图像的规格。现在我不知道如何从那个唯一的信息中检索该信息身份证?

更新: tableViewController 将从 firebase 接收数据:

import UIKit
import FBSDKLoginKit
import Alamofire
import Firebase

class ListVC: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var tableView: UITableView!

    var lists = [List]()

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.delegate = self
        tableView.dataSource = self

        dispatch_async(backgroundQueue, {
        self.initObservers()
        })

    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        self.tableView.reloadData()

    }

    func initObservers() {

        LoadingOverlay.shared.showOverlay(self.view)

           DataService.ds.REF_LISTS.observeEventType(.Value, withBlock: { snapshot in
                print(snapshot.value)

                self.lists = []

                if let snapshots = snapshot.children.allObjects as? [FDataSnapshot] {


                    for snap in snapshots {
                        print("SNAP: \(snap)")

                        if let listDict = snap.value as? Dictionary<String, AnyObject> {
                            let key = snap.key
                            let list = List(listKey: key, dictionary: listDict)
                            self.lists.insert(list, atIndex:0)
                        }
                    }
                }

                self.tableView.reloadData()
                LoadingOverlay.shared.hideOverlayView()

            })
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return lists.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        if let cell = tableView.dequeueReusableCellWithIdentifier("ListCell") as? ListCell {
            let list = self.lists[indexPath.row]

            cell.request?.cancel()

            cell.configureCell(list)

            return cell

        } else {

            return ListCell()
        }

    }

}

将数据发布到 firebase 的 addController:

import UIKit
import Firebase
import Alamofire
import FBSDKCoreKit

class AddVC: UIViewController, UITextFieldDelegate, UITextViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    @IBOutlet weak var addTitle: UITextField!
    @IBOutlet weak var addDescription: UITextView!
    @IBOutlet weak var addLocation: UITextField!
    @IBOutlet weak var placeholderLbl: UILabel!
    @IBOutlet weak var freeSwitch: UISwitch!
    @IBOutlet weak var tradeSwitch: UISwitch!
    @IBOutlet weak var imageSelectorImg: UIImageView!
    @IBOutlet weak var overlayView: UIView!

    var currentUsername = ""
    var imageSelected = false
    var imagePicker: UIImagePickerController!
    var base64String: NSString = ""

    override func viewDidLoad() {
        super.viewDidLoad()

        addTitle.delegate = self
        addDescription.delegate = self
        addLocation.delegate = self

        imagePicker = UIImagePickerController()
        imagePicker.delegate = self


        getCurrentUser()
        hideKeyboardWhenTappedAround()
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

        addTitle.text = ""
        addDescription.text = ""
        addLocation.text = ""
        freeSwitch.setOn(false, animated: false)
        tradeSwitch.setOn(false, animated: false)
        placeholderLbl.hidden = false
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func getCurrentUser() {
        DataService.ds.REF_USER_CURRENT.observeEventType(FEventType.Value, withBlock: { snapshot in

            let currentUser = snapshot.value.objectForKey("username") as! String

            print("Username: \(currentUser)")
            self.currentUsername = currentUser }, withCancelBlock: { error in
                print(error.description)
        })
    }

    func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
        imagePicker.dismissViewControllerAnimated(true, completion: nil)
        imageSelectorImg.image = image
        dispatch_async(backgroundQueue, {
        let uploadImage = image
        let imageData = UIImageJPEGRepresentation(uploadImage, 0.5)
        self.base64String = imageData!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength)
        })

        imageSelected = true
    }

    @IBAction func selectImage(sender: UITapGestureRecognizer) {
        presentViewController(imagePicker, animated: true, completion: nil)
    }


    func postToFirebase() {

        // LoadingOverlay.shared.showOverlay(self.overlayView)
        var post: Dictionary<String, AnyObject> = ["username": self.currentUsername, "description": self.addDescription.text!, "title": self.addTitle.text!, "location": self.addLocation.text!, "images": self.base64String]

        if self.freeSwitch.on && self.tradeSwitch.on {
            post["tradeOption"] = "Gratis/Te ruil"
        } else if self.freeSwitch.on {
            post["tradeOption"] = "Gratis"
        } else if self.tradeSwitch.on {
            post["tradeOption"] = "Te ruil"
        }

        let firebasePost = DataService.ds.REF_LISTS.childByAutoId()
        firebasePost.setValue(post)

    }


    @IBAction func postListItem(sender: AnyObject) {

        if let addTitle = addTitle.text where addTitle != "", let addDescription = addDescription.text where addDescription != "", let addLocation = addLocation.text where addLocation != "" {

            dispatch_async(backgroundQueue, {
                self.postToFirebase()

                dispatch_async(dispatch_get_main_queue(), { () -> Void in

                    let storyboard = UIStoryboard(name: "Main", bundle: nil)
                    let listVC = storyboard.instantiateViewControllerWithIdentifier("TBC") as! UITabBarController
                    listVC.selectedIndex = 1
                    self.presentViewController(listVC, animated: false, completion: nil)
                })
            })
        }
    }

    func textViewDidBeginEditing(textView: UITextView) {
        placeholderLbl.hidden = true
    }

    func textViewDidEndEditing(textView: UITextView) {
        if textView.text == "" {
            placeholderLbl.hidden = false
        }
    }

    func textFieldShouldReturn(textField: UITextField) -> Bool {
        textField.resignFirstResponder()

        return true
    }

}

以及配置单元格的 swift 文件:

import UIKit
import Alamofire
import Firebase

class ListCell: UITableViewCell {

    @IBOutlet weak var listImg: UIImageView!
    @IBOutlet weak var listTitle: UILabel!
    @IBOutlet weak var listTradeOption: UILabel!
    @IBOutlet weak var listLocation: UILabel!
    @IBOutlet weak var headImg: UIImageView!

    var list: List!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    func retrieveImages() {
    DataService.ds.REF_LISTS.observeEventType(FEventType.Value, withBlock: { snapshot in

        if let snapshots = snapshot.children.allObjects as? [FDataSnapshot] {

            for snap in snapshots {
                let image = snap.value.objectForKey("images") as! String

                let decodedData = NSData(base64EncodedString: image, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)
                let decodedImage = UIImage(data: decodedData!)
                self.headImg.image = decodedImage

            }
        }

    })
}

func configureCell(list: List) {

    self.list = list
    self.listTitle.text = list.listTitle
    self.listTradeOption.text = list.listTradeOption
    self.listLocation.text = list.listLocation
    retrieveImages()

}

}

还有模型文件列表:

import Foundation
import Firebase

class List {
    private var _listTitle: String!
    private var _listDescription: String!
    private var _listTradeOption: String!
    private var _listLocation: String!
    private var _listImageURL: String?
    private var _listKey: String!
    private var _listRef: Firebase!

    var listTitle: String? {
        return _listTitle
    }

    var listDescription: String? {
        return _listDescription
    }

    var listTradeOption: String? {
        return _listTradeOption
    }

    var listLocation: String? {
        return _listLocation
    }

    var listKey: String {
        return _listKey
    }

    var listImageURL: String? {
        return _listImageURL
    }

    init(title: String, description: String, tradeOption: String, location: String, listImageURL: String?) {
        self._listTitle = title
        self._listDescription = description
        self._listTradeOption = tradeOption
        self._listLocation = location
        self._listImageURL = listImageURL
    }

    init(listKey: String, dictionary: Dictionary<String, AnyObject>) {
        self._listKey = listKey

        if let title = dictionary ["title"] as? String {
            self._listTitle = title
        }

        if let desc = dictionary ["description"] as? String {
            self._listDescription = desc
        }

        if let trade = dictionary ["tradeOption"] as? String {
            self._listTradeOption = trade
        }

        if let loc = dictionary ["location"] as? String {
            self._listLocation = loc
        }

        if let imgUrl = dictionary["images"] as? String {
            self._listImageURL = imgUrl
        }

        self._listRef = DataService.ds.REF_LISTS.childByAppendingPath(self._listKey)
    }

}

我还有一个 DataServicefile,我使用以下代码通过唯一 ID 创建一个用户:

var REF_USER_CURRENT: Firebase {
        let uid = NSUserDefaults.standardUserDefaults().valueForKey(KEY_UID) as! String
        let user = Firebase(url: "\(REF_BASE)").childByAppendingPath("users").childByAppendingPath(uid)
        return user!
    }

    func createFirebaseUser(uid: String, user: Dictionary<String, String>) {
        REF_USERS.childByAppendingPath(uid).setValue(user)
    }

我知道这很多,但也许是最好的帮助方式:)

【问题讨论】:

    标签: swift image firebase


    【解决方案1】:

    尝试在列表单元格中编辑它

    var imageURL = String()
    
    
    func retrieveImages() {
    
    let decodedData = NSData(base64EncodedString: imageURL, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)
    let decodedImage = UIImage(data: decodedData!)
    self.headImg.image = decodedImage
    
    }
    
    func configureCell(list: List) {
    
    self.list = list
    self.listTitle.text = list.listTitle
    self.listTradeOption.text = list.listTradeOption
    self.listLocation.text = list.listLocation
    self.imageURL = list.listImageURL //you already had the image url for that specific cell
    
    retrieveImages()
    
    }
    

    【讨论】:

    • 我真的不明白你在说什么......我对此很陌生:p 我将用这种情况下所需的 .swift 文件更新我的问题。或许你可以给我解释一下?
    • 好的,那我再看看,尽力帮助你
    • 你第一次说你收到错误的那一行在哪里?我在您更新的代码中找不到它。您的意思是您在本节中遇到错误:' for snap in snapshots { print("SNAP: (snap)") if let listDict = snap.value as? Dictionary { let key = snap.key let list = List(listKey: key, dictionary: listDict) self.lists.insert(list, atIndex:0) } }'
    • 不抱歉,我尝试了我在配置单元格中的问题中首先提出的代码行,并且还在 cellForRowAtIndexPath 中尝试了它。但因为它不起作用,我将其删除了..如果你愿意,我可以像我一样再次更新它吗?
    • 我已经更新了我的文件代码,以我尝试过的另一种方式配置单元格,这会带来图片,但所有图片都与 firebase 上最后上传的图片相同......之前我在 func retrieveImages() 中使用我的“第一个”问题的代码进行了尝试
    【解决方案2】:
    • 在 firebase 中使用 base64String 存储和访问图像不是 有效的方法,我们可以使用 FirebaseStorage (Google 云存储 bucket) 用于将图像上传到 Firebase,它将为我们提供 特定图像的下载 URL。我们可以将该 URL 简单地以字符串格式存储到我们的数据库中,并在我们随时访问它 需要,然后从该 URL 下载相应的图像 使用 SDWebImage
    • 请参阅以下链接以将 FirebaseStorage 集成到您的项目中:https://firebase.google.com/docs/storage/ios/upload-files

    【讨论】:

    • Firebase 提供的这项功能将为我们上传的图片提供 google 安全性。
    猜你喜欢
    • 1970-01-01
    • 2016-02-12
    • 2017-12-17
    • 2020-08-05
    • 2017-12-22
    • 2022-01-22
    • 2020-06-14
    • 2020-10-23
    • 2017-08-30
    相关资源
    最近更新 更多