UITableViewCell Image not loading - uitableview

I want to download images from firebase storage and load it in the tableview but it is not working.
My downloadUrl is right and there is no error.
URLSession.shared.dataTask(with: downloadURL) { (data, response, error) in
if error != nil {
print(error?.localizedDescription)
return
}
DispatchQueue.main.async {
if let downloadedImage = UIImage(data: data!) {
cell.imageView?.image = downloadedImage
}
}
}

Why not just use Firebase Storage's built in download mechanisms for this?
let httpsReference = FIRStorage.storage().referenceForURL('https://firebasestorage.googleapis.com/b/bucket/o/images%20stars.jpg') // your download URL
httpsReference.dataWithMaxSize(1 * 1024 * 1024) { (data, error) -> Void in
if (error != nil) {
// Uh-oh, an error occurred!
} else {
// Data for "images/stars.jpg" is returned
let starsImage: UIImage! = UIImage(data: data!)
cell.imageView.image = starsImage // by default, callbacks are raised on the main thread so this will work
}
}

Related

I want to pick video from Imagepicker then I want to send video in firebase and retrieve it

I want to pick video from Images Picker then I want to send video in firebase and retrieve it Please provide code in swift 5, i write code also for sending video on firebase
func downloadImages(folderPath:String,success:#escaping (_ image:UIImage)->(),failure:#escaping (_ error:Error)->()){
// Create a reference with an initial file path and name
let reference = Storage.storage().reference(withPath: "\(folderPath)")
reference.getData(maxSize: (1 * 1024 * 1024 * 1024 * 1024 * 1024)) { (data, error) in
if let _error = error{
print(_error)
failure(_error)
} else {
if let _data = data {
let myImage:UIImage! = UIImage(data: _data)
success(myImage)
}
}
}
}
Upload video On firebase Storage is
func upload(file: URL, completion: #escaping ((_ url : URL?) -> ())) {
let name = "\(Int(Date().timeIntervalSince1970)).mp4"
do {
let data = try Data(contentsOf: file)
let storageRef =
Storage.storage().reference().child("Videos").child(name)
if let uploadData = data as Data? {
let metaData = StorageMetadata()
metaData.contentType = "video/mp4"
storageRef.putData(uploadData, metadata: metaData
, completion: { (metadata, error) in
if let error = error {
completion(nil)
}
else{
storageRef.downloadURL { (url, error) in
guard let downloadURL = url else {
completion(nil)
return
}
completion(downloadURL)
}
print("success")
}
})
}
}catch let error {
print(error.localizedDescription)
}
}
and Get Video From firebase
let reference = Storage.storage().reference().child("Videos").child(folderPath)
reference.getData(maxSize: INT64_MAX) { (data, error) in
if let error = error {
print("Error downloading image data: \(error)")
return
}
reference.getMetadata(completion: { (metadata, metadataErr) in
if let error = metadataErr {
print("Error downloading metadata: \(error)")
return
}
else {
reference.downloadURL { URL, error in
completion(URL)
print(URL)
}

Firebase: Returning a UIImage from URL returns void

Just wondering if anyone knows why my below code returns void instead of a UIImage.
func getImageFromURL(imageURL : String) -> UIImage {
let ref = Storage.storage().reference(forURL: imageURL)
ref.getData(maxSize: 2 * 1024 * 1024) { (data, error) in
if error != nil {
print("ERROR: Image not downloaded from Firebase.")
} else {
print("SUCCESS: Image downloaded from Firebase Storage")
let img = UIImage(data: data!)
return img
}
}
}

Swift Firebase Storage.storage().reference(forURL: ) not working

Suddenly my reference to to my Storage to retrieve images to share is not working anymore. It was literally just working 30 minutes ago but being very inconsistent. Do I have to add new security rules or something? But I guess welcome to programming where code magically stops working lol.
let ref = Storage.storage().reference(forURL: pictureImage)
ref.getData(maxSize: 2 * 1024 * 1024, completion: {(data, error) in
if error != nil {
print("image could not be downloaded")
} else {
if let imgData = data {
if let img = UIImage(data: imgData) {
objectsToShare.append(img)
print("image downloaded")
}
}
}
})
Update
When I use this call it works, yet my "getData" call has stopped working...
let storageRef = Storage.storage().reference(forURL: pictureImage)
storageRef.delete(completion: { error in
if let error = error {
print(error)
} else {
print("Successful Delete")
}
})
Same is working for me
func downloadImageUserFromFirebase(Link:String) {
let storageRef = Storage.storage().reference(forURL: Link)
storageRef.getData(maxSize: 2 * 1024 * 1024) { (data, error) in
if error == nil {
if let imgData = data {
if let img = UIImage(data: imgData) {
print("got imagedata \(String(describing: imgData))")
// objectsToShare.append(img)
print("image downloaded")
}
}
} else {
print("ERROR DOWNLOADING IMAGE : \(String(describing: error))")
}
}
}
Seems like you Had made some changes in your Rules
Well for me the problem was that I was missing the -ObjC flag in Other linker flags in my app's build settings.

ContentsOfURL returns nil in swift 2.0 from a perfectly valid URL

I am trying to fetch an image from a URL but the contentsOfURL method keeps returning nil. The url is legal and has only one image.
I have tried the dispatch_get_global_queue method and also the method described below. The NSData value is always nil no matter how many times i run. i have already tried restarting the simulator as well. The network is also fast and there are no issues with the network.
This is the part of the code that is failing
var imageURL : NSURL(string : "https://www.nasa.gov/sites/default/files/wave_earth_mosaic_3.jpg")
if let url = imageURL{
spinner?.startAnimating()
let request = NSURLRequest(URL: url)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){(data,response,error) -> Void in
self.imageData = NSData(contentsOfURL: url)
}
dispatch_async(dispatch_get_main_queue()){
if url == self.imageURL{
self.image = UIImage(data: self.imageData!)
}
else{
}
}
task.resume()
}
This is how your function should look like. No need for GCD.
There is also no need for let task = .... and NSData(contentsOfURL: url) downloads the image again as Eric D stated.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var imageURL = "https://www.nasa.gov/sites/default/files/wave_earth_mosaic_3.jpg"
loadImage(fromUrl: imageURL) { (image, error) in
if let image = image {
print("got an image")
} else {
print("got an error")
}
}
}
// pretty function that takes a string and a callback
// it sends either an image or an error back through the callback
func loadImage(fromUrl urlString: String, completion:(image:UIImage?,error:NSError?) -> Void) {
guard let url = NSURL(string:urlString) else {
// invalid url
completion(image: nil,error: nil)
return
}
let request = NSURLRequest(URL: url)
NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) in
if let error = error {
completion(image: nil,error: error)
return
}
guard let data = data, image = UIImage(data:data) else {
// no connection error, but no image extracted from data
return completion(image: nil, error: nil)
}
completion(image: image, error: nil)
}.resume()
}
}

