Swift: Почему JSONDecoder (Codable / Decodable) не вызывает метод init () структуры? - PullRequest
1 голос
/ 13 июня 2019

Я чувствую, что чего-то не хватаетSwift 5.1.

У меня есть следующее struct, которое установлено в Decodable, поэтому я могу проанализировать внешний URL-адрес JSON:

struct ReleaseGroup: Decodable, Identifiable {
  let id: Int
  let externalServiceID: String
  let title: String
  let externalServiceImageURL: URL
  let type: String
  var image: UIImage?

  private enum CodingKeys: String, CodingKey {
    case id
    case externalServiceID = "external_service_id"
    case title
    case externalServiceImageURL = "external_service_image_url"
    case type
  }

  // do I have to do this just because UIImage is an optional?
  init(id: Int, externalServiceID: String, title: String, externalServiceImageURL: URL, type: String) {
    let url = URL(string: "https://someurl.com/some-image.jpeg")
    let data = try? Data(contentsOf: url!)
    self.image = UIImage(data: data!)
    self.id = id
    self.externalServiceID = externalServiceID
    self.title = title
    self.type = type
    self.externalServiceImageURL = externalServiceImageURL
  }
}

Я также определил этот фрагменткод в другом месте, который отвечает за фактическое создание экземпляров из вызова API:

init() {
  guard let url = URL(string: "http://127.0.0.1:8000/api/releases/") else { return }
  URLSession.shared.dataTask(with: url) { (data, _, _) in

    guard let data = data else { return }

    let releaseGroups = try! JSONDecoder().decode([ReleaseGroup].self, from: data)
    DispatchQueue.main.async {
        self.releaseGroups = releaseGroups
      }
    }
    }.resume()
}

Однако приведенное выше не вызывает метод init() для ReleaseGroup, который, как я думал, вызывается в любое времясоздается экземпляр ReleaseGroup.

Если я создаю их явно, это работает:

for releaseGroup in releaseGroups {
          let rg = ReleaseGroup.init(id: releaseGroup.id, externalServiceID: releaseGroup.externalServiceID, title: releaseGroup.title, externalServiceImageURL: releaseGroup.externalServiceImageURL, type: releaseGroup.type)
            self.releaseGroups.append(rg)
        }

1 Ответ

2 голосов
/ 13 июня 2019

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

См. эту статью от Apple для получения дополнительной информации

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...