NSNetService dictionaryFromTXTRecord 对无效输入的断言失败

ate*_*elo 5 cocoa nsnetservice ios swift

输入dictionary(fromTXTRecord:)来自网络,可能来自应用程序外部,甚至来自设备。但是,Apple 的文档说:

... 如果 txtData 不能表示为 NSDictionary 对象,则断言失败。

断言失败会使程序员(我)无法处理错误,这对于处理外部数据的方法来说似乎不合逻辑。

如果我在 Mac 上的终端中运行它:

dns-sd -R 'My Service Name' _myservice._tcp local 4567 asdf asdf
Run Code Online (Sandbox Code Playgroud)

我在 iPhone 上运行的应用程序崩溃了。

dictionary(fromTXTRecord:)期望 TXT 记录数据 ( asdf asdf) 为key=val格式。如果像上面一样,一个单词不包含任何内容,则=该方法将无法解析它并使断言失败。

除了根本不使用该方法并实现我自己的解析之外,我认为没有办法解决这个问题,这感觉不对。

我错过了什么吗?

ate*_*elo 1

我仍然希望这里遗漏了一些东西,但与此同时,我最终检查了数据的正确性,然后才调用苹果自己的方法。

这是我的解决方法:

func dictionaryFromTXTRecordData(data: NSData) -> [String:NSData] {
    let buffer = UnsafeBufferPointer<UInt8>(start: UnsafePointer(data.bytes), count: data.length)
    var pos = 0
    while pos < buffer.count {
        let len = Int(buffer[pos])
        if len > (buffer.count - pos + 1) {
            return [:]
        }
        let subdata = data.subdataWithRange(NSRange(location: pos + 1, length: len))
        guard let substring = String(data: subdata, encoding: NSUTF8StringEncoding) else {
            return [:]
        }
        if !substring.containsString("=") {
            return [:]
        }
        pos = pos + len + 1
    }
    return NSNetService.dictionaryFromTXTRecordData(data)
}
Run Code Online (Sandbox Code Playgroud)

我在这里使用 Swift 2。欢迎所有贡献。Swift 3 版本、Objective-C 版本、改进、修正。