Search code examples
iosswiftswift2alamofire

Swift 2.0 migration error with alamofire


I am trying to use this piece of code I got raywenderlich.com in Xcode 7. But at the return line is giving me error saying

Cannot convert return expression of type (NilLiteralConvertible, NilLiteralConvertible) to return type Result<UIImage>

extension Alamofire.Request {
  public static func imageResponseSerializer() -> GenericResponseSerializer<UIImage> {
    return GenericResponseSerializer { request, response, data in
      if data == nil {
        return (nil, nil)
      }

      let image = UIImage(data: data!, scale: UIScreen.mainScreen().scale)

      return (image, nil)
    }
  }

  public func responseImage(completionHandler: (NSURLRequest, NSHTTPURLResponse?, UIImage?, NSError?) -> Void) -> Self {
    return response(responseSerializer: Request.imageResponseSerializer(), completionHandler: completionHandler)
  }
}

See original code at http://www.raywenderlich.com/85080/beginning-alamofire-tutorial


Solution

  • It looks like when you converted your project to Swift 2 you also upgraded to AlamoFire 2.x. The tutorial was written for Swift 1.2 where the closure's signature was:

    (NSURLRequest?, NSHTTPURLResponse?, NSData?) -> (SerializedObject?, NSError?)
    

    With AlamoFire 2 the signature is now:

    (NSURLRequest?, NSHTTPURLResponse?, NSData?) -> Result<SerializedObject>
    

    This means your method needs to return .Success(image!) in the passing condition and .Failure(data, myError) in the failing condition. It also means you can't just pass image without unwrapping since that initializer is nullable and the result's parameter is not.

    Your serializer could look something like this:

    return GenericResponseSerializer { request, response, data in
        guard let validData = data else {
            let error = ...
            return .Failure(data, error)
        }
    
        guard let image = UIImage(data: validData, scale: UIScreen.mainScreen().scale) else {
            let error = ...
            return .Failure(data, error)
        }
    
        return .Success(image)
    }
    

    For your error you could either define your own ErrorType enum that will be helpful to you or use AlamoFire.Error:

    let error = Error.errorWithCode(.DataSerializationFailed, failureReason: "Image parsing failed.")
    

    Your responseImage function will need a similar change:

    public func responseImage(completionHandler: (NSURLRequest?, NSHTTPURLResponse?, Result<UIImage>) -> Void) -> Self {
        return response(responseSerializer: Request.imageResponseSerializer(), completionHandler: completionHandler)
    }
    

    This will in turn require you to update code that uses responseImage but those error messages should be helpful.