Codable class does not conform to protocol Decodable
Why am I getting a "Type 'Bookmark' does not conform to protocol 'Decodable'" error message
It's either because Publication isn't Decodable (you have not shown what it is, so it's hard to tell) or because of the weak
designation on publication
.
Either way, it's easy to fix: you just need to implement init(from:)
to complete the implementation of Decodable; the compiler is simply telling you that this implementation cannot be synthesized.
Codable class doesn't conform to protocol 'Decodable'
It is not necessary to separate the structs. The error occurs because you have added too many keys in the CodingKeys
enum. If you keep only the required ones, then it will work:
struct Model: Codable {
let aps: Aps
let link: String?
let checkAction: String?
enum CodingKeys: String, CodingKey {
case aps ,link
case checkAction = "gcm.notificaiton.check_action"
}
struct Aps: Codable {
let alert: Alert
let sound: String?
struct Alert: Codable {
let title: String?
let body: String?
}
}
}
alert
, sound
etc are not coding keys of Model
. They are coding keys of Aps
. It is not necessary to specify them in Aps
, because they are the same as the property names.
Custom Struct: Type does not conform to protocol 'Decodable'
You will need to make Wish
adopt Codable
.
But because UIImage
and UIColor
are not Codable
, you’ll have to manually implement them as outlined in Encoding and Decoding Custom Types:
struct Wishlist: Codable {
var name: String
var image: UIImage
var wishes: [Wish]
var color: UIColor
var textColor: UIColor
var index: Int
enum CodingKeys: String, CodingKey {
case name, image, wishData, color, textColor, index
}
init(name: String, image: UIImage, wishes: [Wish], color: UIColor, textColor: UIColor, index: Int) {
self.name = name
self.image = image
self.wishes = wishes
self.color = color
self.textColor = textColor
self.index = index
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decode(String.self, forKey: .name)
wishes = try values.decode([Wish].self, forKey: .wishData)
color = try values.decode(Color.self, forKey: .color).uiColor
textColor = try values.decode(Color.self, forKey: .textColor).uiColor
index = try values.decode(Int.self, forKey: .index)
let data = try values.decode(Data.self, forKey: .image)
guard let image = UIImage(data: data) else {
throw DecodingError.dataCorruptedError(forKey: .image, in: values, debugDescription: "Invalid image data")
}
self.image = image
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
try container.encode(wishes, forKey: .wishData)
try container.encode(Color(uiColor: color), forKey: .color)
try container.encode(Color(uiColor: textColor), forKey: .textColor)
try container.encode(index, forKey: .index)
try container.encode(image.pngData(), forKey: .image)
}
}
struct Wish: Codable {
public var name: String
public var checkedStatus: Bool
public var link: String
public var price: String
public var note: String
public var image: UIImage
init(name: String, link: String, price: String, note: String, image: UIImage, checkedStatus: Bool) {
self.name = name
self.checkedStatus = checkedStatus
self.link = link
self.price = price
self.note = note
self.image = image
}
enum CodingKeys: String, CodingKey {
case name, checkedStatus, link, price, note, image
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decode(String.self, forKey: .name)
checkedStatus = try values.decode(Bool.self, forKey: .checkedStatus)
link = try values.decode(String.self, forKey: .link)
price = try values.decode(String.self, forKey: .price)
note = try values.decode(String.self, forKey: .note)
let data = try values.decode(Data.self, forKey: .image)
guard let image = UIImage(data: data) else {
throw DecodingError.dataCorruptedError(forKey: .image, in: values, debugDescription: "Invalid image data")
}
self.image = image
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
try container.encode(checkedStatus, forKey: .checkedStatus)
try container.encode(link, forKey: .link)
try container.encode(price, forKey: .price)
try container.encode(note, forKey: .note)
try container.encode(image.pngData(), forKey: .image)
}
}
Where I’d use this as a convenient way to encode UIColor
objects:
struct Color: Codable {
let red: CGFloat
let green: CGFloat
let blue: CGFloat
let alpha: CGFloat
init(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
self.red = red
self.green = green
self.blue = blue
self.alpha = alpha
}
init(uiColor: UIColor) {
var red: CGFloat = 0
var green: CGFloat = 0
var blue: CGFloat = 0
var alpha: CGFloat = 0
uiColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
self.red = red
self.green = green
self.blue = blue
self.alpha = alpha
}
var uiColor: UIColor { UIColor(red: red, green: green, blue: blue, alpha: alpha) }
}
Note, I did a couple of unrelated changes:
I made both of these
struct
. I wouldn’t introduce reference types (much lessNSObject
subclasses) unless necessary.I simplified some of the property names. E.g. in
Wish
, we wouldn’t generally usewish
prefix in property names. I also wouldn’t use “data” in a property name unless it was, in fact, aData
.I updated
init
methods to use standard naming conventions.
My structure does not conform to protocol 'Decodable' / 'Encodable' if I use protocol type in my structure in swift
JSONDecoder
needs to know the concrete type of thing that you want to decode the JSON into. After all, everything must have a concrete type at runtime, that you can get with type(of:)
. You can't tell it to just "decode a protocol". The encoder is a bit different though - it doesn't actually need to know the concrete type, and there is a way to get around it.
It seems like the type of UIConfig
depends on objectid
, so we can check objectid
and decide what type of UIConfig
to decode:
enum CodingKeys: CodingKey {
case id, objectid, config
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(String.self, forKey: .id)
objectid = try container.decode(String.self, forKey: .objectid)
if objectid == "bd_label" {
config = try container.decode(LabelConfig.self, forKey: .config)
} else if objectid == "bd_button" {
config = try container.decode(ButtonConfig.self, forKey: .config)
}
// other cases...
else {
throw DecodingError.dataCorruptedError(forKey: .config, in: container, debugDescription: "no suitable config type found for objectid \(objectid)!")
}
}
For the Encodable
part, you can make a "type eraser"-like thingy:
struct AnyEncodable: Encodable {
let encodeFunction: (Encoder) throws -> Void
init(_ encodable: Encodable) {
encodeFunction = encodable.encode(to:)
}
func encode(to encoder: Encoder) throws {
try encodeFunction(encoder)
}
}
and do:
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(objectid, forKey: .objectid)
try container.encode(AnyEncodable(config), forKey: .config)
}
By using AnyEncodable
, we are basically wrapping the protocol in a concrete type, but don't worry - this won't actually create an extra pair of curly brackets in the JSON.
Type 'Model' does not conform to protocol 'Decodable'/Encodable
A @Published
property with type, let's say, String
, are of type Published<String>
. And apparently, that type is not Codable
.
You can solve this by writing custom encode and decode functions. That's not difficult; it's only some extra lines of code. Please see the documentation on Codable
for some examples.
Here is an example for your case:
class TimeModel: Codable, Identifiable, ObservableObject {
@Published var id: UUID = UUID()
@Published var nome : String
@Published var time : String
func aggiornaUI() {
DispatchQueue.main.async {
self.objectWillChange.send()
}
}
init(nome: String, time: String) {
self.nome = nome
self.time = time
}
enum CodingKeys: String, CodingKey {
case id
case nome
case time
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(nome, forKey: .nome)
try container.encode(time, forKey: .time)
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(UUID.self, forKey: .id)
nome = try container.decode(String.self, forKey: .nome)
time = try container.decode(String.self, forKey: .time)
}
}
This should work, but I can't really test it because I don't know the rest of your code.
Type does not conform to protocol 'Decodable'/'Encodable'
Every property in a Codable
type must also be Codable
as well.
The simplest way to make a type codable is to declare its properties
using types that are already Codable.
Built-in Codable types — String, Int, Double, Data, URL Array,
Dictionary, Optional are Codable if they contain Codable types
Hence, the AdditionalCharge
must also be Codable
for FundingRequest
to be Codable
.
class AdditionalCharge: Codable {
var ItemDescription = ""
var ItemValue:String = ""
}
Type '' does not conform to protocol 'Decodable'/'Encodable'
Instead of NSNumber use native Swift types, like Double, and align other code to that
struct Spty: Identifiable, Codable{
@DocumentID var id: String? = UUID().uuidString
var spty: String
var r: Double
var g: Double
var b: Double
}
Type 'PlayerData' does not conform to protocol 'Decodable' and 'Encodable'
Player
should conform also
class Player : Codable {
Type 'Response' does not conform to protocol 'Decodable' \ 'Encodable'
The issue is caused by the fact that you declared both properties of Response
as implicitly unwrapped optionals (IOU). The compiler cannot autogenerate the required methods of Codable
for IOU properties.
However, there's no need to make those IOU anyways. If they are required properties that are always present in the response, make them non-optional. If they might be missing, make them Optional
(use ?
instead of !
).
Also, Swift is not Objective-C. There's no need to make your types inherit from NSObject
. And you should also use struct
s instead of class
es unless you explicitly need reference type behaviour. You should also make all properties immutable unless you explicitly need to be able to mutate them.
struct ErrorObj: Codable {
let numError: Int
let description: String
}
struct Response<T: Codable>: Codable {
let error: ErrorObj
let result: T
func getResponse(errorObj: (ErrorObj) -> Void, successObj: (T) -> Void) {
if error.numError != 0 {
errorObj(error)
} else{
successObj(result)
}
}
}
Related Topics
Swiftui Text View Does Not Show Non-Displayable Characters
How to Split a String at The Last Occurence of a Sequence
Strange Behavior with Swift Compiler
Swift Cannot Invoke '*' with an Argument List of Type '(Int, Int)'
What Is The Default Value of The Padding Modifier in Swift
How Are Swift Enums Implemented Internally
Swift Playground with Debugger Support
Access Class Property from Instance
When How to Start Submitting Apps to The iOS App Store Written Using The Swift Programming Language
Modifying Struct Instance Variables Within a Dispatch Closure in Swift
Ambiguous Use of 'Filter' When Converting Project to Swift 4
Check Os Version Using Swift on MAC Os X
Can't Upload .Ipa from Xcode 8, "The Info.Plist Indicates a iOS App, But Submitting a Pkg or Mpkg."
Missing Required Module Firebase - Jenkins Build Error
Loading Image from Assets to Nsimage Keep Getting Error, Expecting Nsimage.Name
Cocoapods Framework with Dependencies - Include of Non-Modular Header Inside Framework Module
Access Id Does Not Work When Testing a Textfield with 'Issecuretextentry = True'