I am having an issue with the new @Persisted property wrapper and decoding JSON. If I have an optional variable and it is present in the JSON, then the decoding is successful, but if I have an optional variable and that value is missing from the JSON, then the decoding fails. This is only an issue using the @Persisted property wrapper and everything works as expected using the old method of @objc and dynamic vars.
Hey @Jason_Flax I put together a small sample app to help the team debug. This project is pulling in realmDatabase v 11.1.1 and realm v 10.11.0 via swift package manager
NFLPlayer as you can see 2 of the 3 codable objects are not Object. I don’t know if that is contributing to the bug? Both versions of NFLPlayer are here (1 is commented out)
import RealmSwift
//public class NFLPlayer: Object, ObjectKeyIdentifiable, Codable {// @Persisted(primaryKey: true) public private(set) var id: String = ""// @Persisted public private(set) var draftYear: String?// @Persisted public private(set) var draftRound: String?//}@objcMemberspublicclassNFLPlayer: Object, ObjectKeyIdentifiable, Codable {
publicprivate(set)dynamicvar id: String=""publicprivate(set)dynamicvar draftYear: String?
publicprivate(set)dynamicvar draftRound: String?
publicoverrideclassfuncprimaryKey() -> String? {
"id"
}
}
structNFLPlayers: Codable {
let timestamp: String?
let player: [NFLPlayer]?let id: String?
}
structNFLPlayersWrapper: Codable {
let players: NFLPlayers?
}
This is where the network request is made
import Foundation
enum APIError: Error {
case general
}
class API {
func run(completion: @escaping (Result<[NFLPlayer]?, Error>) -> Void) {
let url = URL(string: "https://api.myfantasyleague.com/2020/export?TYPE=players&DETAILS=1&JSON=1")!
let task = URLSession.shared.dataTask(with: url, completionHandler: { data, response, error in
self.handleResponse(data: data, response: response, error: error, completion: completion)
})
task.resume()
}
private func handleResponse(data: Data?, response: URLResponse?, error: Error?, completion: @escaping (Result<[NFLPlayer]?, Error>) -> Void) {
guard let httpResponse = response as? HTTPURLResponse,
let data = data else {
completion(.failure(APIError.general))
return
}
switch httpResponse.statusCode {
case 200...299:
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let nflPlayersWrapper = try decoder.decode(NFLPlayersWrapper.self, from: data)
completion(.success(nflPlayersWrapper.players?.player))
} catch {
completion(.failure(error))
}
default:
return
}
}
}