I am calling a url of the image from the webservice. The image is not loaded to uitableview

During the debugging of the code I tested the URL, that url works in the browser and the image is displayed in the browser. But the below code is not loading the image to the image wrapper.
let row = indexPath.row
cell.NewsHeading.font =
UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline)
cell.NewsHeading.text = SLAFHeading[row]
if let url = NSURL(string: SLAFImages[indexPath.row]) {
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) -> Void in
if error != nil {
print("thers an error in the log")
} else {
dispatch_async(dispatch_get_main_queue()) {
cell.NewsImage.image = UIImage(data: data!)
}
}
}
task.resume()
}
return cell
As explained in the comments, you can't return from an asynchronous task - you can't know when the task will be complete and when the data will be available.
The way to handle this in Swift is to use callbacks, often called by convention "completion handlers".
In this example I create a function to run the network task, and this function has a callback for when the image is ready.
You call this function with a syntax named "trailing closure" and there you handle the result.
Here's an example for you.
The new function:
func getNewsImage(stringURL: String, completion: (image: UIImage)->()) {
if let url = NSURL(string: stringURL) {
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) -> Void in
if error != nil {
print(error!.localizedDescription)
} else {
if let data = data {
if let image = UIImage(data: data) {
completion(image: image)
} else {
print("Error, data was not an image")
}
} else {
print("Error, no data")
}
}
}
task.resume()
}
}
Your elements from your example:
let row = indexPath.row
cell.NewsHeading.font = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline)
cell.NewsHeading.text = SLAFHeading[row]
And how you call the new function:
getNewsImage(SLAFImages[indexPath.row]) { (image) in
dispatch_async(dispatch_get_main_queue()) {
cell.NewsImage.image = image
// here you update your UI or reload your tableView, etc
}
}
It's just an example to show how it works, so you might have to adapt to your app, but I believe it demonstrates what you need to do.

Resources