使用swift4的Codable协议,有很多级别的引擎日期和数据转换策略.
鉴于JSON:
{
"name": "Bob",
"age": 25,
"tax_rate": "4.25"
}
Run Code Online (Sandbox Code Playgroud)
我想将它强制进入以下结构
struct ExampleJson: Decodable {
var name: String
var age: Int
var taxRate: Float
enum CodingKeys: String, CodingKey {
case name, age
case taxRate = "tax_rate"
}
}
Run Code Online (Sandbox Code Playgroud)
日期解码策略可以将基于字符串的日期转换为日期.
基于String的Float是否有某种功能
否则我一直坚持使用CodingKey引入一个String并使用计算得到:
enum CodingKeys: String, CodingKey {
case name, age
case sTaxRate = "tax_rate"
}
var sTaxRate: String
var taxRate: Float { return Float(sTaxRate) ?? 0.0 }
Run Code Online (Sandbox Code Playgroud)
这种方式比我看起来需要更多的维护.
这是最简单的方式还是类似于DateDecodingStrategy用于其他类型的转换?
更新:我应该注意:我也走了超越的路线
init(from decoder:Decoder)
Run Code Online (Sandbox Code Playgroud)
但这是相反的方向,因为它迫使我为自己做这一切.
我正在尝试将我的对象序列化如下:
import Foundation
struct User: Codable {
let username: String
let profileURL: String
}
let user = User(username: "John", profileURL: "http://google.com")
let json = try? JSONEncoder().encode(user)
if let data = json, let str = String(data: data, encoding: .utf8) {
print(str)
}
Run Code Online (Sandbox Code Playgroud)
但是在macOS上我得到以下内容:
{"profileURL":"http:\/\/google.com","username":"John"}
Run Code Online (Sandbox Code Playgroud)
(注意转义'/'字符).
在Linux机器上,我得到:
{"username":"John","profileURL":"http://google.com"}
Run Code Online (Sandbox Code Playgroud)
如何让JSONEncoder在macOS上返回未转义的表单?
我需要JSON中的字符串严格未转义.
我Codable第一次使用Swift 4的协议,我无法理解使用decodeIfPresentfrom Decodable.
/// Decodes a value of the given type for the given key, if present.
///
/// This method returns `nil` if the container does not have a value associated with `key`, or if the value is null. The difference between these states can be distinguished with a `contains(_:)` call.
///
/// - parameter type: The type of value to decode.
/// - parameter key: The key that the decoded value is associated …Run Code Online (Sandbox Code Playgroud) 我已定义enum如下:
enum Type: String, Codable {
case text = "text"
case image = "image"
case document = "document"
case profile = "profile"
case sign = "sign"
case inputDate = "input_date"
case inputText = "input_text"
case inputNumber = "input_number"
case inputOption = "input_option"
case unknown
}
Run Code Online (Sandbox Code Playgroud)
映射JSON字符串属性.自动序列化和反序列化工作正常,但我发现如果遇到不同的字符串,反序列化将失败.
是否可以定义一个unknown映射任何其他可用案例的案例?
这可能非常有用,因为这些数据来自RESTFul API,可能会在将来发生变化.
Swift JSONDecoder提供了一个dateDecodingStrategy属性,允许我们根据DateFormatter对象定义如何解释传入的日期字符串.
但是,我目前正在使用一个API,它返回date strings(yyyy-MM-dd)和datetime strings(yyyy-MM-dd HH:mm:ss),具体取决于属性.有没有办法JSONDecoder处理这个,因为提供的DateFormatter对象一次只能处理dateFormat一个?
一个火腿解决方案是重写附带的Decodable模型,只接受字符串作为其属性,并提供公共Dategetter/setter变量,但这对我来说似乎是一个糟糕的解决方案.有什么想法吗?
我有以下代码.
import Foundation
let jsonData = """
[
{"firstname": "Tom", "lastname": "Smith", "age": "28"},
{"firstname": "Bob", "lastname": "Smith"}
]
""".data(using: .utf8)!
struct Person: Codable {
let firstName, lastName: String
let age: String?
enum CodingKeys : String, CodingKey {
case firstName = "firstname"
case lastName = "lastname"
case age
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
firstName = try values.decode(String.self, forKey: .firstName)
lastName = try values.decode(String.self, forKey: .lastName)
age = try values.decode(String.self, forKey: .age) …Run Code Online (Sandbox Code Playgroud) 我目前正在处理Codable项目中的类型并遇到问题.
struct Person: Codable
{
var id: Any
}
Run Code Online (Sandbox Code Playgroud)
id在上面的代码中可以是a String或an Int.这就是id类型的原因Any.
我知道Any不是Codable.
我需要知道的是我如何才能使它发挥作用.
在应用程序中,我们有两种类型的贴纸,字符串和位图。每个贴纸包可以包含这两种类型。这就是我声明模型的方式:
// Mark: - Models
protocol Sticker: Codable {
}
public struct StickerString: Sticker, Codable, Equatable {
let fontName: String
let character: String
}
public struct StickerBitmap: Sticker, Codable, Equatable {
let imageName: String
}
Run Code Online (Sandbox Code Playgroud)
在用户选择一些贴纸并使用它们后,我们希望将这些贴纸保存到其中,UserDefaults以便我们可以向他显示“最近使用过的”贴纸选项卡。我正在尝试解码保存的[Sticker]数组:
let recentStickers = try? JSONDecoder().decode([Sticker].self, from: data)
Run Code Online (Sandbox Code Playgroud)
但我收到以下编译错误:
Protocol type 'Sticker' cannot conform to 'Decodable' because only concrete types can conform to protocols
Run Code Online (Sandbox Code Playgroud)
我不明白为什么我声明Stickeras Codablewhich 也实现了Decodable. 任何帮助将不胜感激!
所以我有一个返回JSON对象数组的API路由.例如:
[
{"firstname": "Tom", "lastname": "Smith", "age": 31},
{"firstname": "Bob", "lastname": "Smith", "age": 28}
]
Run Code Online (Sandbox Code Playgroud)
我试图想象如何在Swift中使用新的可编码特性将它们转换为类中的两个对象.因此,如果我有一个可编码的人类,我会想要采取这种反应并让它给我两个人物.
我也在使用Alamofire来处理这些请求.
我怎样才能做到这一点?到目前为止,我所看到的与可编码内容有关的所有内容只允许1个对象.我还没有看到任何与Alamofire或Web框架的集成.
Swift 4有Codable,真棒.但UIImage默认情况下不符合它.我们怎么做?
我试过singleValueContainer和unkeyedContainer
extension UIImage: Codable {
// 'required' initializer must be declared directly in class 'UIImage' (not in an extension)
public required init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let data = try container.decode(Data.self)
guard let image = UIImage(data: data) else {
throw MyError.decodingFailed
}
// A non-failable initializer cannot delegate to failable initializer 'init(data:)' written with 'init?'
self.init(data: data)
}
public func encode(to encoder: Encoder) throws {
var …Run Code Online (Sandbox Code Playgroud)