我拥有的:具有不同属性的可编码结构。
我想要的:一个函数,当属性编码为 Json 时,我可以在其中获取属性的确切名称。我认为最有前途的方法是使用 Keypath,但我不知道如何以及是否可能。谢谢!
如何解码不同 JSON 对象的数组,其中每个对象的相同属性告诉您使用什么类型来解码它:
let json =
"""
[
{
"@type": "FirstObject",
"number": 1
},
{
"@type": "SecondObject",
"name": "myName"
}
]
"""
Run Code Online (Sandbox Code Playgroud)
这是一些基于类似答案的代码,它大部分都可以实现,但失败了,因为它不知道 CodingKeys 的用途.data:
struct FirstObject: MyData {
var dataType: String
var number: Int
enum CodingKeys: String, CodingKey {
case dataType = "@type"
case number
}
}
struct SecondObject: MyData {
var dataType: String
var name: String
enum CodingKeys: String, CodingKey {
case dataType = "@type"
case name
}
}
struct SchemaObj: Decodable
{
var dataType: …Run Code Online (Sandbox Code Playgroud) 我正在使用一个 API,它可以根据项目返回一个值Bool或一个值。Int我不熟悉如何处理数据中一个值的不同类型Codable。额定键可以是对象或布尔值,只是不确定如何正确处理它而不出现错误typeMismatch。这是我第一次使用 API 遇到这种情况。
{"id":550,"favorite":false,"rated":{"value":9.0},"watchlist":false}\nRun Code Online (Sandbox Code Playgroud)\n{\xe2\x80\x9cid":405,"favorite":false,"rated":false,"watchlist":false}\nRun Code Online (Sandbox Code Playgroud)\nstruct AccountState: Codable {\n let id: Int?\n let favorite: Bool?\n let watchlist: Bool?\n let rated: Rated?\n}\n\nstruct Rated : Codable {\n let value : Int? // <-- Bool or Int\n}\nRun Code Online (Sandbox Code Playgroud)\n 我有一个相当大的结构,符合Codable,并且它的属性之一需要与其本身具有相同的类型。我正在尝试做的事情的简短示例如下所示:
struct Message: Codable {
let content: String
// ...other values
let reference: Message // <-- Error: Value type 'Message' cannot have a stored property that recursively contains it
}
Run Code Online (Sandbox Code Playgroud)
Swift 似乎不允许结构体递归地将自身包含为其值之一。Message除了创建一个完整的重复结构(这会将其变成先有鸡还是先有蛋的问题,其中重复结构不能包含自身等)之外,还有什么方法可以使其工作吗?不创建重复的结构还允许我重用接收和呈现Message结构的 SwiftUI 代码。
我收到许多随机问题。大多像某些结构无法解码,无法理解如何定义结构。
请发现代码被截断
var JSON = """
{"variants":{"variant_groups":[{"group_id":"1","name":"Crust","variations":[{"name":"Thin","price":0,"default":1,"id":"1","inStock":1},{"name":"Thick","price":0,"default":0,"id":"2","inStock":1,"isVeg":1},{"name":"Cheese burst","price":100,"default":0,"id":"3","inStock":1,"isVeg":1}]},{"group_id":"2","name":"Size","variations":[{"name":"Small","price":0,"default":1,"id":"10","inStock":1,"isVeg":0},{"name":"Medium","price":100,"default":0,"id":"11","inStock":1,"isVeg":1},{"name":":Large","price":200,"default":0,"id":"12","inStock":1,"isVeg":0}]},{"group_id":"3","name":"Sauce","variations":[{"name":"Manchurian","price":20,"default":0,"id":"20","inStock":1,"isVeg":0},{"name":"Tomato","price":20,"default":0,"id":"21","inStock":1,"isVeg":1},{"name":"Mustard","price":20,"default":0,"id":"22","inStock":1,"isVeg":0}]}],"exclude_list":[[{"group_id":"1","variation_id":"3"},{"group_id":"2","variation_id":"10"}],[{"group_id":"2","variation_id":"10"},{"group_id":"3","variation_id":"22"}]]}}
""".data(using: .utf8)
/*
not sure is this the right way to define Root
*/
struct Root : Codable {
let variants : varientStruct
let exclude_list : exclude_list
}
struct exclude_list : Codable{
let variation_id : String
let group_id : String
}
struct varientStruct: Codable {
let variant_groups = [variant_groups_struct]
}
struct variant_groups_struct : Codable {
let group_id : String
let name :String
let variations: [variationsStruct]
}
struct variationsStruct :Codable {
let name …Run Code Online (Sandbox Code Playgroud) protocol CodableWithDefault: Codable {
static var `default`: Self { get }
}
extension Set: CodableWithDefault {
static var `default`: Set {
return Set()
}
}
Run Code Online (Sandbox Code Playgroud)
在Swift 4中,这工作正常,但是从4.1开始,它抱怨:
'CodableWithDefault' requires that 'Element' conform to 'Encodable'
我找不到任何表示要扩展的方法Set,该扩展Element也必须实现Encodable。
Swift 4.1完全可行吗?
我正在解析像这样的JSON
struct ExampleStruct : Codable {
init() {
}
// implementation
}
if let jsonData = jsonString.data(using: .utf8) {
do {
let decoder = JSONDecoder()
let object = try decoder.decode(ExampleStruct.self, from: jsonData)
} catch {
print("Coding error - \(error)")
}
}
Run Code Online (Sandbox Code Playgroud)
这很好,但是我一直试图在周末学习泛型.我正在尝试编写一个方法,我传入一个Codable结构类型和一个JSON字符串,它返回我想要的类型的对象.
我尝试过以下方法: -
func getType<T>(_ anyType: T.Type, from jsonString:String) -> T? {
if let jsonData = jsonString.data(using: .utf8) {
do {
let decoder = JSONDecoder()
let object = try decoder.decode(anyType, from: jsonData)//Errors here
return object as? T
return nil …Run Code Online (Sandbox Code Playgroud) 我正在使用提供 2 个 JSON URL 的 API。每个 URL 都包含一个嵌套容器,该容器具有属于同一类和对象的不同属性。
JSON 网址 1
{
"last_updated": 1535936629,
"xyz": 5,
"data": {
"dataList": [
{
"id": "42",
"a1": "a1value",
"a2": "a2value",
},
// ,,,
]
}
}
Run Code Online (Sandbox Code Playgroud)
JSON 网址 2
{
"last_updated": 1536639996,
"xyz": 5,
"data": {
"dataList": [
{
"id": "42",
"a3": "a3value",
"a4": "a4value",
},
// ,,,
]
}
}
Run Code Online (Sandbox Code Playgroud)
我想使用这些 JSON URLS 使用嵌套dataList列表中的项目创建单个 Codable CustomClass 对象,因此我创建了一个Feed结构来处理这 2 个 JSON 文件。
Feed.swift
import Foundation
Struct Feed: Decodable …Run Code Online (Sandbox Code Playgroud) 我有一个UserDefaults用于处理存储,删除和获取存储对象到默认值的类。我相信,这是完整的课程,简洁明了:
现在的问题在于存储功能。我似乎无法编码Encodable String对象。我知道我可以将对象存储为默认值,但这会破坏MVDefaults处理通用对象的目的。
我在这里想念什么吗?
import Foundation
enum MVDefaultsKey: String {
case requestToken = "defaultsRequestToken"
}
/// The class that has multiple class functions for handling defaults.
/// Also has the helper class functions for handling auth tokens.
class MVDefaults {
// MARK: - Functions
/// Stores token.
class func store<T: Encodable>(_ object: T, key: MVDefaultsKey) {
let encoder = JSONEncoder()
let encoded = try? encoder.encode(object)
UserDefaults.standard.set(encoded, forKey: key.rawValue)
}
/// Removes the stored token …Run Code Online (Sandbox Code Playgroud) Codable当您知道JSON数据的密钥格式时,该功能非常有用。但是,如果您不知道按键怎么办?我目前面临这个问题。
通常,我希望这样返回JSON数据:
{
"id": "<123>",
"data": [
{
"id": "<id1>",
"event": "<event_type>",
"date": "<date>"
},
{
"id": "<id2>",
"event": "<event_type>",
"date": "<date>"
},
]
}
Run Code Online (Sandbox Code Playgroud)
但这就是我要解码的内容:
{
"id": "123",
"data": [
{ "<id1>": { "<event>": "<date>" } },
{ "<id2>": { "<event>": "<date>" } },
]
}
Run Code Online (Sandbox Code Playgroud)
问题是:如何使用Codable密钥唯一的JSON解码?我觉得我缺少明显的东西。
这就是我希望做的,所以我可以使用Codable:
struct SampleModel: Codable {
let id: String
let data: [[String: [String: Any]]]
// MARK: - Decoding
enum CodingKeys: String, CodingKey {
case id = "id" …Run Code Online (Sandbox Code Playgroud)