I am working on mix and match iOS source code. I have implemented codable for swift data model class which reduces the burden of writing parser logic. I tried to conform my objective c class to codable protcol which in turn thrown an error "Cannot find protocol declaration for 'Codable'". Is there any way to use this swift protocol into objective c class? Or Is there any other objective c api that provides the same capability as Codable? The idea is to make the parsing logic same across swift and objective c classes.
Asked
Active
Viewed 1.7k times
23
-
NSCoding is the corresponding Objective-C protocol that also was used for Swift before Codable was introduced – Joakim Danielson May 31 '18 at 06:24
-
@JoakimDanielson - Conforming to NSCoding protocol, custom class objects can be serialized/deserialized to archive/unarchive. Will this help to parse jsonobject to custom type or vice versa? – myCmyL May 31 '18 at 06:39
-
2No. You can't. `Codable` is only available to **Swift** only. And there is no counter-part for **Objective-C**, because if there was one then why introducing `Codable` after all? – nayem May 31 '18 at 06:55
-
Read Jordan Rose's explanation, [Why You Cant Make Someone Else's Class Decodable](https://forums.swift.org/t/why-you-cant-make-someone-elses-class-decodable-a-long-winded-explanation-of-required-initializers/6437), which touches on how required initializers and subclasses make for Problems with non-final data structures. ObjC does not have `final`, so those reasons apply to the current poster's question as well. – AmitaiB Jan 09 '19 at 16:17
2 Answers
14
Yes, you can use Codable together with Obj-C. The tricky part is that because Obj-C can't see Decoder
, so you will need to create a helper class method when you need it to be allocated from Obj-C side.
public class MyCodableItem: NSObject, Codable {
private let id: String
private let label: String?
enum CodingKeys: String, CodingKey {
case id
case label
}
@objc public class func create(from url: URL) -> MyCodableItem {
let decoder = JSONDecoder()
let item = try! decoder.decode(MyCodableItem.self, from: try! Data(contentsOf: url))
return item
}
public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(String.self, forKey: .id)
label = try? container.decode(String.self, forKey: .label)
super.init()
}
required init(coder decoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

supc
- 190
- 1
- 9
-
Hi, can i pass i dictionary instead of an url to the create func? And also, what is the point of returning the the item in the create function? how objc call will interact with this swift codable clss? because it seems like you are not using the swift class at all but just creating a func inside of it to do the parsing without reusing the codable code already provided by the swift class. – Coder Oct 17 '21 at 20:46
-
The purpose of exposing the `create` method was to use it as a work around so Objective-C can work with Codable in some way. So you can definitely create some other helper methods to help you converting any type of data to a Codable class. – supc Oct 19 '21 at 00:16
3
class LoginDataModel: NSObject ,Codable {
@objc var stepCompleted: String?
@objc var userID: Int?
@objc var authkey: String?
@objc var type, status: String?
enum CodingKeys: String, CodingKey {
case stepCompleted = "step_completed"
case userID = "user_id"
case authkey
case type, status
}
}

Arjun Patel
- 1,394
- 14
- 23