例:
import Foundation
class Player: Codable {
let name: String
init(name: String) {
self.name = name
}
}
class Team: Codable {
let players: [Player]
let capitan: Player
init(players: [Player], capitan: Player) {
self.players = players
self.capitan = capitan
}
}
let player1 = Player(name: "p1")
let player2 = Player(name: "p2")
let team = Team(players: [player1, player2], capitan: player1)
print(team.players[0] === team.capitan) // true
let encoder = JSONEncoder()
let data = try encoder.encode(team)
let decoder = JSONDecoder()
let team2 = …Run Code Online (Sandbox Code Playgroud) 注意:我已经看过这个问题 - > 如何在Swift 4的可解码协议中使用自定义键?但它没有解释如何编码/解码枚举
这是我想要的结构:
struct MyStruct: Decodable {
let count: PostType
}
enum PostType: Decodable {
case fast(value: Int, value2: Int)
case slow(string: String, string2: String)
}
Run Code Online (Sandbox Code Playgroud)
现在我知道我希望我的结构看起来如何,问题是:
init函数应该在PostType枚举中看起来像什么.我使用下面的代码来帮助我快速构建JSON.
let jsonData = """
{
"count": {
"fast" :
{
"value": 4,
"value2": 5
}
}
}
""".data(using: .utf8)!
// Decoding
do {
let decoder = JSONDecoder()
let response = try decoder.decode(MyStruct.self, from: jsonData)
print(response)
} catch {
print(error)
}
Run Code Online (Sandbox Code Playgroud)
谁能帮我这个?
Edit1 …
我正在尝试使用Swift 4解析来自CoinmarketCap 的一些 JSON 响应。JSONDecoder()但问题是来自 json 的响应正在根据用户输入而变化。例如,如果用户想要欧元的价格,输出如下:
[
{
"price_eur": "9022.9695444"
}
]
Run Code Online (Sandbox Code Playgroud)
但如果用户想要以英镑为单位的价格:
[
{
"price_gbp": "7906.8032145"
}
]
Run Code Online (Sandbox Code Playgroud)
所以问题是Decodable如果变量(json键)名称发生变化,我应该如何制作继承自的结构?
我正在尝试创建一个函数,该函数根据传递给它的自定义JSON模型接受"Codable"类型的参数.错误 :
Cannot invoke 'decode' with an argument list of type '(T, from: Data)'
Run Code Online (Sandbox Code Playgroud)
发生在解码行上,这是函数:
static func updateDataModels <T : Codable> (url: serverUrl, type: T, completionHandler:@escaping (_ details: Codable?) -> Void) {
guard let url = URL(string: url.rawValue) else { return }
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else { return }
do {
let dataFamilies = try JSONDecoder().decode(type, from: data)// error takes place here
completionHandler(colorFamilies)
} catch let jsonErr {
print("Error serializing json:", …Run Code Online (Sandbox Code Playgroud) 如何在与 coredata NSManagedObject 映射时编码/解码 swift4 codable 中的 NSOrderedSet 变量?
import CoreData
import Foundation
@objc(TestObject)
public class TestObject:NSManagedObject,Encodable
{
@nonobjc public class func fetchRequest() -> NSFetchRequest<TestObject> {
return NSFetchRequest<TestObject>(entityName: "TestObject")
}
@NSManaged public var testName: String?
@NSManaged public var devices: NSOrderedSet? // of entity type "Device"
enum CodingKeys: String, CodingKey {
case testName
case devices
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy:CodingKeys.self)
try container.encode(testName,forKey:.testName)
try container.encode(devices,forKey:.devices)
}
}
public required convenience init(from decoder: Decoder) throws { …Run Code Online (Sandbox Code Playgroud) 我有一个非常大的 Json 文件要(几 MB)解析,但没有合适的文档。生活艰难。就我可以识别文件中的对象而言,这很容易。但是有些东西我不明白,简单的 Codable 协议失败了。在数组中,layers我可以找到三个 Layer 对象,每个对象都有属性elements。在elements我可以找到不止一个elementData在第一层有"ImageID":32dd...和component,在第二层"name":...和第三层有和"contours": [...]。可能会有更多的可能性。我的每一次尝试都以错误结束。
对不起,这段代码会很长,但我不想剪掉重要的部分:
"layers":[
{
"name":"img",
"elements":[
{
"elementData":{
"imageId":"32dd800000002"
},
"transform":{
"xScale":100,
"yScale":100
},
"active":true
},
{
"component":{
"glyphName":"e",
"layerName":"img"
}
},
{
"elementData":{
"composite":{
"builder":{
"builderGroup":{
}
}
}
},
"transform":{
"xOffset":120
},
"nonSpacing":true
}
],
"color":"maroon",
"active":true
},
{
"name":"Black",
"elements":[
{
"component":{
"glyphName":"e",
"layerName":"Black"
}
},
{
"elementData":{
"name":"caron",
"contours":[
{
"nodes":[
"80 …Run Code Online (Sandbox Code Playgroud) 我试图使用 Codable 来保存我正在创建的应用程序中的数据,但是当我将 Codable 放入我的结构中时,我不断收到错误消息:
“ReminderGroups”类型不符合“Decodable”协议
和
“ReminderGroups”类型不符合“Encodable”协议
struct ReminderGroups: Codable {
var contentsArray: [ReminderItem] = []
var reminderName: String = ""
var reminderItem: UIImage = #imageLiteral(resourceName: "Folder")
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试为 POST 请求创建一个结构。据我所知,结构符合类型Codable别名,但我不断收到错误消息
参数类型 'RegisterUserRequest.Type' 不符合预期的类型 'Encodable'" 将其作为参数传递给我的
JSONEncoder.
我试图只符合Encodable, 编写建议的必需 init() 但似乎没有任何效果。
这就是我的 Struct 的样子
struct RegisterUserRequest: Codable {
var firstName: String
var lastName: String
var email: String
var phoneNumber: String
var dateOfBirth: String
enum CodingKeys: String, CodingKey {
case firstName = "first_name"
case lastName = "last_name"
case email
case phoneNumber = "phone"
case dateOfBirth = "date_of_birth"
}
}
Run Code Online (Sandbox Code Playgroud)
这是我得到的错误
我想使用某个 URL 端点将图像文件上传到后端服务器。我可以使用 Alamofire 的上传请求作为 multipartFormData 轻松做到这一点。但是我想摆脱 Alamofire 以尽量减少对第三方框架的依赖。这是 Alamofire 代码,它有效:
func uploadRequestAlamofire(parameters: [String: Any], imageData: Data?, completion: @escaping(CustomError?) -> Void ) {
let url = imageUploadEndpoint!
let headers: HTTPHeaders = ["X-User-Agent": "ios",
"Accept-Language": "en",
"Accept": "application/json",
"Content-type": "multipart/form-data",
"ApiKey": KeychainService.getString(by: KeychainKey.apiKey) ?? ""]
Alamofire.upload(multipartFormData: { (multipartFormData) in
for (key, value) in parameters {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
}
if let data = imageData {
multipartFormData.append(data, withName: "file", fileName: "image.png", mimeType: "image/jpg")
}
}, usingThreshold: UInt64.init(), to: url, …Run Code Online (Sandbox Code Playgroud) 我知道classand的基本概念,struct但是为 API 创建模型以获取数据并告诉我优缺点更有效。
以前我不使用可选的模型。相反,我给了它一些价值。IE
class CompanyInfo : Codable {
var NameEn : String = ""
var CityEn : String = ""
var Website : String = ""
var Email : String = ""
var Phone : String = ""
var Fax : String = ""
}
Run Code Online (Sandbox Code Playgroud)
但是当它null从 API获得一些价值时。即"Fax": null然后应用程序崩溃,因为它无法使用以下行解析数据
let data = try JSONDecoder().decode(dataModel.self, from: dataSet)
Run Code Online (Sandbox Code Playgroud)
定义模型的最佳方法是什么,这样我就不需要解开可选项或给它默认值。