Ошибка миграции Swift 2.0 с alamofire

Я пытаюсь использовать этот фрагмент кода, который я получил raywenderlich.com в Xcode 7. Но в строке возврата выдает ошибку:

Невозможно преобразовать возвращаемое выражение типа (NilLiteralConvertible, NilLiteralConvertible) в возвращаемый тип 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)
  }
}

Исходный код см. на странице http://www.raywenderlich.com/85080/beginning-alamofire-tutorial


person miracle-doh    schedule 17.09.2015    source источник
comment
Трудно дать точный ответ, потому что весь этот проект требует преобразования, и я не знаю, как вы преобразовали библиотеки Alamofire. Для начала я бы попробовал вернуть необязательный UIImage и посмотреть, работает ли это, в идеале вы должны исправить GenericResponseSerializer, чтобы принять как минимум UIImage? необязательно.   -  person Shizam    schedule 17.09.2015
comment
хм, спасибо за ответ, но когда я устанавливаю UIImage в качестве возвращаемого типа, xcode застревает   -  person miracle-doh    schedule 17.09.2015
comment
@miracle-doh ты заставил это работать? я следую тому же учебнику с swift 2.0 и alamofire 3.0, и я получаю 3 встроенных ошибки   -  person alex    schedule 04.10.2015
comment
да, правильный ответ работает. Я использовал это так Alamofire.request(.GET, imageURL).validate(contentType: ["image/*"]).responseImage() { (_, _, result) in guard let image = result.value else { print("could not fetch image value") return } //do stuff with image` }`   -  person miracle-doh    schedule 05.10.2015


Ответы (2)


Похоже, когда вы преобразовали свой проект в Swift 2, вы также обновили его до AlamoFire 2.x. Учебник был написан для Swift 1.2, где подпись закрытия была:

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

Теперь с AlamoFire 2 подпись выглядит так:

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

Это означает, что ваш метод должен возвращать .Success(image!) в случае прохождения условия и .Failure(data, myError) в случае отказа. Это также означает, что вы не можете просто передать изображение без распаковки, поскольку этот инициализатор допускает значение NULL, а параметр результата — нет.

Ваш сериализатор может выглядеть примерно так:

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)
}

Для вашей ошибки вы можете либо определить свое собственное перечисление ErrorType, которое будет вам полезно, либо использовать AlamoFire.Error:

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

Ваша функция responseImage потребует аналогичного изменения:

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

Это, в свою очередь, потребует от вас обновления кода, который использует responseImage, но эти сообщения об ошибках должны быть полезными.

person Brian Nickel♦    schedule 17.09.2015
comment
как изменить часть responseImage? - person miracle-doh; 17.09.2015

У меня это работает, удалите старый Alamofire из образца Рэя и добавьте форму последней версии git https://github.com/Alamofire/Alamofire и измените пример XMLResponseSerializer, для UIImage это выглядит так:

extension Alamofire.Request {
public static func imageResponseSerializer() -> ResponseSerializer<UIImage, NSError> {
    return ResponseSerializer { request, response, data, error in
        guard error == nil else { return .Failure(error!) }
        guard let validData = data else {
            let failureReason = "Image parsing failed."
            let error = Error.errorWithCode(.DataSerializationFailed, failureReason: failureReason)
            return .Failure(error)
        }
        guard let image = UIImage(data: validData, scale: UIScreen.mainScreen().scale) else {
            let failureReason = "Image format failed."
            let error = Error.errorWithCode(.DataSerializationFailed, failureReason: failureReason)
            return .Failure( error)
        }
        return .Success(image)
    }
}
public func responseImage(completionHandler: Response<UIImage, NSError> -> Void) -> Self {
    return response(responseSerializer: Request.imageResponseSerializer(), completionHandler: completionHandler)
}
}
person Simon Ggettrick    schedule 15.10.2015