Return value from completion handler - Swift
I'm using a loadImage method in a Utilities class and am having some trouble with returning images via closures. Basically because my code could return either an image or an error, assigning it to an image property when the method is called will not work.
Is the approach I'm using wrong in the method declaration of the class, or should I be calling the method differently to anticipate potentially differing results? Thanks
public class UtilitiesService: NSObject {
public class func loadImage(urlString:String)
{
var imgURL: NSURL = NSURL(string: urlString)!
let request: NSURLRequest = NSURLRequest(URL: imgURL)
NSURLConnection.sendAsynchronousRequest(
request, queue: NSOperationQueue.mainQueue(),
completionHandler: {(response: NSURLResponse!,data: NSData!,error: NSError!) -> Void in
if error == nil {
self.returnImage(data)
}
})
}
public class func returnImage(imageData: NSData) -> UIImage {
return UIImage(data: imageData)!
}
}
//// view controller
class someView: UIViewController {
var image.image = loadImage(url) ///will throw a return type error
}
Add a handler to your loadImage func:
Swift 3
func loadImage(_ urlString: String, handler:@escaping (_ image:UIImage?)-> Void)
{
let imageURL: URL = URL(string: urlString)!
URLSession.shared.dataTask(with: imageURL) { (data, _, _) in
if let data = data{
handler(UIImage(data: data))
}
}.resume()
}
Call func like this:
loadImage("SomeURL") { (image) -> Void in
if let image = image{
DispatchQueue.main.async {
self.imageView.image = image
}
}
}
Swift 2.3
func loadImage(urlString: String, handler: (image:UIImage?)-> Void)
{
let imageURL: NSURL = NSURL(string: urlString)!
NSURLSession.sharedSession().dataTaskWithURL(imageURL) { (data, _, _) in
if let data = data{
handler(image: UIImage(data: data))
}
}.resume()
}
Call func like this:
loadImage("someURL") { (image) -> Void in
if let image = image{
dispatch_async(dispatch_get_main_queue()) {
self.imageView.image = image
}
}
}
I would do it this way:
public class UtilitiesService: NSObject {
public class func loadImage(urlString:String, completion:(resultImage:UIImage) -> Void)
{
var imgURL: NSURL = NSURL(string: urlString)!
let request: NSURLRequest = NSURLRequest(URL: imgURL)
NSURLConnection.sendAsynchronousRequest(
request, queue: NSOperationQueue.mainQueue(),
completionHandler: {(response: NSURLResponse!,data: NSData!,error: NSError!) -> Void in
if error == nil {
completion(resultImage: UIImage(data: data))
}
})
}
}
//// view controller
class someView: UIViewController {
var image: UIImageView()? //Create the variable the way you need
loadImage(url, completion: { (resultImage) -> Void in
image = resultImage //Assign the result to the variable
})
}
I think this will work, if it doesn't, tell me and I'll fix it