Как сохранить JSON декодируемые значения в Coredata, используя Swift - PullRequest
2 голосов
/ 07 января 2020

Я пытаюсь загрузить JSON Данные в CoreData. Здесь я использовал JSON structure для декодирования, и после этого я пытаюсь извлечь данные decodable в CoreData. Я не знаю, как использовать декодируемые с iterate данные и извлечение в coredata. Ниже код я пробовал, но не получил должного результата. Пожалуйста, помогите мне решить эту проблему.

Мой JSON

{
    "status": true,
    "data": [
        {
            "id": "20",
            "name": "ar1"
        },
        {
            "id": "21",
            "name": "ar2"
        },
        {
            "id": "22",
            "name": "ar3"
        }
    ]
}

Моя структура для JSON

struct userList: Codable {
    let status: Bool
    let data: [userData]
}

struct userData: Codable {
    let id, name: String
}

My Coredata Entity

var users = [User]() // User is my entity name

JSON Кодируется и пытается загрузить в CoreData

do {
       let result = try JSONDecoder().decode(userList.self, from:data) // here I am dong mistakes.
       let status = result.status
       if status == true {
           let newPerson = User(context: self.context)
           newPerson.id = "" // Cant able to get values
           newPerson.name = ""
           self.users.append(newPerson)

            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                self.tableView.reloadData()
             }
            } else {
               print(error)
             }

    } catch {
         print(error)
}

1 Ответ

1 голос
/ 08 января 2020

Чтобы иметь возможность декодировать JSON непосредственно в классы базовых данных, вы должны принять Decodable

  • Реализовать два расширения, чтобы иметь возможность передавать контекст управляемого объекта через JSONDecoder

    extension CodingUserInfoKey {
        static let context = CodingUserInfoKey(rawValue: "context")!
    }
    
    extension JSONDecoder {
        convenience init(context: NSManagedObjectContext) {
            self.init()
            self.userInfo[.context] = context
        }
    }
    
  • В User принять Decodable и добавить CodingKeys и требуемый init(from метод

    public class User: NSManagedObject, Decodable {
    
        private enum CodingKeys: String, CodingKey { case name, id }
    
        public required convenience init(from decoder: Decoder) throws {
            guard let context = decoder.userInfo[.context] as? NSManagedObjectContext else { fatalError("Error: with managed object context!") }
            let entity = NSEntityDescription.entity(forEntityName: "User", in: context)!
            self.init(entity: entity, insertInto: context)
            let values = try decoder.container(keyedBy: CodingKeys.self)
            name = try values.decode(String.self, forKey: .name)
            id = try values.decode(String.self, forKey: .id)
        }
    ...
    
  • Теперь вам нужна только одна зонтичная структура для объекта root. Еще раз, пожалуйста, имя структуры всегда начинаются с заглавной буквы

    struct Root: Decodable {
        let status: Bool
        let data: [User]
    }
    
  • Для декодирования JSON используйте пользовательский инициализатор, экземпляры User автоматически вставляются в базу данных

    do {
        let decoder = JSONDecoder(context: context) // context is the NSManagedObjectContext instance 
        let result = try decoder.decode(Root.self, from: data)
        if result.status {
           print("success")
           try context.save()
        }  
    catch { print(error)
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...