adams.s adams.s - 6 months ago 218
Swift Question

Retrieving image from firebase? (swift)

So i have a firebase structure like the pic below enter image description here

Now i want to retrieve that image file that i've uploaded. to decode the base64String and show it. Every user can make a post and the information that will be sended to firebase has a description etc. and also have an image. now i tried to retrieve it whit this codes but nothing did work.

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

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


but this already gave me a nil error on that line, so i couldn't even decode. i think i understand why it's giving me a nil error, there is no images in listItems on firebase, you first have the unique ID and then the specs with images in. now i don't now how i can retrieve that information from that unique ID?

UPDATE:
the tableViewController what will receive the data from 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()
}

}

}


the addController which post the data to firebase:

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
}

}


and the swift file to configure the cell:

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()

}


}

also the list Model file:

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)
}

}


i've got also a DataServicefile, where i create a user by unique ID with this code:

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)
}


i know it's a lot but maybe the best way to help :)

Answer

Try editing this in List Cell

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()

}
Comments