Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assign a new image to UIImageView with Swift

I'm using Xcode 6 Beta 4, and I'm trying to retrieve a remote image and assign it to a UIImageView. I'm using an NSURLSession dataTask in order to make this asynchronous. Here is my code:

func dataTask(imageUrl: String, targetImage:UIImageView) {

    let nsURL = NSURL(string: imageUrl)

    let task = NSURLSession.sharedSession().dataTaskWithURL(nsURL) {
        (data, response, error) in
        if !error {
            NSLog("No Error!")                
            var image:UIImage = UIImage(data: data)
            targetImage.image = image
        }
        else {
            NSLog("Error!")
        }
    }

    task.resume()
}

this is how i make the call:

        self.dataTask("http://bicicletaspony.com/img/spn/TeamA.png", targetImage: image)

And this is the error i get :(

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Modifications to the layout engine must not be performed from a background thread.'

It's a very simple image assignment. Why does it crash that way?! any help will be much appreciated!

like image 973
Jorge Vicente Mendoza Avatar asked Jul 23 '14 19:07

Jorge Vicente Mendoza


People also ask

How do I add an image to UIImageView?

The first step is to drag the UIImageView onto your view. Then open the UIImageView properties pane and select the image asset (assuming you have some images in your project). You can also configure how the underlying image is scaled to fit inside the UIImageView.

How do I assign an image in Swift?

First one is to drag and drop an image file from Finder onto the assets catalog. Dragging the image will automatically create new image set for you. Drag and drop image onto Xcode's assets catalog. Or, click on a plus button at the very bottom of the Assets navigator view and then select “New Image Set”.


1 Answers

The closure run at the end of dataTaskWithURL is called on a background thread. UIKit (like most other toolkits) can only be called from the main thread. You'll need to set the image on the main thread with something like this:

if !error {
    NSLog("No Error!")             
    var image:UIImage = UIImage(data: data)
    dispatch_async(dispatch_get_main_queue(), {
        targetImage.image = image
    })
}
like image 139
iain Avatar answered Oct 07 '22 08:10

iain