So I have some JSON data that I pull from an api using alamofire. When the data comes back the structure looks like this
{
"sneakers" : {
"brands" : {
"Adidas" : [ {
"brand" : "adidas",
"category" : "lifestyle",
"colorway" : "Cream White/Cream White/Core White",
"description" : "First released on April 29, 2017, the Yeezy Boost 350 V2 ‘Cream White’ combines a cream Primeknit upper with tonal cream SPLY 350 branding, and a translucent white midsole housing full-length Boost. Released again in October 2018, this retro helped fulfill Kanye West’s oft-repeated ‘YEEZYs for everyone’ Twitter mantra, as adidas organized the biggest drop in Yeezy history by promising pre-sale to anyone who signed up on the website. Similar to the first release, the ‘Triple White’ 2018 model features a Primeknit upper, a Boost midsole and custom adidas and Yeezy co-branding on the insole.",
"designer" : "Kanye West",
"imagesrc" : "https://image.goat.com/crop/1250/attachments/product_template_additional_pictures/images/014/822/695/original/116662_03.jpg.jpeg",
"maincolor" : "White",
"name" : "Yeezy Boost 350 V2 'Cream White / Triple White'",
"nickname" : "Cream White / Triple White",
"price" : "Buy New - $220",
"productlink" : "$190YEEZY BOOST 350 V2 'CREAM WHITE / TRIPLE WHITE'",
"productlinkhref" : "https://www.goat.com/sneakers/yeezy-boost-350-v2-cream-white-cp9366",
"releasedate" : "2017-04-29",
"silhouette" : "Yeezy Boost 350",
"technology" : "Boost",
"webscraperorder" : "1554084922-147",
"webscraperstarturl" : "https://www.goat.com/sneakers"
}
]
}
}
}
Where there can be potentially more brands( Nike, Air Jordan) that have more sneakers under them. Using Swift Decodable protocol I was able to properly parse the JSON data into objects that are easily readable for any user. This code can be seen below.
import Foundation
import RealmSwift
import Realm
struct Sneaker: Decodable {
var sneakers : Sneakers
}
struct Sneakers: Decodable {
let brands: Shoe
}
struct Shoe: Decodable {
let adidas: [SneakerInfo]
let nike: [SneakerInfo]
let airjordan: [SneakerInfo]
let vans: [SneakerInfo]
enum CodingKeys: String, CodingKey {
case adidas = "Adidas"
case nike = "Nike"
case airjordan = "Air Jordan"
case vans = "Vans"
}
}
struct SneakerInfo: Decodable {
let brand, category, colorway, description: String?
let designer: String?
let imagesrc: String?
let maincolor, name, nickname, price: String?
let productlink: String?
let productlinkhref: String?
let releasedate, silhouette, technology, webscraperorder: String?
let webscraperstarturl: String?
enum CodingKeys: String, CodingKey {
case brand, category, colorway, description, designer, imagesrc, maincolor, name, nickname, price, productlink, productlinkhref, releasedate, silhouette, technology,webscraperorder,webscraperstarturl
}
}
Currently I am trying to migrate this same code to be ready to use with realm and codable but I keep getting errors.
My issue is complaining about my implementation and the inits. I will include the class below. I have been stuck on this all day.
import Foundation
import Realm
import RealmSwift
@objcMembers class SneakerTemp: Object, Decodable {
dynamic var sneaker: SneakersTemp
enum CodingKeys: String, CodingKey {
case sneaker
}
required init()
{
super.init()
}
override static func primaryKey() -> String?
{
return UUID().uuidString
}
required init(from decoder: Decoder) throws
{
let container = try decoder.container(keyedBy: CodingKeys.self)
sneaker = try container.decode(SneakersTemp.self, forKey: .sneaker)
super.init()
}
required init(value: Any, schema: RLMSchema)
{
super.init(value: value, schema: schema)
}
required init(realm: RLMRealm, schema: RLMObjectSchema)
{
super.init(realm: realm, schema: schema)
}
}
@objcMembers class SneakersTemp: Object, Decodable {
dynamic var brands:ShoeTemp
enum CodingKeys: String, CodingKey {
case brands
}
required init()
{
super.init()
}
override static func primaryKey() -> String?
{
return UUID().uuidString
}
required init(from decoder: Decoder) throws
{
let container = try decoder.container(keyedBy: CodingKeys.self)
brands = try container.decode(ShoeTemp.self, forKey: .brands)
super.init()
}
required init(value: Any, schema: RLMSchema)
{
super.init(value: value, schema: schema)
}
required init(realm: RLMRealm, schema: RLMObjectSchema)
{
super.init(realm: realm, schema: schema)
}
}
@objcMembers class ShoeTemp: Object, Decodable {
let adidas = RealmSwift.List<SneakerInfoTemp>()
let nike = RealmSwift.List<SneakerInfoTemp>()
let airjordan = RealmSwift.List<SneakerInfoTemp>()
let vans = RealmSwift.List<SneakerInfoTemp>()
enum CodingKeys: String, CodingKey {
case adidas = "Adidas"
case nike = "Nike"
case airjordan = "Air Jordan"
case vans = "Vans"
}
required init(from decoder: Decoder) throws
{
let container = try decoder.container(keyedBy: CodingKeys.self)
adidas = try container.decode(String.self, forKey: .adidas)
nike = try container.decode(String.self, forKey: .nike)
airjordan = try container.decode(String.self, forKey: .airjordan)
vans = try container.decode(String.self, forKey: .vans)
super.init()
}
required init()
{
super.init()
}
override static func primaryKey() -> String?
{
return UUID().uuidString
}
required init(value: Any, schema: RLMSchema)
{
super.init(value: value, schema: schema)
}
required init(realm: RLMRealm, schema: RLMObjectSchema)
{
super.init(realm: realm, schema: schema)
}
}
@objcMembers class SneakerInfoTemp: Object, Decodable {
dynamic var brand: String?
dynamic var category: String?
dynamic var colorway: String?
dynamic var descriptionTemp: String?
dynamic var designer: String?
dynamic var imagesrc: String?
dynamic var maincolor: String?
dynamic var name: String?
dynamic var nickname: String?
dynamic var price: String?
dynamic var productlink: String?
dynamic var productlinkhref: String?
dynamic var releasedate: String?
dynamic var silhouette: String?
dynamic var technology: String?
dynamic var webscraperorder: String?
dynamic var webscraperstarturl: String?
enum CodingKeys: String, CodingKey {
case brand, category, colorway, designer, imagesrc, maincolor, name, nickname, price, productlink, productlinkhref, releasedate, silhouette, technology,webscraperorder,webscraperstarturl
case descriptionTemp = "description"
}
required init(from decoder: Decoder) throws
{
let container = try decoder.container(keyedBy: CodingKeys.self)
brand = try container.decode(String.self, forKey: .brand)
category = try container.decode(String.self, forKey: .category)
colorway = try container.decode(String.self, forKey: .colorway)
descriptionTemp = try container.decode(String.self, forKey: .descriptionTemp)
designer = try container.decode(String.self, forKey: .designer)
imagesrc = try container.decode(String.self, forKey: .imagesrc)
maincolor = try container.decode(String.self, forKey: .maincolor)
name = try container.decode(String.self, forKey: .name)
nickname = try container.decode(String.self, forKey: .nickname)
price = try container.decode(String.self, forKey: .price)
productlink = try container.decode(String.self, forKey: .productlink)
productlinkhref = try container.decode(String.self, forKey: .productlinkhref)
releasedate = try container.decode(String.self, forKey: .releasedate)
silhouette = try container.decode(String.self, forKey: .silhouette)
technology = try container.decode(String.self, forKey: .technology)
webscraperorder = try container.decode(String.self, forKey: .webscraperorder)
webscraperstarturl = try container.decode(String.self, forKey: .webscraperstarturl)
super.init()
}
required init()
{
super.init()
}
required init(value: Any, schema: RLMSchema)
{
super.init(value: value, schema: schema)
}
required init(realm: RLMRealm, schema: RLMObjectSchema)
{
super.init(realm: realm, schema: schema)
}
}
Main error is
Property 'self.sneaker' not initialized at super.init call
and
Property 'self.brands' not initialized at super.init call