из JSON в Realm
салют, цель: заполнить БД реалма данными из джэйсона; в джэйсоне 20 объектов (массивы) в каждом по 6 элементов; при заполнении БД икскод дает ошибку Thread 1: "Invalid array input: more values (20) than properties (6)." Как сделать чтобы в реалме создалось 20 записей по 6 элементов?
//структура ДЖСОН
struct Person: Codable{
let results: [Result]
}
struct Result: Codable{
let personID: Int
let personName: String
let personStatus: String
let personSpecies: String
let location: Location
let personImageURL: String
enum CodingKeys: String, CodingKey{
case personID = "id"
case personName = "name"
case personStatus = "status"
case personSpecies = "species"
case location
case personImageURL = "image"
}
}
struct Location: Codable {
let personLocation: String
enum CodingKeys: String, CodingKey{
case personLocation = "name"
}
}
//класс РЕАЛМ
class RMRealmClass: Object{
@objc dynamic var personIDRealm = Int()
@objc dynamic var personNameRealm = String()
@objc dynamic var personStatusRealm = String()
@objc dynamic var personSpeciesRealm = String()
@objc dynamic var personImageURLRealm = String()
@objc dynamic var personLocationRealm = String()
override static func primaryKey() -> String? {
return "personIDRealm"
}
}
class CollectionViewController_d: UICollectionViewController {
@IBOutlet var RMCollection: UICollectionView!
let realm = try! Realm()
var persons2: Results<RMRealmClass>{
get{return realm.objects(RMRealmClass.self)}
}
override func viewDidLoad() {
super.viewDidLoad()
loadData()
}
//метод ДЖСОН + РЕАЛМ
func loadData(){
AF.request("https://rickandmortyapi.com/api/character").responseJSON { response in
guard let data = response.data else {return}
DispatchQueue.main.async{
do {
let persons = try JSONDecoder().decode(Person.self, from: data)
try! self.realm.write{
self.realm.create(RMRealmClass.self, value: persons.results)
}
}
catch let error {print (error)}
}
}
}
Ответы (1 шт):
Автор решения: D To
→ Ссылка
import UIKit
import Alamofire
import AlamofireImage
import RealmSwift
//структура json
struct Person: Codable{
let results: [Result]
}
struct Result: Codable{
let personID: Int
let personName: String
let personStatus: String
let personSpecies: String
let location: Location
let personImageURL: String
enum CodingKeys: String, CodingKey{
case personID = "id"
case personName = "name"
case personStatus = "status"
case personSpecies = "species"
case location
case personImageURL = "image"
}
}
struct Location: Codable {
let personLocation: String
enum CodingKeys: String, CodingKey{
case personLocation = "name"
}
}
// class Realm
class RMRealmClass: Object{
@objc dynamic var personIDRealm = Int()
@objc dynamic var personNameRealm = String()
@objc dynamic var personStatusRealm = String()
@objc dynamic var personSpeciesRealm = String()
@objc dynamic var personImageURLRealm = String()
@objc dynamic var personLocationRealm = String()
override static func primaryKey() -> String? {
return "personIDRealm"
}
}
class CollectionViewController_d: UICollectionViewController {
@IBOutlet var RMCollection: UICollectionView!
//создание экземпляра класса Realm
let realm = try! Realm()
//получение данных хранящихся в Realm для первичного заполнения таблицы
var persons2: Results<RMRealmClass>{
get{return realm.objects(RMRealmClass.self)}
}
override func viewDidLoad() {
super.viewDidLoad()
//реализация метода получения json и парсинга его в Realm
loadData ()
RMCollection.reloadData()
}
//метод получения json и парсинга его в Realm
func loadData(){
AF.request("https://rickandmortyapi.com/api/character").responseJSON { response in
guard let data = response.data else {return}
DispatchQueue.main.async{
do {
let persons = try JSONDecoder().decode(Person.self, from: data)
for result in persons.results{
try! self.realm.write{
let rmRealm = RMRealmClass()
rmRealm.personIDRealm = result.personID
rmRealm.personNameRealm = result.personName
rmRealm.personStatusRealm = result.personStatus
rmRealm.personSpeciesRealm = result.personSpecies
rmRealm.personLocationRealm = result.location.personLocation
rmRealm.personImageURLRealm = result.personImageURL
self.realm.add(rmRealm, update: .modified)
}
}
}
catch let error {print (error)}
}
}
}
// получаем количество ячеек коллекции
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return persons2.count
}
//заполнение коллекции
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell_d
let person = persons2[indexPath.item]
cell.name.text = person.personNameRealm
cell.status.text = person.personStatusRealm
cell.species.text = person.personSpeciesRealm
cell.location.text = person.personLocationRealm
let url = URL(string: person.personImageURLRealm) ?? URL(string: "здесь размещаем ссылку на дефолтное изображение")!
cell.image.af.setImage(withURL: url)
cell.logo.image = UIImage(systemName: "circle.fill")
switch person.personStatusRealm{
case String("Alive"): cell.logo.tintColor = .green
case String("unknown"): cell.logo.tintColor = .orange
default: cell.logo.tintColor = .red
}
return cell
}
}