4

I have an extension allowing me to download images to my UITableView from API.

extension UIImageView {

    func donwloadImage(from url: String) {
        let urlRequest = URLRequest(url: URL(string: url)!)
        let task = URLSession.shared.dataTask(with: urlRequest) { (data,response,error) in

            if error != nil {
                print(error)
                return
            }

            DispatchQueue.main.async {
                self.image = UIImage(data: data!)

            }
        }
        task.resume()
    }

}

The app crashes if imageUrl is nil.

How do I wrap it using ?? so the UIImageView is just blank if there’s no image?

This is a data model and fetch data function

class Article: NSObject {

    var headline: String?
    var date: String?
    var imageUrl: String?
    var desc: String?
    var url: String?

} 

@objc func fetchArticles() {
        let urlRequest = URLRequest(url: URL(string: "https://newsapi.org/v2/everything?pageSize=15&sortBy=publishedAt&apiKey=API_KEY")!)

let task = URLSession.shared.dataTask(with: urlRequest) { (data,response,error) in

            if error != nil {
                print(error)
                return
            }

            self.articles = [Article]()
            do {
                let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: AnyObject]

                if let articlesFromJson = json["articles"] as? [[String: AnyObject]] {
                    for articlesFromJson in articlesFromJson {
                        let article = Article()
                        if
                            let title = articlesFromJson["title"] as? String,
                            let publishedAt = articlesFromJson["publishedAt"] as? String,
                            let urlToImage = articlesFromJson["urlToImage"] as? String,
                            let description = articlesFromJson["description"] as? String,
                            let url = articlesFromJson["url"] as? String

                        {

                            article.headline = title
                            article.date = publishedAt
                            article.imageUrl = urlToImage
                            article.desc = description
                            article.url = url


                        }
                        self.articles?.append(article) // and so on...
Russ
  • 99
  • 1
  • 7
  • 2
    You cannot assign a default value in `URL(string:` unless the string represents a **valid** URL to a placeholder image. – vadian Feb 02 '20 at 20:05
  • maybe i can provide some google 'empty image' url as a default value? – Russ Feb 02 '20 at 20:14
  • “The app crashes if `imageUrl` is `nil`.” ... Yet, in your code snippet, there is no `imageUrl`. Perhaps you can share a code snippet with `imageUrl`, showing us where’s it is crashing. But the typical pattern would be `imageView.image = nil; if let url = imageUrl { ... }`. Or, if you don’t want to set the `image` to `nil`, use some placeholder image that you have in your project. – Rob Feb 02 '20 at 20:36
  • 1
    Needless to say, the `nil`-coalescing operator, `??`, is not the right technique here. Use `if let x = y { ... }` or `guard let x = y else { ... }` patterns. – Rob Feb 02 '20 at 20:41
  • mr Rob i have added more code snippets, pls have a look – Russ Feb 02 '20 at 21:10

1 Answers1

0

I suggest you use a POD that downloads images asynchronously and always leaves an image of placeHolder, look at the following example that uses it:

import SDWebImage

imageView.sd_setImage (
   with: URL (string: "http://www.example.com/image.jpg"), 
   placeholderImage: UIImage (named: "placeholder.png") // define your default Image
)

Link para o POD: https://cocoapods.org/pods/SDWebImage

Hope this helps.