Getting the following error when trying to fetch a remote image.

Hi,

I'm writing code to get a remote image via URL and I get the following error each time. I converted the URL to https as recommended.

This is the error I get.

URL is Optional(https://img.recipepuppy.com/627470.jpg)

2022-03-29 16:27:41.892870+1100 QantasTest[13489:314159] ATS failed system trust 2022-03-29 16:27:41.892949+1100 QantasTest[13489:314159] Connection 3: system TLS Trust evaluation failed(-9802)

2022-03-29 16:27:41.893119+1100 QantasTest[13489:314159] Connection 3: TLS Trust encountered error 3:-9802

2022-03-29 16:27:41.893212+1100 QantasTest[13489:314159] Connection 3: encountered error(3:-9802)

2022-03-29 16:27:41.894548+1100 QantasTest[13489:314159] Task <526F7B9B-ADC8-4D14-8EA6-DEAD629E7C5A>.<0> HTTP load failed, 0/0 bytes (error code: -1200 [3:-9802])

2022-03-29 16:27:41.894666+1100 QantasTest[13489:314182] NSURLConnection finished with error - code -1200

The code I use is:

 print("URL is \(String(describing: self.thumbNailUrl))")

DispatchQueue.global().async { [weak self] in

    if let data = try? Data(contentsOf: self!.thumbNailUrl!) {

            if let image = UIImage(data: data) {

                                DispatchQueue.main.async {

                                    self?.imageView.image = image

                                }

                            }

                        }

              }

Any suggestions?

Cheers Richard

Answered by DTS Engineer in 708765022

First up, don’t use Data(contentsOf:) with network URLs. That’s a synchronous API and it blocks the current thread waiting for the results. Thread are expensive and you don’t want to waste them in this way.

Rather, you should use a URLSession asynchronous API. There are two approaches you can take here:


Second, don’t use the global concurrent queue (DispatchQueue.global().async) as a source of serialisation. Dispatch only has a limited number of worker threads and if you do stuff like this you run the risk of exhausting that pool (iOS) or causing thread explosion (macOS). Neither is good.

On the plus side, if you switch to URLSession you eliminate this problem.


Neither of the above will fixt fix your actual networking problem. On that front, note the error codes in play. Error -1200 is NSURLErrorSecureConnectionFailed, indicating that something went wrong at the TLS level. Error -9802 is errSSLFatalAlert, which confirms that. Unfortunately this has a variety of potential causes so it’s hard to say for sure what’s going wrong.

Looking at the URL you posted, https://img.recipepuppy.com/627470.jpg, it’s clear that there’s a TLS setup issue on the server side. The certificate returned by the server has a Subject Alternative Name field containing cloudfront.net and *.cloudfront.net, but neither of those match the DNS name you connected to, img.recipepuppy.com.

For more background on how this is meant to work, see my TLS for App Developers post.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Your link is dodgy.
The website has a certificate that is not valid.

Accepted Answer

First up, don’t use Data(contentsOf:) with network URLs. That’s a synchronous API and it blocks the current thread waiting for the results. Thread are expensive and you don’t want to waste them in this way.

Rather, you should use a URLSession asynchronous API. There are two approaches you can take here:


Second, don’t use the global concurrent queue (DispatchQueue.global().async) as a source of serialisation. Dispatch only has a limited number of worker threads and if you do stuff like this you run the risk of exhausting that pool (iOS) or causing thread explosion (macOS). Neither is good.

On the plus side, if you switch to URLSession you eliminate this problem.


Neither of the above will fixt fix your actual networking problem. On that front, note the error codes in play. Error -1200 is NSURLErrorSecureConnectionFailed, indicating that something went wrong at the TLS level. Error -9802 is errSSLFatalAlert, which confirms that. Unfortunately this has a variety of potential causes so it’s hard to say for sure what’s going wrong.

Looking at the URL you posted, https://img.recipepuppy.com/627470.jpg, it’s clear that there’s a TLS setup issue on the server side. The certificate returned by the server has a Subject Alternative Name field containing cloudfront.net and *.cloudfront.net, but neither of those match the DNS name you connected to, img.recipepuppy.com.

For more background on how this is meant to work, see my TLS for App Developers post.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Getting the following error when trying to fetch a remote image.
 
 
Q