First - the problem
The problem is that when run the function loadImages(), all of the UIImage objects except for the last one are being returned as nil. To describe in a little more depth: I have 8 urls of images, the first 7 return nil when decoded, the final url is successfully decoded and returned as a UIImage.
I have tried several things to debug:
Changed the amount of urls returned from the api, still the function consistently returns nil for every URL except for the final url in the array returned from the api.
I also changed the API to return an array of only the url that was successfully decoded into a UIImage object, still the function returned nil for each url except the final url, even though they were all the same URL!
I am really lost on this, sleep deprived, and new to swift, so if any help in figuring out what I am missing would be super helpful! Below I have shared all my code, I really hope this is something small I am missing!
Second - my code
Here I have a network request that is going out and getting a list of image urls that are returned in a json array with a wrapper key of "item"
func fetchImageUrls() {
guard !isLoading else {
return
}
isLoading = true
let resource = ImageUrlsResource()
let request = APIRequest(resource: resource)
self.request = request
request.execute {[weak self] urls in
self?.imageUrls = urls ?? []
self?.isLoading = false
self?.loadImages()
}
}
This returns the image urls and formats them to the array of imageUrls properly. The loadImages function is below:
func loadImages() {
for i in imageUrls {
let url = URL(string: i.url)
print(url)
guard let requestUrl = url else {fatalError()}
let request = URLRequest(url: requestUrl)
let imageRequest = ImageRequest(url: request)
self.imageRequest = imageRequest
imageRequest.execute { [weak self ] image in
print(image) // here is returning nill
let finalImage = FinalImage(id: i.id, image: image ?? nil)
self?.finalImages.append(finalImage)
}
}
}
Here is the image request class
class ImageRequest {
let url: URLRequest
init(url: URLRequest) {
self.url = url
}
}
extension ImageRequest: NetworkRequest {
func decode(_ data: Data) -> UIImage? {
return UIImage(data: data)
}
func execute(withCompletion completion: @escaping (UIImage?) -> Void) {
load(url, withCompletion: completion)
}
}
And the Network request protocol:
protocol NetworkRequest: AnyObject {
associatedtype ModelType
func decode(_ data: Data) -> ModelType?
func execute(withCompletion completion: @escaping (ModelType?) -> Void)
}
extension NetworkRequest {
fileprivate func load(_ url: URLRequest, withCompletion completion: @escaping (ModelType?) -> Void) {
let task = URLSession.shared.dataTask(with: url) {[weak self] (data, response, error) -> Void in
guard let data = data, let value = self?.decode(data) else {
DispatchQueue.main.async {
completion(nil)
}
return
}
DispatchQueue.main.async {
completion(value)
}
}
task.resume()
}
}
Appreciate any help!!
EDIT I added some print statements into the functions at these points
func loadImages() {
for i in imageUrls {
let url = URL(string: i.url)
print(url)
guard let requestUrl = url else {fatalError()}
let request = URLRequest(url: requestUrl)
let imageRequest = ImageRequest(url: request)
self.imageRequest = imageRequest
imageRequest.execute { [weak self ] image in
print(image)
print("fetching the image")
let finalImage = FinalImage(id: i.id, image: image ?? nil)
self?.FinalImages.append(finalImage)
}
}
}
extension ImageRequest: NetworkRequest {
func decode(_ data: Data) -> UIImage? {
print("DATA \(data)")
return UIImage(data: data)
}
func execute(withCompletion completion: @escaping (UIImage?) -> Void) {
load(url, withCompletion: completion)
}
}
here is the output in the console:
Optional(https://dummyimage.com/455x276.png/cc0000/ffffff)
Optional(https://dummyimage.com/455x276.png/cc0000/ffffff)
Optional(https://dummyimage.com/455x276.png/cc0000/ffffff)
Optional(https://dummyimage.com/455x276.png/cc0000/ffffff)
Optional(https://dummyimage.com/455x276.png/cc0000/ffffff)
Optional(https://dummyimage.com/455x276.png/cc0000/ffffff)
Optional(https://dummyimage.com/455x276.png/cc0000/ffffff)
Optional(https://dummyimage.com/455x276.png/cc0000/ffffff)
Optional(https://dummyimage.com/455x276.png/cc0000/ffffff)
Optional(https://dummyimage.com/455x276.png/cc0000/ffffff)
Optional(https://dummyimage.com/455x276.png/cc0000/ffffff)
Optional(https://dummyimage.com/455x276.png/cc0000/ffffff)
Optional(https://dummyimage.com/455x276.png/cc0000/ffffff)
nil
fetching the image
nil
fetching the image
nil
fetching the image
nil
fetching the image
nil
fetching the image
nil
fetching the image
nil
fetching the image
DATA 1297 bytes
nil
fetching the image
nil
fetching the image
nil
fetching the image
nil
fetching the image
nil
fetching the image
Optional(<UIImage:0x60000057d950 anonymous {455, 276}>)
fetching the image