我正在尝试解析一个 JSON 数组,它可以是
{
"config_data": [
{
"name": "illuminate",
"config_title": "Blink"
},
{
"name": "shoot",
"config_title": "Fire"
}
]
}
Run Code Online (Sandbox Code Playgroud)
或者它可以是以下类型
{
"config_data": [
"illuminate",
"shoot"
]
}
Run Code Online (Sandbox Code Playgroud)
甚至
{
"config_data": [
25,
100
]
}
Run Code Online (Sandbox Code Playgroud)
所以为了使用 JSONDecoder 解析这个,我创建了一个结构如下 -
Struct Model: Codable {
var config_data: [Any]?
enum CodingKeys: String, CodingKey {
case config_data = "config_data"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
config_data = try values.decode([Any].self, forKey: .config_data)
}
}
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为Any不确认可解码协议。这可能是什么解决方案。数组可以包含任何类型的数据
在 Playgrounds 中,以下代码会产生错误:
import Foundation
struct Model: Codable {
let textBody: String
enum CodingKeys: String, CodingKey {
case textBody = "TextBody"
}
}
let json = """
{
"TextBody": "First Line\n\nLastLine"
}
""".data(using: .utf8)!
let model = try! JSONDecoder().decode(Model.self, from: json)
Run Code Online (Sandbox Code Playgroud)
致命错误:“尝试!” 表达式意外引发错误: Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.",underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Unescaped control字符 27 周围的字符。” UserInfo={NSDebugDescription=字符 27 周围的未转义控制字符。}))):文件 MyPlayground.playground,第 19 行
根据 JSONLint,上面的 JSON 是完全有效的。那么什么给呢?
更新:
我需要一个解决方案来处理从 API 返回的数据。这是我到目前为止想出的东西,但它很糟糕......
if let data = data,
let …Run Code Online (Sandbox Code Playgroud) 我已经调试了几个小时,为什么我的代码随机因此错误而中断: JSONDecodeError: Expecting value: line 1 column 1 (char 0)
这是我的代码:
while True:
try:
submissions = requests.get('http://reymisterio.net/data-dump/api.php/submission?filter[]=form,cs,'+client+'&filter[]=date,cs,'+since).json()['submission']['records']
break
except requests.exceptions.ConnectionError:
time.sleep(100)
Run Code Online (Sandbox Code Playgroud)
而且我一直在通过打印进行调试,requests.get(url)并且requests.get(url).text遇到了以下“特殊”情况:
requests.get(url)返回成功的200响应并requests.get(url).text返回html。我已经在线阅读了使用时应该会失败的信息requests.get(url).json(),因为它无法读取html,但是以某种方式不会损坏。为什么是这样?
requests.get(url)返回成功的200响应,并且requests.get(url).text为json格式。我不明白为什么到requests.get(url).json()JSONDecodeError时会中断?
requests.get(url).text情况2 的确切值为:
{
"submission": {
"columns": [
"pk",
"form",
"date",
"ip"
],
"records": [
[
"21197",
"mistico-form-contacto-form",
"2018-09-21 09:04:41",
"186.179.71.106"
]
]
}
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用解析响应JSONDecoder。如果相应的键有值,那么它将很好,但是如果键的值为空,则它将无法编译,并出现以下错误。
valueNotFound(Swift.String,Swift.DecodingError.Context(codingPath:[CodingKeys(stringValue:“ Results”,intValue:nil),_JSONKey(stringValue:“ Index 0”,intValue:0),CodingKeys(stringValue:“ VehicleName”, intValue:nil)],debugDescription:“期望的字符串值,但发现为null。”,底层错误:nil))
guard let obj = try? JSONDecoder().decode(ShipmentsResponse.self, from: json) else {return}
Run Code Online (Sandbox Code Playgroud)
这是我违抗的货运类
class ShipmentResponse : Codable {
var ItemId: String = ""
var VehicleName: String = ""
var VehicleNumber: String = ""
convenience required init(from decoder: Decoder) throws
{
self.init()
let values = try decoder.container(keyedBy: CodingKeys.self)
ItemId = try values.decode(String.self, forKey: .ItemId)
do {
_ = try values.decode(String.self, forKey: .VehicleName)
} catch {
print(error)
}
VehicleName = try values.decode(String.self, forKey: .VehicleName)
VehicleNumber …Run Code Online (Sandbox Code Playgroud) TL; DR
有没有一种方法可以使用JSONDecoder并编写一个函数,它只是从给定的json读出指定的可解码类型的字段值?
成像我有以下json:
{
"product":{
"name":"PR1",
"price":20
},
"employee":{
"lastName":"Smith",
"department":"IT",
"manager":"Anderson"
}
}
Run Code Online (Sandbox Code Playgroud)
我有2个Decodable结构:
struct Product: Decodable {
var name: String
var price: Int
}
struct Employee: Decodable {
var lastName: String
var department: String
var manager: String
}
Run Code Online (Sandbox Code Playgroud)
我想写一个函数
func getValue<T:Decodable>(from json: Data, field: String) -> T { ... }
Run Code Online (Sandbox Code Playgroud)
所以我可以这样称呼它:
let product: Product = getValue(from: myJson, field: "product")
let employee: Employee = getValue(from: myJson, field: "employee")
Run Code Online (Sandbox Code Playgroud)
这是可能的,JSONDecoder或者我应该弄乱JSONSerialization,首先读出给定json的"子树",然后将其传递给解码器?在swift中似乎不允许在泛型函数中定义结构.
我正在使用泛型和可编码的URLSession.
当我收到来自 API 的响应时,我检查状态是否在 200 - 299 范围内并像这样解码数据
guard let data = data, let value = try? JSONDecoder().decode(T.self, from: data) else {
return completion(.error("Could not decode JSON response"))
}
completion(.success(value))
Run Code Online (Sandbox Code Playgroud)
然后将其传递给完成处理程序,一切正常。
我有一个新的端点,我也必须 POST,但是,这个端点返回一个没有内容正文的 204。
因此,我无法解码响应,只是因为我无法传入类型?
我的完成处理程序期望
enum Either<T> {
case success(T)
case error(String?)
}
Run Code Online (Sandbox Code Playgroud)
并像这样打开我的响应状态代码
case 204:
let value = String(stringLiteral: "no content")
return completion(.success(value))
Run Code Online (Sandbox Code Playgroud)
产生错误
“Either< > ”中的成员“success”产生“Either”类型的结果,但上下文需要“Either< >”
我的 APIClient 是
protocol APIClientProtocol: class {
var task: URLSessionDataTask { get set }
var session: SessionProtocol …Run Code Online (Sandbox Code Playgroud) ($10741e078 处的未知上下文).CodingKeys>,Swift.DecodingError.Context(codingPath:[],debugDescription:“无法获取键控解码容器 - 找到空值。”,underlyingError:nil)
我的模型是,
struct Details : Decodable {
var userInfo : RequestUserInfo
var commercialInfo : String?
}
struct RequestUserInfo : Decodable {
var UserName : String?
var Email : String?
var UserIdentity : String?
var UserMobile : String?
var ThirdName : String?
var LastName : String?
var IdIssueDate : String?
var IdSourceCity : String?
}
Run Code Online (Sandbox Code Playgroud)
($10741e078 处的未知上下文).CodingKeys>,Swift.DecodingError.Context(codingPath:[],debugDescription:“无法获取键控解码容器 - 找到空值。”,underlyingError:nil)
我确实在堆栈溢出中看到了很多类似的问题,但似乎没有人与我的情况相似。我是组合框架的新手,我花了整个下午才弄清楚出了什么问题,但仍然卡在这里......
\n\nXcode 给出了以下错误,我所做的是使用 TMDB 的 API 并将其解码到我的 Actor 模型中。并且在这条线上失败了let result = try self.decoder.decode(TMDBActorsResult.self, from: output.data)。你能给我一些提示这是怎么回事吗adult?
\n\n\n错误:keyNotFound(CodingKeys(stringValue:“成人”,intValue:nil),Swift.DecodingError.Context(codingPath:[CodingKeys(stringValue:“结果”,intValue:nil),_JSONKey(stringValue:“索引0”,intValue: 0), CodingKeys(stringValue: "knownFor", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "没有与密钥关联的值 CodingKeys(stringValue: \\"adult\\" , intValue: nil) (\\"adult\\").",underlyingError: nil))
\n
我还检查了 url 是否正常工作,这是 TMDB API 的返回数据:
\n\n\n\n\n\n/// 演员模型
\n\nimport SwiftUI\n\n\nstruct TMDBActorsResult: Codable {\n let page: Int?\n let results: [Actor]\n let totalResults: Int?\n let totalPages: Int?\n}\n\nstruct Actor: Codable {\n let profilePath: String?\n let …Run Code Online (Sandbox Code Playgroud) 在使用Google translate API 时,我发现有时 google 无法翻译任何内容,同时它不断引发相同的异常:额外数据。
我在互联网上搜索,我发现一个理论说我被谷歌翻译以某种方式阻止了,或者可以因为翻译数据超过 5k 个字符限制而被阻止。 这是一个解决方案,但我认为这不是解决它的正确方法。
我的代码不是新的,它已经正常工作了大约 1 个月,但是前几天,它开始引发错误,我当时不知道如何解决它,所以我把它留到了以后解决它,但是当我醒来时,它又开始工作了,我以为是 google 或其他原因引起的错误,所以我只是忘记了,但在同一天,晚上 10 点左右,它停止工作。我想说的是它非常不一致,有时它起作用有时不起作用。
如何重现:使用指定的python 版本运行google_trans_new包网站上的示例代码。
这是我的代码:
from google_trans_new import google_translator
translator = google_translator()
translate_text = translator.translate('?????????',lang_tgt='en')
print(translate_text)
Run Code Online (Sandbox Code Playgroud)
输出:
Traceback (most recent call last):
File "c:/Users/my_name/MyApp.py", line 105, in <module>
translate_text = translator.translate('?????????',lang_tgt='en')
File "C:\Users\my_name\AppData\Local\Programs\Python\Python37\lib\site-packages\google_trans_new\google_trans_new.py", line 188, in translate
raise e
File "C:\Users\my_name\AppData\Local\Programs\Python\Python37\lib\site-packages\google_trans_new\google_trans_new.py", line 152, in translate
response = json.loads(response)
File "C:\Users\my_name\AppData\Local\Programs\Python\Python37\lib\json\__init__.py", line 348, in loads
return _default_decoder.decode(s)
File "C:\Users\my_name\AppData\Local\Programs\Python\Python37\lib\json\decoder.py", line 341, …Run Code Online (Sandbox Code Playgroud) 这是我的场景:我有一个快速的 WebSocket 服务器和一个 Javascript 客户端。通过同一个 WebSocket,我将发送对应于不同Codable 类型的各种对象。如果已知正确的类型,则解码很简单。对我来说,困难在于确定客户端发送的是哪种类型。我的第一个想法是使用如下所示的 JSON:
{type: "GeoMarker",
data: {id: "2",
latitude: "-97.32432"
longitude: "14.35436"}
}
Run Code Online (Sandbox Code Playgroud)
这样我就知道使用解码data这let marker = try decoder.decode(GeoMarker.self)
似乎很简单,但由于某种原因,我只是不知道如何将对象提取data为 JSON,以便我可以使用 GeoMarker 类型对其进行解码。
我想出的另一个解决方案是创建一个中间类型,如下所示:
struct Communication: Decodable {
let message: String?
let markers: [GeoMarker]?
let layers: [GeoLayer]?
}
Run Code Online (Sandbox Code Playgroud)
这样我就可以发送以下格式的 JSON:
{message: "This is a message",
markers: [{id: "2",
latitude: "-97.32432"
longitude: "14.35436"},
{id: "3",
latitude: "-67.32432"
longitude: "71.35436"}]
}
Run Code Online (Sandbox Code Playgroud)
并使用let com = try decoder.decode(Communication.self)和解包可选的消息、标记和图层变量。这可行,但看起来很笨重,特别是当我需要更多类型时。说完一切之后,我可能最终需要 8-10 个。
我已经考虑过这个问题,但我觉得我没有想出一个令人满意的解决方案。会有更好的方法吗?对于我不知道的这种事情是否有一个标准? …
jsondecoder ×10
swift ×8
json ×6
ios ×2
python ×2
codable ×1
combine ×1
decodable ×1
nsurlsession ×1
parsing ×1
python-3.x ×1
swift4 ×1
urlsession ×1
websocket ×1