【问题标题】:Alamofire - serializing generic response objects to model from JSON without forced unwrapAlamofire - 将通用响应对象序列化为从 JSON 建模而无需强制解包
【发布时间】:2016-01-25 14:41:17
【问题描述】:

我正在尝试将请求响应(以 JSON 的形式)序列化为模型 - JSON 有时可能会丢失一些属性,因此我尝试使用方法 here 来防止这种情况发生。

然而,模型从模型中抛出了经典的fatal error: unexpectedly found nil while unwrapping an Optional value——模型试图从 responseObject JSON 的 init 调用中强制解包一个非可选值——但是因为它不存在,所以强制解包失败。

从 Alamofire 处理此问题的最佳解决方案是什么?

型号:

final public class User: ResponseObjectSerializable {
    let username: String
    let name: String

    public init?(response: NSHTTPURLResponse, representation: AnyObject) {
        self.username = representation.valueForKeyPath("username") as! String
        self.name = representation.valueForKeyPath("name") as! String
    }
}

Alamofire 请求扩展:

import Foundation
import Alamofire

public protocol ResponseObjectSerializable {
    init?(response: NSHTTPURLResponse, representation: AnyObject)
}

extension Request {
    public func responseObject<T: ResponseObjectSerializable>(completionHandler: Response<T, NSError> -> Void) -> Self {
        let responseSerializer = ResponseSerializer<T, NSError> { request, response, data, error in
            guard error == nil else { return .Failure(error!) }

            let JSONResponseSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
            let result = JSONResponseSerializer.serializeResponse(request, response, data, error)

            switch result {
            case .Success(let value):
                if let
                response = response,
                responseObject = T(response: response, representation: value)
                {
                    return .Success(responseObject)
                } else {
                    let failureReason = "JSON could not be serialized into response object: \(value)"
                    let error = Error.errorWithCode(.JSONSerializationFailed, failureReason: failureReason)
                    return .Failure(error)
                }
            case .Failure(let error):
                return .Failure(error)
            }
        }

        return response(responseSerializer: responseSerializer, completionHandler: completionHandler)
    }
}

客户请求:

Alamofire.request(.GET, requestUrl, parameters: params, encoding: .URL)
        .validate()
        .responseObject { (response: Response<User, NSError>) in
          switch response.result {
            case .Success(let user):

                completionHandler(user, nil)

          case .Failure(let error):
                print("Request failed with error: \(error)")

                completionHandler(nil, error)
            }
        }
        return self

【问题讨论】:

  • 你尝试过像这样 variableName!! 的双重展开吗?
  • 恐怕这只会引发Could not cast value of type 'NSNull' (0x10e6e5378) to 'NSString' (0x10dd52b20). 并中断。使用以下代码:self.username = (representation.valueForKeyPath("username") as? String)!
  • 注意representation.valueForKeyPath("username")!! ? 抛出了一个错误,期望在 ? 之后有一个语句。

标签: json swift alamofire


【解决方案1】:

您的 User 类带有一个可失败的初始化程序,但您似乎没有使用它。

这是我的想法的一个简单版本:

class User {
let firstName: String

init?(name: String?) {
    guard let name = name else {
        self.firstName = "" // trash value needed until swift 2.2
        return nil
    }
    self.firstName = name
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多