Downloading Image

I am trying to download an image into a table view cell. I have a class the parses data and performs a network request called Article Manger. I also extended the UIImage View to download the image; however, I keep getting an error that says "Variable 'image' used before being initialized." How can I fix this?

https://github.com/lexypaul13/Covid-News
Code Block
extension UIImageView {
    func downloadImage( url: String){
        let news = ArticleManger()
        news.performRequest(urlString: url)
        DispatchQueue.main.async {
            var image:Data
            self.image = UIImage(data: image)
        }  
    }

How can I fix this?

The error message is saying: Variable 'image' used before being initialized.
You need to initialize the variable image before it is used.

Code Block
            var image:Data = ???


Many things depend on ArticleManger, but you may need to use completion handler to fill ??? and to fix some other parts.


You should better include core parts of your code as text. A link to a full project is helpful for readers who have decided to resolve your issue, but it is not so attracting for many readers who do not want to go deep into a link.
Probably your image is what you get from url ?

if so, initialize the image from url.

https://stackoverflow.com/questions/24231680/loading-downloading-image-from-url-on-swift
@Claude31 Thanks for the response. Below is the core part of the code. As mentioned before, I have a Network Manager class that connects to the server and parses the data. Since I've been able to encapsulate the session into a function called performrequest,
How can I initialize the value of Image to download the images from the server ?

Code Block
//Data Model
class ArticlesData: NSObject {
    var author: String?
    var title: String?
    var publishedAt: String?
    var urlImage: String?
    var urlWebsite : String?
}
//Network Manger
class ArticleManger{
    let website = http://newsapi.org/v2/everything?q=coronavirus&sortBy=popularity&apiKey=d&pageSize=50&page=2
   
var articles: [ArticlesData]? = [] // holds array of model object
    func fetchArticles() {
        performRequest(urlString: website)
    }
       func performRequest(urlString: String){
        if let url = URL(string: website) {
            let session = URLSession(configuration: .default)
            let task = session.dataTask(with: url) { (data, response, error) in
                if error != nil{
                    print(error ?? 0)
                    return
                }
                if let data = data {
                    self.articles = self.parseData(data: data)
          }
            }
            task.resume()
            return
        }
    }
func parseData(data :Data)->[ArticlesData]?  {
  do {
let jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary
let jsonArticles = jsonResult?["articles"] as? [AnyObject] ?? [] // gets first head of json file and converts it to dictionary
let article = ArticlesData()
     for jsonArticle in jsonArticles{ // captures data and stores it in the model object
                article.author = jsonArticle["author"] as? String
                article.title = jsonArticle["description"] as? String
                article.publishedAt = jsonArticle["publishedAt"] as? String
                article.urlImage = jsonArticle["urlToImage"] as? String
                article.urlWebsite = jsonArticle["url"] as? String
                articles?.append(article) //put article data in the array
            }
            print(jsonArticles)
        }catch{
           print("\(error)")
        }
        return articles ?? []
    }
}
class LatestNewsViewController: UIViewController {
 //Website API
    let website = "http://newsapi.org/v2/everything?q=coronavirus&sortBy=popularity&apiKey=&pageSize=50&page=2" //Website API
    var urlSelected = ""
    var news = ArticleManger()
   
    //
    @IBOutlet weak var table_view: UITableView!
    //
    override func viewDidLoad() {
        super.viewDidLoad()
        news.fetchArticles()
        table_view.dataSource = self
    }
    
extension UIImageView {
    func downloadImage( url: String){
        let news = ArticleManger()
        news.performRequest(urlString: url)
        DispatchQueue.main.async {
            var image:Data
            self.image = UIImage(data: image)
        }
        
    }

Accepted Answer
With proper indentation, code is much easier to read.

Code Block
// Data Model
class ArticlesData: NSObject {
var author: String?
var title: String?
var publishedAt: String?
var urlImage: String?
var urlWebsite : String?
}
// Network Manger
class ArticleManger{
let website = "http ://newsapi .org/v2/everything?q=coronavirus&sortBy=popularity&apiKey=d&pageSize=50&page=2"
// I edited to be able to post on forum
var articles: [ArticlesData]? = [] // holds array of model object
func fetchArticles() {
performRequest(urlString: website)
}
func performRequest(urlString: String){
if let url = URL(string: website) {
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
if error != nil{
print(error ?? 0)
return
}
if let data = data {
self.articles = self.parseData(data: data)
}
}
task.resume()
return
}
}
func parseData(data :Data)->[ArticlesData]? {
do {
let jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary
let jsonArticles = jsonResult?["articles"] as? [AnyObject] ?? [] // gets first head of json file and converts it to dictionary
let article = ArticlesData()
for jsonArticle in jsonArticles{ // captures data and stores it in the model object
article.author = jsonArticle["author"] as? String
article.title = jsonArticle["description"] as? String
article.publishedAt = jsonArticle["publishedAt"] as? String
article.urlImage = jsonArticle["urlToImage"] as? String
article.urlWebsite = jsonArticle["url"] as? String
articles?.append(article) //put article data in the array
}
print(jsonArticles)
} catch {
print("\(error)")
}
return articles ?? []
}
}
class LatestNewsViewController: UIViewController {
//Website API
let website = "http://newsapi.org/v2/everything?q=coronavirus&sortBy=popularity&apiKey=&pageSize=50&page=2" //Website API
var urlSelected = ""
var news = ArticleManger()
//
@IBOutlet weak var table_view: UITableView!
//
override func viewDidLoad() {
super.viewDidLoad()
news.fetchArticles()
table_view.dataSource = self
}
extension UIImageView {
func downloadImage( url: String){
let news = ArticleManger()
news.performRequest(urlString: url)
DispatchQueue.main.async {
var image:Data
self.image = UIImage(data: image)
}
}


There are several errors here:
line 58: you need to declare the class LatestNewsViewController to conform to UITableViewDataSource protocol (otherwise, error on line 70) and implement the required delegate functions.

line 73: extension must not be inside a class.

You asked

How can I initialize the value of Image to download the images from the server ?

If I understand your code, data are loaded by performRequest. Exact ?

Code Block
func performRequest(urlString: String) { }

loads self.articles.
What is not clear, is which article you want to use image from ?
What you get are images url (no image data at all yet):
So, if you want to get the image of first article:
Code Block
let imageOfFirst = self.articles[0].urlImage ?? !!

Then load
var image by reading this from the url.
Thanks for the solution. Just to clarify would I place the let imageOfFirst = self.articles[0].urlImage ?? !! in perform request function ? If so how would I access it in the extension UIImage ? Also, how do I properly indent code before submitting it ? @Claude31 
Downloading Image
 
 
Q