Reputation: 3064
I'm making an application using swift that calls onto a Google Places api to generate a JSON file of locations, including images of the location generated. These images are given as URLs that I need to convert to UIImage and then append these images to an array. When opening the contents of the URL, I am able to see the images, but these images are not appending to the array. Here is my view controller's class that is attempting to generate said images:
import Foundation
import UIKit
import WebKit
class ImageViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
var photos: [Photo]?
var uiImages: [UIImage]?
override func viewDidLoad() {
for photo in photos! {
let url = URL(string:"https://maps.googleapis.com/maps/api/place/photo?photoreference=\(photo.reference)&sensor=false&maxheight=\(photo.height)&maxwidth=\(photo.width)&key=AIzaSyC_SoYT7VnYnyz3GAb7qqbXjZeLFG5GE70")
let data = try? Data(contentsOf: url!)
let image: UIImage = UIImage(data: data!)!
self.uiImages?.append(image)
print(image)
print(self.uiImages)
}
}
}
In this loop, I tell the code to print "image" and then the array "uiImages" after the append occurs. Yet, I am returning nil when printing the array of images, but not nil for the image itself.
I feel this could have something to do with the asynchrony of the method, but I also tried appending on the main thread and this did not change anything. Additionally, the "photos" variable is not nil, it is set when the view controller is instantiated.
Here is the code for the Photo class:
import Foundation
struct Photo {
var height: Int
var width: Int
var reference: String
init?(height: Int, width: Int, reference: String) {
self.height = height
self.width = width
self.reference = reference
}
}
EDIT:
Here is what my ImageViewController class looked like after making the suggested changes:
import Foundation
import UIKit
import WebKit
class ImageViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
var photos: [Photo]?
var uiImages = [UIImage]()
override func viewDidLoad() {
for photo in photos! {
let url = URL(string:"https://maps.googleapis.com/maps/api/place/photo?photoreference=\(photo.reference)&sensor=false&maxheight=\(photo.height)&maxwidth=\(photo.width)&key=AIzaSyC_SoYT7VnYnyz3GAb7qqbXjZeLFG5GE70")
let task = URLSession.shared.dataTask(with: url!) {(data, response, error) in
let image: UIImage = UIImage(data: data!)!
self.uiImages.append(image)
print(image)
print(self.uiImages)
}
task.resume()
}
}
}
Upvotes: 0
Views: 4240
Reputation: 318814
You never initialize your array, you only declare it.
Change:
var uiImages: [UIImage]?
to:
var uiImages = [UIImage]()
Then change:
self.uiImages?.append(image)
to:
self.uiImages.append(image)
On a side note, never load remote data using Data(contentsOf:)
. Use URLSession
and a dataTask
. Your code is going to cause all kinds of problems due to slow remote data access on the main queue.
Upvotes: 5