For these using Swift 5.x and XCode 13.x.x (i have 13.3.1) and RealmSwift (10.25.1):
Realm with Codable (Encode/Decode) (2 class for example)
import Foundation
import RealmSwift
/*
* Hold info about user profile
*/
class Profile: Object, Codable {
@Persisted(primaryKey: true) var _id: String
@Persisted var firstName: String
@Persisted var lastName: String
@Persisted var email: String
@Persisted var role: String
// Relations
@Persisted var session: Session?
@Persisted var companies: List<Company>
// MARK: Codable support
enum CodingKeys: String, CodingKey {
case email, companies
case id = "_id"
case firstName, lastName, role
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(_id, forKey: .id)
try container.encode(firstName, forKey: .firstName)
try container.encode(lastName, forKey: .lastName)
try container.encode(email, forKey: .email)
try container.encode(role, forKey: .role)
try container.encode(companies, forKey: .companies)
}
required init(from decoder: Decoder) throws {
super.init()
let container = try decoder.container(keyedBy: CodingKeys.self)
_id = try container.decode(String.self, forKey: .id)
firstName = try container.decode(String.self, forKey: .firstName)
lastName = try container.decode(String.self, forKey: .lastName)
email = try container.decode(String.self, forKey: .email)
role = try container.decode(String.self, forKey: .role)
let companiesList = try container.decode([Company].self, forKey: .companies)
companies.append(objectsIn: companiesList)
}
}
Other example:
import Foundation
import RealmSwift
/*
* Hold info about user session
*/
class Session: Object, Codable {
@Persisted(primaryKey: true) var _id: String
@Persisted(indexed: true) var accessToken: String
@Persisted var refreshToken: String
@Persisted var tokenType: String
@Persisted var expiresIn: Double
// Relations
@Persisted var profile: Profile?
// MARK: Codable support
enum CodingKeys: String, CodingKey {
case accessToken = "access_token"
case tokenType = "token_type"
case expiresIn = "expires_in"
case refreshToken = "refresh_token"
case id = "_id"
case v = "__v"
case profile
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(_id, forKey: .id)
try container.encode(accessToken, forKey: .accessToken)
try container.encode(refreshToken, forKey: .refreshToken)
try container.encode(tokenType, forKey: .tokenType)
try container.encode(expiresIn, forKey: .expiresIn)
try container.encode(profile, forKey: .profile)
}
required init(from decoder: Decoder) throws {
super.init()
let container = try decoder.container(keyedBy: CodingKeys.self)
_id = try container.decode(String.self, forKey: .id)
accessToken = try container.decode(String.self, forKey: .accessToken)
refreshToken = try container.decode(String.self, forKey: .refreshToken)
tokenType = try container.decode(String.self, forKey: .tokenType)
expiresIn = try container.decode(Double.self, forKey: .expiresIn)
profile = try container.decode(Profile.self, forKey: .profile)
}
}
You can encode List from realm with this code, for example:
try container.encode(companies, forKey: .companies)
and to decode:
let companiesList = try container.decode([Company].self, forKey: .companies)
companies.append(objectsIn: companiesList)
This is only and example, you can adapt to your need's.
And finally for example when you get data from network (i'm using Moya):
extension Session {
init(data: Data) throws {
self = try JSONDecoder().decode(Session.self, from: data)
}
}
self.xxApi.request(.login(username: "[email protected]", password: "HiTh3r3.2022")) { result in
switch result {
case let .success(response):
guard let session = try? Session(data: response.data) else {
print("Can't parse session data: \(JSON(response.data))")
return
}
// Request parsed so work with data here
print(session)
case let .failure(error):
print(error)
}
}