【问题标题】:How to deal with Null mapping from JSON using RESTKIT on Swift如何在 Swift 上使用 RESTKIT 处理来自 JSON 的 Null 映射
【发布时间】:2015-03-18 19:01:57
【问题描述】:

当从我的服务器接收到包含空值的答案(在 JSON 响应中)时,RestKit 内部映射在处理空值时崩溃。

有什么办法可以克服吗?

我曾尝试扩展 NSNull 以包含“缺失”的方法,但这不起作用并且似乎是错误的。

以下是我的映射和目标代码以及 restkit 输出:

对象映射:

var tempmapping = RKObjectMapping(forClass: PRLAUser.classForCoder())
        tempmapping.addAttributeMappingsFromDictionary([
            "firstName" : "firstName",
            "secondName" : "lastName",
            "email" : "email",
            "id" : "prlaToken"

            ])

目标代码 - 至少是被映射的变量:

var email : String?
var firstName : String?
var lastName : String?


var prlaToken : String?

崩溃日志:

Parola[6138:3119821] -[NSNull length]: unrecognized selector sent to instance 0x197b86ba0

2015-01-20 15:53:37.973 Parola[6138:3119821] * 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[NSNull 长度]:无法识别的选择器发送到实例 0x197b86ba0” * 首先抛出调用栈: (0x1867fa59c 0x196f040e4 0x186801664 0x1867fe418 0x186702b6c 0x100707964 0x100023dc8 0x187605b10 0x1000a34a0 0x1000a4078 0x1000a99d4 0x1000a8dfc 0x10009a8f4 0x1000995a8 0x10009bbb4 0x10009c294 0x10009ca84 0x1875f461c 0x1000e4754 0x1000e2acc 0x1875f461c 0x1876b626c 0x1007b4df0 0x1007bf854 0x1007b8120 0x1007c175c 0x1007c2f18 0x1977252e4 0x197724fa8) libc++abi.dylib:以 NSException 类型的未捕获异常终止

非常感谢您就此事提供任何帮助。

【问题讨论】:

  • 我之前看过这篇文章。这篇文章建议扩展 NSNull 以避免这些调用。这些电话不是问题。问题是为什么要调用它们。
  • 想想 JSON 是什么——在某种程度上它就像 Swift。您可以拥有一个键为“foo”、值为“bar”的字典,或者该值可以为 nil。 Nil 是完全合法的,JSON 到原生的转换会插入一个 [NSNull null] 作为占位符。处理转换后的 JSON 的一种方法是测试每个值 - 每个字符串、数字、数组或字典 [NSNull null] - 并处理它。我试过了,它变得越来越复杂。另一种解决方案是,当 NSNull 收到发送给它的常见消息时,它以某种方式从 NSNull 中恢复正常 - 这就是我上面的解决方案。
  • stackoverflow.com/questions/27917104/…,好像是RestKit的新bug

标签: ios json restkit


【解决方案1】:

如果服务器向您发送一个空值,您首先必须确定它的真正含义。例如,如果您希望字典中有一个字符串,那么键可能不存在,值可能是 null,值可能是空字符串,您需要决定是否要对这些情况进行相同处理.设计 JSON 数据的人实际上可能希望您以不同的方式处理空值。

之后,最简单的方法是通过比较 if (object == (id) [NSNull null]) 或向 NSDictionary 添加一个类别来检查空​​值,该类别会为您进行检查并返回您想要的任何值.

【讨论】:

  • 当然。但我自己没有处理解析,restkit 是。问题是restkit 试图将字符串变量设置为nsnull。一个 swift 对象不能被分配为 nsnull ,更多的是一个可选的 swift 值。因此,objectove c 代码稍后假定 swift 变量是一个字符串,并尝试向它发送消息,即长度。
【解决方案2】:

0.23.1 版适合您。 我在 RestKit github 页面上发布了问题,也进行了临时修复。

https://github.com/RestKit/RestKit/issues/2155

在将 NSNull 转换为 String 的对象中,我做了类似的事情

public override func validateValue(ioValue: AutoreleasingUnsafeMutablePointer<AnyObject?>, forKeyPath inKeyPath: String, error outError: NSErrorPointer) -> Bool {
    if let memory = ioValue.memory {
        if inKeyPath == "hint" && ioValue.memory is NSNull {
            ioValue.memory = nil
            return true
        }
    }
    return super.validateValue(ioValue, forKeyPath: inKeyPath, error: outError)
}

您也可以在请求时更改RKMappingOperationDataSource 以在委托中返回 NO

- (BOOL)mappingOperationShouldSetUnchangedValues:(RKMappingOperation *)mappingOperation;

顺便说一句。 Stack 上已经存在这个问题:RestKit JSON null value crash

【讨论】:

  • 最后,它是 RestKit 中的一个错误,现在可能已经修复。我在那个 restkit 版本中添加了 1 行代码来解决这个错误,但是由于我不能抓住机会并选择一个没有完全更新来处理快速选项的 3rd 方库,所以我最终没有使用 Restkit。
  • 我不会说来自 RestKit 的错误,我检查了来源并发现了导致这个“错误”的提交和更改。然而,他们只依赖于检查属性有效性的内部苹果 api(所以这个validateValue)。如果你在 Objc 中运行这段代码,它会说 NSNull 不对应于 NSString,但是在 Swift 中它会这样说......这就是为什么这个“hack”与validateValue。 ://
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-08
  • 2012-06-12
  • 2013-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多