我处理许多使用 Codable 协议序列化/反序列化为 JSON 的对象。
这并不是说努力创造一个JSONEncoder,设置它漂亮地打印,将对象转换为JSON,然后将其转换成一个字符串,但似乎很多工作。有没有一种简单的方法可以说“请给我看看这个对象的 JSON 输出?”
例如说我有以下结构:
struct Foo: Codable {
let string1: String?
let string2: String?
let date: Date
let val: Int
let aBar: Bar
}
struct Bar: Codable {
let name: String
}
Run Code Online (Sandbox Code Playgroud)
并说我创建了一个Foo对象:
let aBar = Bar(name: "Fred")
let aFoo = Foo(string1: "string1", string2: "string2", date: Date(), val: 42, aBar: aBar)
Run Code Online (Sandbox Code Playgroud)
我可以用六行自定义代码打印出来:
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
guard let data = try? encoder.encode(aFoo),
let output = …Run Code Online (Sandbox Code Playgroud) 我正在尝试Codable为一个对象采用协议,该对象必须从我的 Web 服务返回的 JSON 实例化以响应 API 调用之一。
其中一个属性是枚举类型,可选:nil表示没有选择 定义的任何选项enum。
该enum常数Int为基础的,并在开始1,不是 0:
class MyClass: Codable {
enum Company: Int {
case toyota = 1
case ford
case gm
}
var company: Company?
Run Code Online (Sandbox Code Playgroud)
这是因为0相应 JSON 条目上的值是为“未设置”保留的;即nil在设置初始化company属性时应该映射到它。
Swift 的 enum 初始值设定项init?(rawValue:)提供了开箱即用的此功能:Int与任何情况下的原始值都不匹配的参数将导致初始值设定项失败并返回 nil。此外,Int可以Codable通过在类型定义中声明它来使基于 (和 String) 的枚举符合:
enum Company: Int, Codable {
case toyota = …Run Code Online (Sandbox Code Playgroud) 有没有办法保留 Swift 对 Decodable 类的默认实现,其中只有 Decodable 对象但有一个例外?例如,如果我有一个这样的结构/类:
struct MyDecodable: Decodable {
var int: Int
var string: String
var location: CLLocation
}
Run Code Online (Sandbox Code Playgroud)
我想使用默认解码int,string但location自己解码。所以在init(from decoder:)我想有这样的事情:
required init(from decoder: Decoder) throws {
<# insert something that decodes all standard decodable properties #>
// only handle location separately
let container = try decoder.container(keyedBy: CodingKeys.self)
location = <# insert custom location decoding #>
}
Run Code Online (Sandbox Code Playgroud) 我目前正在使用SWIFT 4中的Decodable解析JSON.
JSON格式如下:
{
"autopayout_from": "1.010",
"earning_24_hours": "9.74731104",
"error": false,
"immature_earning": 0.635593030875,
"last_payment_amount": "1.91238210",
"last_payment_date": "Mon, 26 Feb 2018 15:08:02 GMT",
"last_share_date": "Mon, 26 Feb 2018 16:16:01 GMT",
"payout_daily": false,
"payout_request": false,
"total_hashrate": 109006.86,
"total_hashrate_calculated": 143855.75,
"transferring_to_balance": 0.2281390807,
"wallet": "0xbb76fc2ce36a19da28fd713e350a42f1023e2f7f",
"wallet_balance": "0.49556201",
"workers": {
"10003": {
"alive": false,
"hashrate": 0.0,
"hashrate_below_threshold": false,
"hashrate_calculated": 0.0,
"last_submit": "Mon, 26 Feb 2018 13:23:16 GMT",
"second_since_submit": 10612,
"worker": "10003"
},
"100151": {
"alive": false,
"hashrate": 0.0,
"hashrate_below_threshold": false,
"hashrate_calculated": 0.0,
"last_submit": "Mon, 26 Feb …Run Code Online (Sandbox Code Playgroud) 在测试新的 Codable 如何与 NSCoding 交互时,我使用包含 Codable 结构的 Class 进行了涉及 NSCoding 的操场测试。丝毫
struct Unward: Codable {
var id: Int
var job: String
}
class Akward: NSObject, NSCoding {
var name: String
var more: Unward
init(name: String, more: Unward) {
self.name = name
self.more = more
}
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
aCoder.encode(more, forKey: "more")
}
required init?(coder aDecoder: NSCoder) {
name = aDecoder.decodeObject(forKey: "name") as? String ?? ""
more = aDecoder.decodeObject(forKey: "more") as? Unward ?? Unward(id: -1, job: …Run Code Online (Sandbox Code Playgroud) 鉴于这个类:
class MyClass: Codable {
var variable : Codable? = nil
}
Run Code Online (Sandbox Code Playgroud)
我得到错误:
类型“MyClass”不符合协议“Decodable”
类型“MyClass”不符合协议“Encodable”
如何将符合 Codable 的通用变量作为 Codable 类中的属性?
我用于后端调用的服务返回所有这些 json 结构:
{
"status" : "OK",
"payload" : **something**
}
Run Code Online (Sandbox Code Playgroud)
哪里的东西可以是一个简单的字符串:
{
"status" : "OK",
"payload" : "nothing changed"
}
Run Code Online (Sandbox Code Playgroud)
或嵌套的 json(具有任何属性的任何 json),例如:
{
"status" : "OK",
"payload" : {
"someInt" : 2,
"someString" : "hi",
...
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的结构:
struct GenericResponseModel: Codable {
let status:String?
let payload:String?
}
Run Code Online (Sandbox Code Playgroud)
我想始终将“有效负载”解码为字符串。因此,在第二种情况下,我希望“GenericResponseModel”的有效负载属性包含该字段的 json 字符串,但是如果我尝试解码该响应,则会收到错误消息:
Type 'String' mismatch: Expected to decode String but found a dictionary instead
Run Code Online (Sandbox Code Playgroud)
可以存档我想要的吗?
非常感谢
我有以下 Swift 结构
struct Session: Encodable {
let sessionId: String
}
struct Person: Encodable {
let name: String
let age: Int
}
let person = Person(name: "Jan", age: 36)
let session = Session(sessionId: "xyz")
Run Code Online (Sandbox Code Playgroud)
我需要编码为具有以下格式的 json 对象:
{
"name": "Jan",
"age": 36,
"sessionId": "xyz"
}
Run Code Online (Sandbox Code Playgroud)
的所有键Session都合并到Person
我想过使用带有自定义Encodable实现的容器结构,我使用 aSingleValueEncodingContainer但它显然只能编码一个值
struct RequestModel: Encodable {
let session: Session
let person: Person
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(person)
// crash …Run Code Online (Sandbox Code Playgroud) 我正在使用泛型和可编码的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) 我已经在这里看到了许多其他与我类似的问题,但我无法找到我的案例 - 如果我错过了一些明显的问题,我深表歉意!
我有一个“事务”类,其中包含一些属性,所有这些属性都符合 codable 并且可以很好地保存/加载。我刚刚添加了一个字典并收到以下错误:类型“事务”不符合协议“可解码”和“可编码”。
字典是:
var splitTransaction: [String:(amount: Money<GBP>, setByUser: Bool)]? {
Run Code Online (Sandbox Code Playgroud)
Money 来自何处:https : //github.com/Flight-School/Money(Money 已经符合 codable,我还有其他类型为 Money 的属性运行良好。
从https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types我想我必须使用编码密钥来编码/解码 splitTransaction,但这是否意味着我也必须为我的其他每个属性都有一个编码密钥? 然后也提供一种编码/解码它们的方法?或者有没有办法让所有其他属性自动进行编码/解码,而只是为 splitTransaction 提供一种手动工作的方法。
非常感谢任何指导!
codable ×10
swift ×10
json ×3
decodable ×2
swift4 ×2
dictionary ×1
enums ×1
ios ×1
jsondecoder ×1
nested ×1
nscoding ×1
nsurlsession ×1
optional ×1
pretty-print ×1
swift5 ×1
urlsession ×1