2 / 10
Jul 2021

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.

This works,

@objcMembers public class MyObject: Object, ObjectKeyIdentifiable, Codable { public private(set) dynamic var id: String = "" public private(set) dynamic var myVar1: String public private(set) dynamic var myVar2: String? public override class func primaryKey() -> String? { "id" } }

This doesn’t,

public class MyObject: Object, ObjectKeyIdentifiable, Codable { @Persisted(primaryKey: true) public private(set) var id: String = "" @Persisted public private(set) var myVar1: String @Persisted public private(set) var myVar2: String? }

This is the error,

“No value associated with key CodingKeys(stringValue: "myVar2", intValue: nil) ("myVar2"), converted to my_var2.”, underlyingError: nil))

And my decoder is set to convert from snake case,

let decoder = JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase

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

testApp.swift

import SwiftUI @main struct testApp: App { var body: some Scene { WindowGroup { ContentView() } } }

ContentView the main SwiftUI view

import SwiftUI struct ContentView: View { var body: some View { Text("Hello, world!") .padding() .onAppear { API().run { switch $0 { case .success(let nflPlayers): print("NFLPlayers: \(String(describing: nflPlayers))") case .failure(let error): print("ERROR: \(error)") } } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }

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? //} @objcMembers public class NFLPlayer: Object, ObjectKeyIdentifiable, Codable { public private(set) dynamic var id: String = "" public private(set) dynamic var draftYear: String? public private(set) dynamic var draftRound: String? public override class func primaryKey() -> String? { "id" } } struct NFLPlayers: Codable { let timestamp: String? let player: [NFLPlayer]? let id: String? } struct NFLPlayersWrapper: 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 } } }

I am following along and don’t have an answer but I am curious why you’re doing this

When there are no setters or getters within the object - e.g. why private(set)?

Thank you @Diana_Maria_Perez_Af . That is exactly what I need.

Closed on Aug 2, 2021

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.