由于复杂的原因,我发现自己在违背以下原则Codable:在解码 json 对象时,我想将子对象保留在extra“just as json”键下,存储为[String: Any]字典,但[String: Any](当然)不是Decodable。有什么办法可以做到这一点吗?
第一个答案当然是“不”。我的回答是“我需要”:我需要对数据进行两次 Codable传递,其中第一次解码异构对象列表(每个对象都有一个 key name),而第二次传递使用以这些值为键的字典name,并且是正确类型安全的。第一遍不能是类型安全的,因为它在异构列表上操作,但它需要保留第二遍将使用的所有数据。值得庆幸的是,所有异构数据都隐藏在该extra密钥下,但我仍然不知道该怎么做。
(很可能会有一个关于编码相同内容的后续问题,所以如果您碰巧有洞察力,请随时提及。)
我想通过解析 firestore 数据库的响应来解码时间戳(由 FirebaseFirestore.Timestamp 在 swift 中定义)。
编译器告诉我从服务器解析以下代码:
实例方法“decode(_:forKey:)”要求“Timestamp”符合“Decodable”
created = try container.decode(FirebaseFirestore.Timestamp.self, forKey: .created)
Run Code Online (Sandbox Code Playgroud)
我也无法使用以下行进行编码(在本地保存或发送到服务器):
try container.encode(created, forKey: .created)
Run Code Online (Sandbox Code Playgroud)
编译器说:
无法将“Timestamp”类型的值转换为预期的参数类型“String”
完整的复制粘贴如下
另外,时间戳似乎是字典,而不是整数,因为当我尝试将时间戳解码为整数时,出现错误:
Expected to decode Int but found a dictionary instead.
Run Code Online (Sandbox Code Playgroud)
但我们都知道 [String:Any] (即字典)无法解码。
import FirebaseFirestore
class SomeClassToParseFromFirestoresDatabase: Codable
{
var created = FirebaseFirestore.Timestamp.init(date: Date())
private enum CodingKeys: String, CodingKey
{
case created
}
func encode(to encoder: Encoder) throws
{
var container = encoder.container(keyedBy: CodingKeys.self)
do
{
try container.encode(created, forKey: .created)
}
catch let error
{
print("error encoding …Run Code Online (Sandbox Code Playgroud) 对于要序列化的示例结构: Person
struct Person {
let firstName: String
let lastName: String
}
Run Code Online (Sandbox Code Playgroud)
我们可以使其符合Encodable、Decodable或Codable协议。我知道我们在Encodable和 之间的选择Decodable取决于用例(例如,如果我们正在访问 API 并且不需要解码包含相同类型的响应),但我们也可以使其符合Codable如果结构是两者都用于编码和解码。
如果我们严格需要该结构体用于编码或解码,但不是两者,那么从性能角度来看,仅使用包罗万象Codable而不是指定Encodable/Decodable一致性是一个坏主意吗?
使用Codable而不是指定Encodable/的一个明显缺点Decodable是,另一个程序员可能会将该结构误解为用于编码和解码,而实际上只有两者之一发生。但如果我对性能非常感兴趣怎么办?
这不是关于解码具有多种类型(int、string)的属性值。
我有一个名为datait 的对象可以返回多种类型,此时可以执行的操作可能如下所示:
enum MyData: Codable {
case ObjOne(groupObject)
case ObjTwo(imageObject)
init(from decoder: Decoder) throws {
let value = try decoder.singleValueContainer()
if let v = try? value.decode(groupObject.self) {
self = .ObjOne(v)
return
} else if let v = try? value.decode(imageObject.self) {
self = .ObjTwo(v)
return
}
throw Rating.ParseError.notRecognizedType(value)
}
enum ParseError: Error {
case notRecognizedType(Any)
}
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是,我尝试MyData根据先前解码过程中使用的另一个值来解码对象,简而言之,我想传递一个值,MyData以便它可以确定要解码哪个值
我有这个
enum ContentType: String, Codable {
case linear
case grid
case slider
}
Run Code Online (Sandbox Code Playgroud)
我想MyData知道这个 …
使用 Xcode 10.2 和 iOS 12.x,我们能够从 json 字符串中提取 Decimal。使用 Xcode 11.1 和 iOS 13.1 会引发异常
预期解码 Double,但发现了字符串/数据。
class MyClass : Codable {
var decimal: Decimal?
}
Run Code Online (Sandbox Code Playgroud)
然后尝试解析它
let json = "{\"decimal\":\"0.007\"}"
let data = json.data(using: .utf8)
let decoder = JSONDecoder()
decoder.nonConformingFloatDecodingStrategy = .convertFromString(positiveInfinity: "s1", negativeInfinity: "s2", nan: "s3")
do {
let t = try decoder.decode(MyClass.self, from: data!)
} catch {
print(error)
}
Run Code Online (Sandbox Code Playgroud)
如果我将 json 字符串更改为
let json = "{\"decimal\":0.007}"
它有效,但我们又失去了精度。有任何想法吗?
我对 iOS 中的 Alamofire 和 Codable 概念不熟悉,有人可以告诉我如何使用它来访问我的 json 数据。
这是我的 json 响应。
{"subscriptions": [
{
"batch_user_id": 23,
"batch_name": "demo batch",
"course_name": "IELTS",
"start_date": "Nov 01 2019",
"end_date": "Nov 30 2019",
"no_of_days": 21,
"total_no_of_days": 30,
"extended_date": "Nov 30 2019",
"extended": false,
"course_extensions": [
{
"id": 31,
"amount": "3500.0",
"course_id": 1,
"is_active": true,
"number_of_days": 5
},
Run Code Online (Sandbox Code Playgroud)
这是可编码的代码:
struct course_extensions: Codable {
let id: String
let amount: String
let course_id: String
private enum CodingKeys: String, CodingKey {
case id = "id"
case amount …Run Code Online (Sandbox Code Playgroud) 您是否可以定义一个枚举来表示模型中属性的已知值,同时仍然允许从后端返回未知值?
简短回答:是的,可以!答案如下。
作为我们应用程序的一部分,我们定义了一组功能标志,应用程序使用这些标志根据一组标准启用/禁用某些功能。这些标志作为字符串数组从后端发送回。
然而,在我们的应用程序中,我们不想处理混乱的字符串常量,而是希望将这些值定义为我们标记的枚举,以便Codable编译器自动为我们处理实际枚举情况的编码/解码。
这是此类场景的典型枚举......
enum FeatureFlag : String, CaseIterable, Codable {
case allowsTrading
case allowsFundScreener
case allowsFundsTransfer
}
Run Code Online (Sandbox Code Playgroud)
这种设计的问题在于它不处理可能定义的值以及将来从后端返回的值。
有几种方法可以处理这种情况:
一到三本身就是维护噩梦。是的,四个更好,但是编写所有这些自定义序列化器/反序列化器可能非常耗时且容易出错,而且它无法利用编译器能够自动为您完成此操作的优势!
但如果有第五个呢?如果您可以使枚举本身在运行时优雅地处理未知值,同时在此过程中保持无损,并且不必求助于选项,该怎么办?
这就是我在下面介绍的确切解决方案!享受!
我希望能够保存一个Custom-struct toUserDefaults但为此我需要它是Codable.. 我试过这样的:
struct Wishlist: Codable {
var name: String
var image: UIImage
var wishData: [Wish]
var color: UIColor
var textColor: UIColor
var index: Int
}
Run Code Online (Sandbox Code Playgroud)
但这给了我这个error:
“愿望清单”类型不符合“可解码”协议
这是我的Class Wish,也许这就是问题所在:
class Wish: NSObject {
public var wishName : String?
public var checkedStatus : Bool?
public var wishLink : String?
public var wishPrice : String?
public var wishNote : String?
public var wishImage : UIImage?
init(withWishName name: String, link: String, price: String, …Run Code Online (Sandbox Code Playgroud) 我有这样的结构
struct RGBA: Codable {
var r: UInt8
var g: UInt8
var b: UInt8
var a: UInt8
}
Run Code Online (Sandbox Code Playgroud)
我想保存大量的这种结构(> 1_000_000)
解码
guard let history = try? JSONDecoder().decode(HistoryRGBA.self, from: data) else { return }
Run Code Online (Sandbox Code Playgroud)
编码
guard let jsonData = try? encoder.encode(dataForSave) else { return false }
Run Code Online (Sandbox Code Playgroud)
如何改善编码/解码时间和 RAM 内存量?
我收到来自不同 API 的以下 2 个响应
{
"id": "jdu72bdj",
"userInfo": {
"name": "Sudhanshu",
"age": 28,
"country": "India"
}
}
Run Code Online (Sandbox Code Playgroud)
和
{
"profileId": "jdu72bdj",
"profileDetails": {
"name": "Sudhanshu",
"age": 28,
"country": "India"
}
}
Run Code Online (Sandbox Code Playgroud)
iOS development这是与使用语言相关的Swift。基本上对象结构是相同的,但键不同。我正在使用 解析这些Codable,但我想不出一种使用相同结构进行解析的方法。我能想到的就是制作两种不同的结构,如下所示 -
public struct Container1: Codable {
public let id: String
public let userInfo: UserProfile?
}
Run Code Online (Sandbox Code Playgroud)
和
public struct Container2: Codable {
public let profileId: String
public let profileDetails: UserProfile?
}
Run Code Online (Sandbox Code Playgroud)
他们都使用共同的UserProfile结构。
public struct UserProfile: Codable {
public let …Run Code Online (Sandbox Code Playgroud)