标签: codable

在 iOS userInfo 上使用 Swift 的 Decodable

iOS 从后台通知返回 json 数据,类型为[AnyHashable : Any]. 有什么方法可以将其解析为实现 Codable 协议的结构吗?

例子 :

// Server sends the following data via apn
{"items": [{"id": "192e7926-7891-44eb-8ca7-f795d8552e84", "text": "some text", "num": 0.7}]}
Run Code Online (Sandbox Code Playgroud)

eapp端接收数据时

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
   print(userInfo["items"])
}
Run Code Online (Sandbox Code Playgroud)

print 语句给出以下输出

Optional(<__NSSingleObjectArrayI 0x283fe80b0>(
  {
    id = "192e7926-7891-44eb-8ca7-f795d8552e84";
    num = "0.7";
    text = "Check test";
  }
))
Run Code Online (Sandbox Code Playgroud)

我已经有一个匹配的可编码结构:

struct Item: Codable {
    let id: UUID
    let text: String
    let num: Double
} …
Run Code Online (Sandbox Code Playgroud)

apple-push-notifications swift codable decodable

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

使用 Swift Codable 解码 firestore 文档时获取文档 ID

我正在使用一个类来解码检索到的 firestore 文档,如果我不想操作数据,它会按预期工作:

class Room: Identifiable, Codable {

    @DocumentID public var id:String?
    var name:String

}
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试使用自己的 init 来设置值,我无法获取 firestore 文档 ID?

class Room: Identifiable, Codable {

    @DocumentID public var id:String?
    var name:String
    
    
    enum Keys:String, CodingKey {
        case name
        case capacity
        case photo = "url"
    }
    
