I am loading a users notifications, there are different notification types (like, comment, follow) and I need to decode each based on their "type" property but I am new to taking this approach and have spent all day trying to figure out how to do this...
Right now I keep getting the decoding error in my NotificationsEnum and I think its because I don't know how to access the type property inside each object returned in my array.
I tried using this SO question & answer Decode JSON from the nested container and check its type dynamically for typecasting in swift but it is with classes and I am using structs.
How can I decode each of these objects based on their type property?? I feel like I need to figure out how to implement nestedUnkeyedContainer and nestedContainer somehow but I am having a hard time getting this to work.
Also, after getting the decoding to work, how can I put all of these objects in the same array? Would it be a generics since I would switch on their type to route the notifications to different notification views...??
THANK YOU
Different JSON activity I need to decode depending on type
[
{
_id: 61dc9bde82d0715,
type: 'like',
username: 'testuser1',
likeId: 61dcb2d0712
},
{
_id: 61dc9bde82d0715,
type: 'follow',
username: 'testuser2',
followId: 61dc9bd2d0712
},
{
_id: 61dc9b2d0715,
type: 'comment',
username: 'testuser3',
commentId: 61dc9bb2d0712
}
]
PROFILE/PARENT DATA MODEL
struct ProfileData: Decodable {
**otherProperties**
var notifications: [NotificationsEnum]
// ^ Is this correct type? Was thinking I might need some kind of generic array??
}
// HOW CAN I IMPLEMENT nestedUnkeyedContainer and nestedContainer here???
enum NotificationsEnum: Decodable {
enum DecodingError: Error {
case wrongJSON
}
case like(LikeActivity)
case comment(CommentActivity)
case follow(FollowActivity)
enum CodingKeys: String, CodingKey {
case like = "like"
case comment = "comment"
case follow = "follow"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
switch container.allKeys.first {
case .like:
let value = try container.decode(LikeActivity.self, forKey: .like)
self = .like(value)
case .comment:
let value = try container.decode(CommentActivity.self, forKey: .comment)
self = .comment(value)
case .follow:
let value = try container.decode(FollowActivity.self, forKey: .follow)
self = .follow(value)
case .none:
throw DecodingError.wrongJSON
}
}
}
MODELS
struct LikeActivity: Codable {
let id: String
let type: String
let username: String
let likeId: String
}
struct CommentActivity: Codable {
let id: String
let type: String
let username: String
let commentId: String
}
struct FollowActivity: Codable {
let id: String
let type: String
let username: String
let followId: String
}