看来 Swift 4 中的 Character 类没有实现 Codable 协议。我想了解这样做的基本原理,因为该类似乎有资格作为 Swift 中的基础类。
看看下面的(故意剥离的)递归类,那么在保留使用字符作为字典键的同时使其可编码的最佳方法是什么?
class MyClass: Codable { <- does not compile
var myProperty: [Character: MyClass]?
var myOtherProperty: Int = 42
}
Run Code Online (Sandbox Code Playgroud)
谢谢你!
我正在研究苹果应用程序开发指南,这是我现在正在使用的代码......
struct CategoryInfo: Codable {
var category: String
var description: String
var logo: String
var mobileCategoryName: String
enum Keys: String, CodingKey {
case category
case description = "descr"
case logo
case mobileCategoryName = "mobileCatName"
}
init(from decoder: Decoder) throws {
let valueContainer = try decoder.container(keyedBy: Keys.self)
self.category = try valueContainer.decode(String.self, forKey: Keys.category)
self.description = try valueContainer.decode(String.self, forKey: Keys.description)
self.logo = try valueContainer.decode(String.self, forKey: Keys.logo)
self.mobileCategoryName = try valueContainer.decode(String.self, forKey: Keys.mobileCategoryName)
}
}
override func viewDidLoad() {
super.viewDidLoad()
let categories = …Run Code Online (Sandbox Code Playgroud) 这是以下注释中的后续问题如何映射嵌套的复杂 JSON 对象并将它们保存到核心数据?。
\n\n想象一下我的应用程序已经有了这段代码。
\n\nclass Passenger{\n var name: String\n var number: String\n var image : UIImage\n // init method\n}\nclass Trip {\n let tripNumber : Int\n let passenger : Passenger\n\n init(tripNumber: Int, passenger: Passenger) {\n self.tripNumber = tripNumber\n self.passenger = passenger\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n现在我决定为我的应用程序添加持久性。我只想有一张旅行表。我想向乘客显示行程,但不需要表格来直接查询乘客。它只是旅行的自定义对象/属性。每次我访问乘客都是通过 Trips。
\n\n那么有没有一种方法可以让我创建一个名为 \'TripEntity\' 的新 NSManagedObject 子类并存储我的乘客 \xe2\x80\x94 ,而无需 1. 为 \'Passenger\' 创建另一个 NSManagedObject 子类 2. 创建与乘客和行程之间存在反比关系吗?简而言之,我只是希望它成为一个属性。从概念上讲,对我来说它也只是一个属性。这根本就不是一种关系……
\n\n或者,一旦您使用 Core-data,那么每个自定义类型都需要显式成为 NSManagedObject 的子类?否则它不会被持久化。我猜这也是对象图的含义。你的图表需要完整。图表之外的任何内容都将被忽略......
\n\n我问这个问题是因为我实际想要存储的 JSON 对象非常庞大,并且我正在尝试减少需要完成的工作。
\n我有这样的结构:
struct OrderLine: Codable{
let absUrl: String?
let restApiUrl : String?
let description : String?
let quantity : Int?
let subscription: Subs?
let total: Double?
}
struct Subs: Codable{
let quantity: Int?
let name: String?
}
Run Code Online (Sandbox Code Playgroud)
有些OrderLine在服务器响应中
"subscription": {
"quantity": 6,
"name": "3 Months"
},
Run Code Online (Sandbox Code Playgroud)
但有时它有String类型:
"subscription": "",
Run Code Online (Sandbox Code Playgroud)
没有subscription一切正常,但我有一个错误
CodingKeys(stringValue: "subscription", intValue: nil)],
debugDescription: "Expected to decode Dictionary<String, Any>
but found a string/data instead.", underlyingError: nil)
Run Code Online (Sandbox Code Playgroud)
所以我的问题是 - 如何解码 or to String?with value …
我有以下 JSON 对象:
{
"user_name":"Mark",
"user_info":{
"b_a1234":"value_1",
"c_d5678":"value_2"
}
}
Run Code Online (Sandbox Code Playgroud)
我已经JSONDecoder这样设置了:
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
Run Code Online (Sandbox Code Playgroud)
我的Decodable对象看起来像这样:
struct User: Decodable {
let userName: String
let userInfo: [String : String]
}
Run Code Online (Sandbox Code Playgroud)
我面临的问题是该.convertFromSnakeCase策略正在应用于字典的键,我希望这种情况不会发生。
// Expected Decoded userInfo
{
"b_a1234":"value_1",
"c_d5678":"value_2"
}
// Actual Decoded userInfo
{
"bA1234":"value_1",
"cD5678":"value_2"
}
Run Code Online (Sandbox Code Playgroud)
我研究过使用自定义keyDecodingStrategy(但没有足够的信息来以不同方式处理字典)以及我的自定义初始值设定项Decodable结构的自定义初始值设定项(似乎此时键已经被转换)。
处理此问题的正确方法是什么(仅为字典创建键转换异常)?
注意:我更愿意保留蛇形大小写转换策略,因为我的实际 JSON 对象在蛇形大小写中有很多属性。我当前的解决方法是使用 CodingKeys 枚举手动进行蛇形大小写转换。
假设我有某种具有 JSON 表示形式的类型:
{
"count": 3,
"name": "Pianos",
"type": "instrument",
"id": 1,
}
Run Code Online (Sandbox Code Playgroud)
假设我想将其表示为一个 Swift 对象,如下所示:
struct SomeObject: Codable { // this is the object I'd like to represent
let id: Int
let details: SomeDetails
}
struct SomeDetails: Codable {
let count: Int
let name: String
let type: String
}
Run Code Online (Sandbox Code Playgroud)
解码这个对象是轻而易举的事。但是,在此实例中编码如何工作,以便我可以编码为平面结构——与我用来创建此对象并在上面的 JSON 示例中共享的结构相同?
我有一个 JSON,其 ID 在根级别:
{
"12345": {
"name": "Pim"
},
"54321": {
"name": "Dorien"
}
}
Run Code Online (Sandbox Code Playgroud)
我的目标是使用 Codable 创建一个同时具有 name 和 ID 属性的 User 对象数组。
struct User: Codable {
let id: String
let name: String
}
Run Code Online (Sandbox Code Playgroud)
我知道如何使用带有单个根级别密钥的Codable ,并且知道如何使用未知密钥。但我在这里尝试做的是两者的结合,我不知道下一步该做什么。
这是我到目前为止得到的:(您可以将其粘贴到 Playground 中)
import UIKit
var json = """
{
"12345": {
"name": "Pim"
},
"54321": {
"name": "Dorien"
}
}
"""
let data = Data(json.utf8)
struct User: Codable {
let name: String
}
let decoder = JSONDecoder() …Run Code Online (Sandbox Code Playgroud) 我正在尝试找到一种干净的方法来删除数据模型可选属性(如果nil在 Swift 中自定义编码/解码我的数据模型)。
我的用例:
import Foundation
public struct Message {
public let txnID: UUID
public var userId: String?
public var messageID: UUID?
public init(txnID: UUID, userId: String? = nil, messageID: UUID? = nil) {
self.txnID = txnID
self.userId = userId
self.messageID = messageID
}
}
extension Message: Codable {
private enum CodingKeys: CodingKey {
case txnID, userId, messageID
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
txnID = try container.decode(UUID.self, forKey: .txnID)
// …Run Code Online (Sandbox Code Playgroud) 我正在尝试按如下方式解码错误,我以数组格式处理的大部分错误[String],但在少数情况下,错误不是数组格式,只是一个String.
如果错误以数组格式出现errors,则名称为,但如果是字符串格式,则为error. 我该如何处理这种情况?
我怎么能处理这种情况?
struct CustomError: Codable {
let errors: [String]
}
private func errorDecoding(data : Data) {
let decoder = JSONDecoder()
do {
let errorData = try decoder.decode(CustomError.self, from: data)
} catch {
// TODO
}
}
Run Code Online (Sandbox Code Playgroud) 假设我想按如下方式解码 Person 结构。
struct Person: Decodable {
let firstName: String
let lastName: String
let age: Int: String
}
Run Code Online (Sandbox Code Playgroud)
据我所知,数据只能用上面的方法解码。因此,如果我不将属性更改为自定义名称,如果上面和下面的实现没有区别?
此外,还有其他情况需要使用 CodingKeys 吗?除了重命名目的之外,当它们是必要的时,我很困惑。
struct Person: Decodable {
let firstName: String
let lastName: String
let age: Int: String
}
enum CodingKeys: String, CodingKey {
case firstName
case lastName
case age
}
Run Code Online (Sandbox Code Playgroud)