问题描述
我有 continued this question here,因为焦点已经改变,但是是相关的。
Vapor 正在服务器和 iOS 客户端之间进行通信。只是设置代码,用于学习目的。
现在,我想使用 JSON 通过已建立的连接发送值字典。我陷入了无法解释的演示代码逻辑中,但在我的蒸气路线中,这就是我所在的位置:
app.webSocket("respond") { req,ws in
ws.onText { ws,text in
print(text)
let msgDict = "{'name' = 'bobby'}"
let encoder = JSONEncoder()
let data = try encoder.encode(msgDict)
ws.send(data)
}
}
这不会编译:{{1}}
通常我要寻找的是一个简单的模式来获取内部字典值,将它们编码为 JSON,然后发送它们。什么是我没有做的,或者我做的不对?
解决方法
我发现该代码存在两个问题。
第一个,由编译错误解释,它实际上告诉它不会处理抛出的任何错误。当您执行 encoder.encode(msgDict)
时,此代码可能会抛出 Error
,并且您不会在任何地方处理这种可能的错误。如果您处理了那个可能的错误,您在该闭包中编写的代码将具有预期的类型。您有几种选择:
- 将代码包裹在
do-catch
块中
do {
let data = try encoder.encode(msgDict)
ws.send(data)
} catch let error {
// Handle error
}
- 使用
try?
,表示您不处理错误,但如果发生错误,结果会得到nil
。
if let data = try? encoder.encode(msgDict) {
ws.send(data)
}
- 使用
try!
,表示您强制解包结果(不建议,但您可以尝试,如果您 100% 确定)
let data = try! encoder.encode(msgDict)
ws.send(data)
第二个问题是您如何编写该响应 - "{'name' = 'bobby'}"
。这是一个无效的 JSON,您应该使用双引号:
let msgDict = "{\"name\" = \"bobby\"}"
您也可以使用 Dictionary
,只要内容是 Encodable
类型:
let msgDict = ["name": "bobby"]
您还可以使用 JSONEncoder
对符合 Encodable
的类的任何实例进行编码。
所以整件事,我会这样写:
app.webSocket("respond") { req,ws in
ws.onText { ws,text in
print(text)
let msgDict = ["name": "bobby"]
let encoder = JSONEncoder()
do {
let data = try encoder.encode(msgDict)
ws.send(data)
}
catch let error {
print("An error occurred: \(error)")
}
}
}
,
错误告诉您缺少 do - catch
块
do {
let encoder = JSONEncoder()
let data = try encoder.encode(msgDict)
ws.send(data)
} catch { print(error) }
但是,您创建 JSON 的方法不起作用,因为 msgDict
既不是有效的 JSON,也不是 Swift 字典。
要使用 JSONEncoder
对字典进行编码,它必须是 Swift 字典
let msgDict = ["name":"bobby"]
但是 JSONEncoder
太过分了。一种更简单的方法是逐字创建 JSON 字典
app.webSocket("respond") { req,text in
print(text)
let msgDict = #"{"name":"bobby"}"#
ws.send(Data(msgDict.utf8))
}
}