Kingfisher nil при разворачивании необязательного значения

У меня есть структура Medicine, содержащая image_origin URL-адрес изображения, которое я хочу загрузить и установить в ImageView. Для загрузки/кеширования я использую Kingfisher framework.

    let m = medicines[indexPath.row]

    cell.medicineImage.kf.setImage(with: URL(string: m.value(forKeyPath: "image_origin") as! String)!)
    cell.medicineName.text = m.value(forKeyPath: "i_name") as? String

В приведенном выше коде m является NSManagedObject из CoreData. Я пытаюсь получить URI изображения из CoreData и установить его в ImageView, но каждый раз в строке 2 я получаю следующее сообщение об ошибке: Unexpectedly found nil while unwrapping an Optional value

Я пытался изменить переменные и оптические типы, пытался жестко закодировать URI, но безуспешно.

Что я делаю не так?

P.S. Я использую Swift4


person Konstantin Chsherbakov    schedule 21.07.2018    source источник
comment
Почему value(forKeyPath? Ключевого пути нет. Чтобы получить значение атрибута CoreData, используйте value(forKey: или, что удобнее, запись через точку в подклассе NSManagedObject.   -  person vadian    schedule 22.07.2018
comment
@vadian хорошо, я думаю, есть несколько возможных обозначений. forKeyPath работает как шарм, чтобы получить значение (согласно официальному примеру CoreData).   -  person Konstantin Chsherbakov    schedule 22.07.2018
comment
Какая ссылка на официальный пример CoreData? Я сомневаюсь, что Apple предлагает forKeyPath только для одноуровневого ключа.   -  person vadian    schedule 22.07.2018
comment
@vadian, если вы перейдете к определению функции NSManagedObject.value, я увижу следующее объявление функции: open func value(forKeyPath keyPath: String) -> Any?. Как видите, одна и та же функция может принимать параметр в разных формах имени.   -  person Konstantin Chsherbakov    schedule 22.07.2018
comment
Это общий метод KVC, на который реагирует любой класс, использующий NSObjectProtocol. Прочтите документацию по NSManagedObject. Специальный метод для получения значения одноуровневого ключа — value(forKey. Ключевой путь — это что-то вроде "person.age". Конечно, value(forKeyPath работает, но дороже, потому что он пытается разделить и оценить каждый компонент пути.   -  person vadian    schedule 22.07.2018
comment
Ты прав. Извините за непонимание и спасибо за ссылку на документацию :D   -  person Konstantin Chsherbakov    schedule 22.07.2018


Ответы (2)


Просто разверните безопасно, чтобы исправить сбой, и проверьте свою базу данных, если вы не получаете urlString правильно,

if let urlString = m.value(forKeyPath: "image_origin") as? String {
   print(urlString)
   guard let url = URL(string: urlString) else { return }
   cell.medicineImage.kf.setImage(with: url)
}
person Kamran    schedule 22.07.2018
comment
Спасибо за ваш ответ! Я попробовал ваш код, но все еще получаю следующую ошибку Unexpectedly found nil while unwrapping an Optional value. Что еще может исправить эту ошибку? - person Konstantin Chsherbakov; 22.07.2018
comment
Тогда я думаю, что вы делаете очень основную ошибку. Вы подключили (или инициализировали программно) medicineImage в своем cell? - person Kamran; 22.07.2018
comment
Да, вы правы! Я не знаю почему, но все мои элементы отключились в раскадровке, поэтому они не были инициализированы. Я их переподключил и все заработало! Спасибо! - person Konstantin Chsherbakov; 22.07.2018
comment
Рад, что это помогло! - person Kamran; 22.07.2018

Может быть проблема с ключом image_origin, который может иметь значение в виде строки, а может и не иметь. Итак, просто нужно подтвердить значение и использовать его

let m = medicines[indexPath.row]

cell.medicineName.text = m.value(forKeyPath: "i_name") as? String

guard let urlPath = m.value(forKeyPath: "image_origin") as? String, let url = URL(string: urlPath) else { return }
cell.medicineImage.kf.setImage(with: url)
person bestiosdeveloper    schedule 22.07.2018