标签: codable

Swift Codable:如何“传递”未分析的 json 子对象

由于复杂的原因,我发现自己在违背以下原则Codable:在解码 json 对象时,我想将子对象保留在extra“just as json”键下,存储为[String: Any]字典,但[String: Any](当然)不是Decodable。有什么办法可以做到这一点吗?

第一个答案当然是“不”。我的回答是“我需要”:我需要对数据进行两次 Codable传递,其中第一次解码异构对象列表(每个对象都有一个 key name),而第二次传递使用以这些值为键的字典name,并且是正确类型安全的。第一遍不能是类型安全的,因为它在异构列表上操作,但它需要保留第二遍将使用的所有数据。值得庆幸的是,所有异构数据都隐藏在该extra密钥下,但我仍然不知道该怎么做。

(很可能会有一个关于编码相同内容的后续问题,所以如果您碰巧有洞察力,请随时提及。)

swift codable

3
推荐指数
1
解决办法
1777
查看次数

如何快速解码来自 firebase Firestore 的时间戳

我想通过解析 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)

timestamp firebase swift codable google-cloud-firestore

3
推荐指数
1
解决办法
6999
查看次数

将结构体设置为可编码/可解码而不只是可编码是否有任何性能优势?

对于要序列化的示例结构: Person

struct Person {
    let firstName: String
    let lastName: String
}
Run Code Online (Sandbox Code Playgroud)

我们可以使其符合EncodableDecodableCodable协议。我知道我们在Encodable和 之间的选择Decodable取决于用例(例如,如果我们正在访问 API 并且不需要解码包含相同类型的响应),但我们也可以使其符合Codable如果结构是两者都用于编码和解码。

如果我们严格需要该结构体用于编码或解码,但不是两者,那么从性能角度来看,仅使用包罗万象Codable而不是指定Encodable/Decodable一致性是一个坏主意吗?

使用Codable而不是指定Encodable/的一个明显缺点Decodable是,另一个程序员可能会将该结构误解为用于编码和解码,而实际上只有两者之一发生。但如果我对性能非常感兴趣怎么办?

ios swift codable decodable encodable

3
推荐指数
1
解决办法
905
查看次数

基于另一个值的具有多个对象类型的可编码解码属性

这不是关于解码具有多种类型(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知道这个 …

swift codable

3
推荐指数
1
解决办法
1941
查看次数

从 JSON 中解析 Decimal 作为字符串

使用 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}"

它有效,但我们又失去了精度。有任何想法吗?

swift codable ios13

3
推荐指数
1
解决办法
2668
查看次数

iOS swift Codable 无法与 Alamofire 一起使用 JSON 嵌套数据?

我对 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)

ios swift alamofire codable

3
推荐指数
1
解决办法
1452
查看次数

您可以定义一个枚举来表示您的应用程序明确已知的值,但仍然处理从后端解码的未知值吗?

问题

您是否可以定义一个枚举来表示模型中属性的已知值,同时仍然允许从后端返回未知值?

简短回答:是的,可以!答案如下。

更多背景信息

作为我们应用程序的一部分,我们定义了一组功能标志,应用程序使用这些标志根据一组标准启用/禁用某些功能。这些标志作为字符串数组从后端发送回。

然而,在我们的应用程序中,我们不想处理混乱的字符串常量,而是希望将这些值定义为我们标记的枚举,以便Codable编译器自动为我们处理实际枚举情况的编码/解码。

这是此类场景的典型枚举......

enum FeatureFlag : String, CaseIterable, Codable {
    case allowsTrading
    case allowsFundScreener
    case allowsFundsTransfer
}
Run Code Online (Sandbox Code Playgroud)

这种设计的问题在于它不处理可能定义的值以及将来从后端返回的值。

有几种方法可以处理这种情况:

  1. 放弃枚举并转向字符串常量。这很容易出错,并且会破坏包含/范围界定,因为任何字符串都可以参与此逻辑。
  2. 坚持按原样使用枚举,并在后端更新时强制更新应用程序,将责任传递给部署。
  3. 更新后端以处理版本控制,以仅返回该版本的应用程序已知的值,这使后端的逻辑复杂化,以了解各种前端,但它们不应该这样做。
  4. 最常见的针对未知的防御性程序,通过为使用此枚举的每个类/结构编写自己的编码器/解码器方法,忽略当前案例列表未知的任何标志。

一到三本身就是维护噩梦。是的,四个更好,但是编写所有这些自定义序列化器/反序列化器可能非常耗时且容易出错,而且它无法利用编译器能够自动为您完成此操作的优势!

但如果有第五个呢?如果您可以使枚​​举本身在运行时优雅地处理未知值,同时在此过程中保持无损,并且不必求助于选项,该怎么办?

这就是我在下面介绍的确切解决方案!享受!

enums swift codable

3
推荐指数
1
解决办法
777
查看次数

自定义结构:类型不符合“可解码”协议

我希望能够保存一个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 ios swift codable

3
推荐指数
1
解决办法
6675
查看次数

保存结构的最快方法 iOS / Swift

我有这样的结构

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 内存量?

decode ios swift codable encodable

3
推荐指数
2
解决办法
490
查看次数

使用 Swift 中的 Codable 将具有不同键的 JSON 解析为同一对象

我收到来自不同 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)

parsing json ios swift codable

3
推荐指数
1
解决办法
1649
查看次数