Как преобразовать MKMapItem в двоичные данные для хранения в Core Data?

Я хочу сохранить MKMapItem, который ранее был найден MKLocalSearch, в Core Data, чтобы я мог показать его пользователю при загрузке представления в будущем.

Что у меня есть, так это то, что я создал Entity в файле xcdatamodeld и создал атрибут binaryData с именем mapItem.

Я хочу закодировать найденный MKMapItem в двоичные данные и сохранить его в основных данных.

Позже я хочу декодировать его в MKMapItem.

Я заметил, что у MKMapItem есть метод кодирования, которому нужен объект NSCoder.

Я не очень хорошо знаком с NSCoding, поэтому любая помощь будет оценена по достоинству.

Я всегда могу сохранить строковые атрибуты из MKMapItem в основных данных, создав несколько атрибутов для объекта, но мне было интересно, есть ли простой способ.

Спасибо!


person Sarang Borude    schedule 05.03.2019    source источник
comment
Не было бы проще, если бы вы просто сохранили местоположение с помощью Core Data, чтобы вы могли восстановить соответствующий объект MKMapItem с помощью первого?   -  person El Tomato    schedule 06.03.2019


Ответы (1)


Я понял. Чтобы сохранить MapItem в Core Data, я использовал NSKeyedArchiver. Он кодирует MapItem в данные, а для декодирования вы можете использовать NSKeyedUnarchiver.

func saveMapItems(_ mapItems: [MKMapItem]) {
    do {
        let data = try NSKeyedArchiver.archivedData(withRootObject: mapItems, requiringSecureCoding: false)
        let request: NSFetchRequest<RecentSearchLocation> = RecentSearchLocation.fetchRequest()
        if
            let recentLocations = try? coreDataManager.persistentContainer.viewContext.fetch(request).first,
            let location = recentLocations {
            location.mapItems = data
        } else {
            let location = RecentSearchLocation(context: coreDataManager.persistentContainer.viewContext)
            location.mapItems = data
        }
    } catch {
        print("Can't encode data: \(error)")
    }
    do {
        try coreDataManager.persistentContainer.viewContext.save()
    } catch {
        print("Error saving context \(error)")
    }
}

Для декодирования я сделал это

func readMapItems() -> [MKMapItem] {
        let request: NSFetchRequest<RecentSearchLocation> = RecentSearchLocation.fetchRequest()
        guard
            let data = try? coreDataManager.persistentContainer.viewContext.fetch(request).first?.mapItems,
            let dataToUnarchive = data else {
                print("Cannot get mapItems from coreData data")
                return []
        }
        do {
            guard let recentSearchLocations = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(dataToUnarchive) as? [MKMapItem] else {
                return []
            }
            return recentSearchLocations
        } catch {
            print("Error unarchiving mapItems, \(error)")
            return []
        }
    }
person Sarang Borude    schedule 22.03.2019