I'm attempting to integrate SwiftData into my networking model to incorporate local persistence. In order to achieve this, I need to ensure that my Codable model conforms to SwiftData. However, I encounter an error during the build process. Has anyone else encountered a similar issue and found a resolution?
Below are my models: I've omitted certain model properties to enable the post's release.
import SwiftData
import SwiftUI
// MARK: - Game
@Model
class Game: Codable, Identifiable, Hashable {
let id: Int?
let name: String?
let cover: Cover?
let firstReleaseDate: Int?
let summary: String?
let totalRating: Double?
let ratingCount: Int?
let genres: [Genre]?
let platforms: [Platform]?
let releaseDates: [ReleaseDate]?
let screenshots: [Cover]?
let gameModes: [GameMode]?
let videos: [Video]?
let websites: [Website]?
let similarGames: [Int]?
let artworks: [Artwork]?
enum CodingKeys: String, CodingKey {
case id, name, cover, artworks, genres, platforms, screenshots, summary, videos, websites
case firstReleaseDate = "first_release_date"
case releaseDates = "release_dates"
case totalRating = "total_rating"
case ratingCount = "rating_count"
case gameModes = "game_modes"
case similarGames = "similar_games"
}
init(
id: Int? = nil,
name: String? = nil,
cover: Cover? = nil,
firstReleaseDate: Int? = nil,
summary: String? = nil,
totalRating: Double? = nil,
versionTitle: String? = nil,
ratingCount: Int? = nil,
genres: [Genre]? = nil,
platforms: [Platform]? = nil,
releaseDates: [ReleaseDate]? = nil,
screenshots: [Cover]? = nil,
gameModes: [GameMode]? = nil,
videos: [Video]? = nil,
websites: [Website]? = nil,
similarGames: [Int]? = nil,
artworks: [Artwork]? = nil
) {
self.id = id
self.name = name
self.cover = cover
self.firstReleaseDate = firstReleaseDate
self.summary = summary
self.totalRating = totalRating
self.ratingCount = ratingCount
self.genres = genres
self.platforms = platforms
self.releaseDates = releaseDates
self.screenshots = screenshots
self.gameModes = gameModes
self.videos = videos
self.websites = websites
self.similarGames = similarGames
self.artworks = artworks
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.id = try container.decode(Int?.self, forKey: .id)
self.name = try container.decode(String?.self, forKey: .name)
self.firstReleaseDate = try container.decode(Int?.self, forKey: .firstReleaseDate)
self.summary = try container.decode(String?.self, forKey: .summary)
self.totalRating = try container.decode(Double?.self, forKey: .totalRating)
self.genres = try container.decode([Genre]?.self, forKey: .genres)
self.platforms = try container.decode([Platform]?.self, forKey: .platforms)
self.releaseDates = try container.decode([ReleaseDate]?.self, forKey: .releaseDates)
self.screenshots = try container.decode([Cover]?.self, forKey: .screenshots)
self.gameModes = try container.decode([GameMode]?.self, forKey: .gameModes)
self.videos = try container.decode([Video]?.self, forKey: .videos)
self.websites = try container.decode([Website]?.self, forKey: .websites)
self.similarGames = try container.decode([Int]?.self, forKey: .similarGames)
self.artworks = try container.decode([Artwork]?.self, forKey: .artworks)
self.cover = try container.decode(Cover?.self, forKey: .cover)
self.ratingCount = try container.decode(Int?.self, forKey: .ratingCount)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(cover, forKey: .cover)
try container.encode(artworks, forKey: .artworks)
try container.encode(firstReleaseDate, forKey: .firstReleaseDate)
try container.encode(genres, forKey: .genres)
try container.encode(name, forKey: .name)
try container.encode(platforms, forKey: .platforms)
try container.encode(releaseDates, forKey: .releaseDates)
try container.encode(screenshots, forKey: .screenshots)
try container.encode(summary, forKey: .summary)
try container.encode(totalRating, forKey: .totalRating)
try container.encode(ratingCount, forKey: .ratingCount)
try container.encode(gameModes, forKey: .gameModes)
try container.encode(videos, forKey: .videos)
try container.encode(websites, forKey: .websites)
try container.encode(similarGames, forKey: .similarGames)
}
}
// MARK: - Artwork
@Model
class Artwork: Codable, Hashable {
let id: Int?
let url: String?
enum CodingKeys: CodingKey {
case id
case url
}
init(id: Int?, url: String?) {
self.id = id
self.url = url
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.id = try container.decode(Int?.self, forKey: .id)
self.url = try container.decode(String?.self, forKey: .url)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(url, forKey: .url)
}
}
// MARK: - Cover
@Model
class Cover: Codable, Hashable {
let id: Int?
let url: String?
enum CodingKeys: CodingKey {
case id
case url
}
init(id: Int?, url: String?) {
self.id = id
self.url = url
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.id = try container.decode(Int?.self, forKey: .id)
self.url = try container.decode(String?.self, forKey: .url)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(url, forKey: .url)
}
}
// MARK: - Genre
@Model
class Genre: Codable, Hashable {
let id: Int?
let name: String?
enum CodingKeys: CodingKey {
case id
case name
}
init(id: Int?, name: String?) {
self.id = id
self.name = name
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.id = try container.decode(Int?.self, forKey: .id)
self.name = try container.decode(String?.self, forKey: .name)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(name, forKey: .name)
}
}
// MARK: - GameMode
@Model
class GameMode: Codable, Hashable {
////
}
// MARK: - Platform
@Model
class Platform: Codable, Hashable {
////
}
// MARK: - ReleaseDate
@Model
class ReleaseDate: Codable, Hashable, Comparable {
////
}
// MARK: - Video
@Model
class Video: Codable, Hashable {
////
}
// MARK: - Website
@Model
class Website: Codable, Hashable {
////
}
Tried to convert a Codable model to conform to Swift Data @Model Macro

SwiftData (or any of the new macros) appears to not be compatible with
Codable.There is no documentation for or against this but the one example where Apple replicates using SwiftData for server data they create an auxiliary
structand initialize with aconvenience init.https://developer.apple.com/documentation/swiftdata/maintaining-a-local-copy-of-server-data