    required init(from decoder: Decoder) throws {

        // How do I get the document ID to set the id value?

        let container = try decoder.container(keyedBy: Keys.self)
        name = try container.decode(String.self, forKey: .name)
        capacity = try container.decode(Int.self, …
Run Code Online (Sandbox Code Playgroud)

ios swift codable google-cloud-firestore

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

无法将 @available 与 Codable 一起使用

我想将available带有renamed和参数的属性应用于符合 的unavailable属性,如下所示:structCodable

struct SampleData: Codable {
    @available(*, unavailable, renamed: "newProperty")
    let oldProperty: String
    let newProperty: String
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试构建此代码时,出现如下编译错误:

注意:“oldProperty”已在此处明确标记为不可用

在此输入图像描述

如果 astruct不符合Codable,则效果很好。

在此输入图像描述

有谁知道如何解决这个问题?

如果无法解决此问题,请告诉我原因,我将不胜感激。

提前致谢。

swift codable

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

我们可以在 Swift 中使结构体中的 Codable 键不区分大小写吗

我们可以使 Codable 键大小写不敏感吗?不是值,但键本身需要不区分大小写

struct Model: Codable, Equatable {
let number: String?
let id: String?
let address: String?

enum CodingKeys: String, CodingKey {
case number = "A-Number"
case id = "A-Id"
case address = "AddressId"
}
}
Run Code Online (Sandbox Code Playgroud)

这样它就适用于 json:

Sample Json 1
{
"A-Number" : "12345",
"A-Id" : "1",
"AddressId" : "3456"
}

Sample Json 2
{
"a-number" : "12345",
"a-id" : "1",
"addressid" : "3456"
}
Run Code Online (Sandbox Code Playgroud)

xcode ios swift codable decodable

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

Swift 4 Codable:无法排除属性

我正在开发一个简单的音乐音序器应用程序。这种应用程序倾向于具有必须保存/加载的复杂数据结构,因此Codable在Swift4中引入协议对我来说是个好消息。

我的问题是:我必须有一个非编码属性。它不必进行编码,因为它是一个临时变量,仅在应用程序处于活动状态时才保持活动状态。因此,我只是尝试通过实现来排除CodingKey,但编译器仍然给我错误“类型'Song'不符合协议'Decodable'”。

具体来说,我想在下面的代码中排除“ musicSequence”。

class Song : Codable { //Type 'Song' does not conform to protocol 'Decodable'
    var songName : String = "";    
    var tempo : Double = 120;

    // Musical structure
    var tracks : [Track] = [] // "Track" is my custom class, which conforms Codable as well    
    // Tones
    var tones = [Int : ToneSettings] (); // ToneSettings is also my custom Codable class

    var musicSequence : MusicSequence? = nil; // I get the …
Run Code Online (Sandbox Code Playgroud)

ios swift4 codable

2
推荐指数
1
解决办法
798
查看次数

怎么做 - 从Codable结构中捕获init(来自解码器:Decoder)的错误?

let jsonString = """
                    {
                        "name":1,
                        "gender":"male",
                    }
                    """

struct Person: Codable {
    var name: String
    var gender: String

    public init(from decoder: Decoder) throws {
        do {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            name = try container.decode(String.self, forKey: .name)
            gender = try container.decode(String.self, forKey: .gender)
        } catch {
            print("XXXXXX \(error)")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

从上面的代码,它不会编译,因为它抱怨,

从初始化程序返回而不初始化所有存储的属性.

我想抛出一些错误,但如果没有,我该怎么办呢

  1. 为每个属性创建默认值.
  2. 使它们都是可选的.

optional ios swift swift4 codable

2
推荐指数
1
解决办法
1184
查看次数

为什么我可以将Codable与Swift 3.3的项目语言版本一起使用?

Swift 4中引入了Codable。我的项目语言版本是Swift 3.3,但我仍然可以在项目中使用Codable。这不是问题,但是怎么可能呢?我只是想知道。

swift codable

2
推荐指数
1
解决办法
387
查看次数

Swift 4-无法使用类型为((Codable)'的参数列表调用'encode'

我建立了一组API函数,这些函数对一个对象进行编码(使用Struct符合的Codable),然后将生成的JSON Data对象发布到服务器,然后对JSON响应进行解码。一切正常-对Swift 4.2中的JSON解析新方法特别满意。但是,现在我想重构代码,以便可以将代码重用于各种方法调用-当我这样做时,我会得到一个非常烦人的错误。

func encodeRequestJSON(apiRequestObject: Codable) -> Data {
    do {
        let encoder = JSONEncoder()
        let jsonData = try encoder.encode(apiRequestObject)
        let jsonString = String(data: jsonData, encoding: .utf8)
        print(jsonString)
    } catch {
        print("Unexpected error")
        }
    return jsonData!
}
Run Code Online (Sandbox Code Playgroud)

这是错误消息:

Cannot invoke 'encode' with an argument list of type '(Codable)'
Run Code Online (Sandbox Code Playgroud)

我尝试将类型从Codable更改为Encodable,但是除了消息中的类型为(Encodable)以外,发生了相同的错误。有什么建议吗?我的后备方法是在当前ViewController中对数据进行编码,然后调用HTTPPost函数,然后在VC中进行解码。但这确实很笨拙。

json swift codable encodable

2
推荐指数
1
解决办法
539
查看次数

将无效网址解码为nil

在您回答之前:

我意识到:

  • 空字符串是无效的 URL
  • 我可以写一个定制的解码器 Employee
  • 我可以宣布urlString

我正在寻找一种更好的解决方案,用于解码可选项URL本身。我希望Codable我缺少一些魔法!


所以,我有JSON之类的

let json = Data("""
                {
                    "name": "Fred",
                    "url": ""
                }
                """.utf8)
Run Code Online (Sandbox Code Playgroud)

以及包含可选URL的相应​​对象…

struct Employee: Decodable {
    let name: String
    let url: URL?
}
Run Code Online (Sandbox Code Playgroud)

由于urlJSON中的内容无效,因此我希望将其解码为nil,而不是抛出错误。

尝试以下操作不起作用(不会被调用)…

extension Optional where Wrapped == URL {
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        do {
            self = try container.decode(URL.self)
        } catch {
            self = nil
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

过去我用过……

struct FailableDecodable<T: …
Run Code Online (Sandbox Code Playgroud)

url swift codable

2
推荐指数
1
解决办法
58
查看次数

如何使用Codable处理JSON响应的失败案例?

我有一些来自服务器的JSON响应。成功的情况下,可能是这样的:

{
  "success": true, 
  "data": [
    {
       /// something here 
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

如果所有服务器响应都将成功,那么解析该JSON真的很容易。但是我们也有失败案例,例如:

{
  "success": false, 
  "msg": "Your session expired",
  "end_session": true 
}
Run Code Online (Sandbox Code Playgroud)

这意味着我们需要处理两种情况。如您所注意到的,类似的属性success, msg可能出现在任何响应中。为了解决这个问题,我创建了以下结构:

struct RegularResponse<T: Codable>: Codable {
let success: Bool
let msg: String?
let endSession: Bool?
let data: T?

enum CodingKeys: String, CodingKey {
    case success, msg, data
    case endSession = "end_session"
}

}
Run Code Online (Sandbox Code Playgroud)

如果响应成功或不成功,它可能包含一些数据,可以识别出发生错误的原因(使用successattribute或msg)。解析过程如下:

let model = try JSONDecoder().decode(RegularResponse<MyModel>.self, from: data)

            if model.success {
                // do something with data …
Run Code Online (Sandbox Code Playgroud)

json ios swift codable

2
推荐指数
1
解决办法
54
查看次数