Search code examples
iosuiimageviewxcplayground

How to update UIImageView after downloading image in Playground


I'm playing around in a Playground trying to better understand async image download and setting.

I'm using an NSURLSession DataTask, and I have the image data coming in great— I can confirm this using the Playground's Quick Look.

I'm also using XCPlayground framework to set the page as needing indefinite execution, and the currentPage's liveView is the target imageView.

Yet, something is still missing, and the live view isn't updating properly. Any ideas? What I want to do is boiled down to the following code. You can see the playground's state in the screenshot:

import UIKit
import XCPlayground

XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

let someImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 256, height: 256))

let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
session.dataTaskWithRequest(NSURLRequest(URL: NSURL(string: "http://www.stridesapp.com/strides-icon.png")!))
    {
        data, response, error in
        if let data = data
        {
            print(data)
            someImageView.image = UIImage(data: data)
        }
    }.resume()

XCPlaygroundPage.currentPage.liveView = someImageView

The state of the Playground


Solution

  • Given that the NSURLSession will not run its completion handler on the main queue, you should dispatch the update of the view to the main queue yourself:

    import UIKit
    import XCPlayground
    
    XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
    
    let someImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 256, height: 256))
    
    let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
    session.dataTaskWithRequest(NSURLRequest(URL: NSURL(string: "http://www.stridesapp.com/strides-icon.png")!)) { data, response, error in
            if let data = data {
                print(data)
                dispatch_async(dispatch_get_main_queue()) {
                    someImageView.image = UIImage(data: data)
                }
            }
        }.resume()
    
    XCPlaygroundPage.currentPage.liveView = someImageView
    

    Thus:

    live view