Nesting of data tasks in Swift

Viewed 30

I am currently learning Swift for my upcoming internship and I would like some feedback on nesting data tasks. Here I am trying to fetch a JSON that contains the url to an image and then fetch the image from the url. Is this solution acceptable ?

Thank you for your feedback

func fetchImageOfTheDay() {
    guard let url = URL(string: "\(pictureOfTheDayUrl)?api_key=\(api_key)") else {
        fatalError()
    }
    
    URLSession.shared.dataTask(with: url) { data, response, error in
        guard let data = data else {
            return
        }
        let decoder = JSONDecoder()
        guard let imageText = try? decoder.decode(ImageOfTheDay.self, from: data) else {
            fatalError()
        }
        guard let imageUrl = URL(string: imageText.url) else {
            fatalError()
        }
        
        URLSession.shared.dataTask(with: imageUrl) { data, response, error in
            guard let data = data else {
                return
            }
            guard let image = UIImage(data: data) else {
                fatalError()
            }
            DispatchQueue.main.async {
                self.imageOfTheDay = image
                self.imageText = imageText
            }
            
        }.resume()
    }.resume()
    
    
} 
1 Answers

Architecturally it could've been better and you definitely should consider:

  • breaking it up into 2 separate methods
  • further separating the code into separate classes, building an hierarchy of services that depend on each other
  • separating the usage of the results of your data tasks from their retrieval
  • improving on the error handling, retaining the reasons for the failure

But otherwise, yeah, it's fine to create and resume a dataTask inside another dataTask's completion handler.

Related