Класс Codable не соответствует протоколу Decodable

Почему я получаю "Type" Bookmark? не соответствует сообщению об ошибке "Decodable"?

class Bookmark: Codable {
   weak var publication: Publication?
   var indexPath: [Int]
   var locationInText = 0

   enum CodingKeys: String, CodingKey {
      case indexPath
      case locationInText
   }

   init(publication: Publication?, indexPath: [Int]) {
      self.publication = publication
      self.indexPath = indexPath
   }
}

Я не хочу сохранять публикацию var, поскольку публикация принадлежит Закладу, но закладка должна знать, к какой публикации она принадлежит. Инициализация декодирования публикации установит ссылку на закладку для себя.

Ответ 1

Почему я получаю "Type" Bookmark? не соответствует протоколу "Decodable" "сообщение об ошибке

Это либо потому, что Publication не Decodable (вы не показывали, что это такое, поэтому это трудно сказать), либо из-за обозначения weak на publication.

В любом случае, это легко исправить: вам просто нужно реализовать init(from:) для завершения реализации Decodable; компилятор просто говорит вам, что эта реализация не может быть синтезирована.

Ответ 2

Компилятор не может синтезировать требуемый метод init(from:) из-за ссылки weak, поэтому вам нужно написать его самостоятельно.

class Bookmark: Codable {
    weak var publication: Publication?
    var indexPath: [Int]
    var locationInText = 0

    private enum CodingKeys: String, CodingKey {
        case indexPath
        case locationInText
    }

    init(publication: Publication?, indexPath: [Int]) {
        self.publication = publication
        self.indexPath = indexPath
    }

    required init(from decoder:Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        indexPath = try values.decode([Int].self, forKey: .indexPath)
        locationInText = try values.decode(Int.self, forKey: .locationInText)
    }
}

Ответ 3

Оглядываясь назад, я получил похожую ошибку при попытке установить Codable для моего класса, который состоял из переменных типа NSNumber. Смотрите изображение ниже:

enter image description here

Изменение NSNumber на примитивный тип данных Int решило проблему. Увидеть ниже:

enter image description here

Я предполагаю, что это может быть правдой для других типов данных, которые требуют связывания со стандартными типами значений Swift, такими как NSString, NSArray и т.д.

Ответ 4

Еще одна причина, по которой вы можете получить это сообщение, заключается в том, что ваше перечисление CodingKeys не является исчерпывающим. Если у вас есть три свойства в типе данных, то у вашего перечисления CodingKeys также должно быть три свойства/имени.

Ответ 5

Короче говоря, при реализации Codable все свойства, которые не являются примитивным типом данных (означают тип класса или, возможно, это может быть классjective-c), должны быть Codable.

   weak var publication: Publication?

в этом случае публикация относится к классу типа, поэтому публикация должна реализовывать Codable

Ответ 6

У меня была похожая проблема, с которой я наткнулся на это исправление. Поскольку я новичок в Swift, я не уверен, почему это работает! Если кто-нибудь знает, я был бы признателен за знание.

Я изменил это:

let id, type: Int

к этому:

let id: Int
let type: Int