Управление сложными атрибутами в классе, который расширяет как NSManagedObject, так и Codable - PullRequest
0 голосов
/ 16 января 2019

У меня есть класс, который расширяет как NSManagedObject, так и Codable. С помощью этого класса я пытаюсь сохранить данные приложения на iphone локально, а также легко преобразовать их из JSON в объект класса Swift.

Проблема, с которой я сталкиваюсь в своем классе, заключается в том, что я получаю сообщение об ошибке при попытке написать функцию encode в моем классе:

`Reference to member 'arrayOfStrings' cannot be resolved without a contextual type`. 

Я потратил некоторое время, пытаясь это исправить, и мне не повезло выяснить, в чем же заключается проблема.

Проблемы связаны с двумя атрибутами типа [String] и [Int] соответственно.

Мой класс объявлен как таковой в файле с именем Foo+CoreDataClass.swift:

import Foundation
import CoreData

@objc(Foo)
public class Foo: NSManagedObject, Codable {
    enum CodingKeys: String, CodingKey {
        case id
        case name
        case arrayOfStrings
        case imageUrl
        case arrayOfInts
    }

    public required convenience init(from decoder: Decoder) throws {
        guard let context = decoder.userInfo[CodingUserInfoKey.context!] as? NSManagedObjectContext else { fatalError("Some fatal error") }
        guard let entity = NSEntityDescription.entity(forEntityName: "MyManagedObject", in: context) else { fatalError() }

        self.init(entity: entity, insertInto: context)
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.id = try container.decode(Int.self, forKey: CodingKeys.id)
        self.name = try container.decode(String.self, forKey: CodingKeys.name)
        self.arrayOfStrings = try container.decode([String].self, forKey: CodingKeys.arrayOfStrings) as NSObject
        self.imageUrl = try container.decode(String.self, forKey: CodingKeys.imageUrl)
        self.arrayOfInts = try container.decode([Int].self, forKey: CodingKeys.arrayOfInts) as NSObject
    }

    public 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)
        try container.encode(arrayOfStrings, forKey: .arrayOfStrings)
        try container.encode(imageUrl, forKey: .imageUrl)
        try container.encode(arrayOfInts, forKey: .arrayOfInts)
    }
}

extension CodingUserInfoKey {
    static let context = CodingUserInfoKey(rawValue: "context")
}  

Другой файл, который объявляет свойства, Foo+CoreDataProperties.swift определяется так:

extension Foo {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Foo> {
        return NSFetchRequest<Foo>(entityName: "Foo")
    }

    @NSManaged public var id: Int
    @NSManaged public var name: String?
    @NSManaged public var imageUrl: String?
    @NSManaged public var arrayOfStrings: NSObject?
    @NSManaged public var arrayOfInts: NSObject?
}

Эти файлы были созданы из XCode, когда я на вкладке Editor и выбрал Create NSManagedObject Subclass.

Я сделал Foo класс в Foo+CoreDataClass.swift наследуемом от Codable после того, как прочитал этот пост: Как использовать swift 4 Codable в Core Data? вместе с этими Apple Docs о том, как для кодирования пользовательских объектов .

Кому-нибудь удалось успешно использовать NSManagedObject и Codable с атрибутами, которые принимают тип массива? Цель, которую я пытаюсь достичь, - это иметь возможность конвертировать между JSON и объектом CoreData.

Edit: У меня также проблема с получением Date объектов для правильного кодирования, отображается то же сообщение об ошибке, что и выше.

...