2016-11-05 5 views
0

Попытка сохранить MKMapItem как часть моего пользовательского класса.NSCoding для несовместимого объекта (MKMapItem)

import UIKit 
import MapKit 

class Place: NSObject, NSCoding { 

var mapItem : MKMapItem! 
var type : Category! 

init(mapItem: MKMapItem, type: Category) { 
    self.mapItem = mapItem 
    self.type = type 

} 

// MARK: NSCoding 
    required init?(coder decoder: NSCoder) { 

     mapItem = decoder.decodeObject(forKey: "mapItem") as! MKMapItem? 
     type = decoder.decodeObject(forKey: "type") as! Category? 
    } 

    func encode(with coder: NSCoder) { 

     coder.encode(mapItem, forKey: "mapItem") 
     coder.encode(type, forKey: "type") 
    } 

} 

Но это не будет работать, потому что MKMapItem не NSCoding-совместимый (компилятор не жалуется, хотя). Я действительно понимаю, как кодировать пользовательские классы, но не могу понять, как это сделать для объекта, уже определенного iOS.

Я знаю, что есть один ответ для Objective-C на этом, но очень понравится решение Swift. Благодарю.

PS Я попытался подклассировать MKMapItem и предоставить «новые» инициализаторы, даже если это потребует значительных изменений кода в другом месте. Но это приводит к «Невозможно присвоить свойство:« метка »- это свойство только для получения». И «метка», и «isCurrentLocation» доступны только для загрузки.

import UIKit 
import MapKit 

class NewMapItem: MKMapItem { 


    required init(placemark: MKPlacemark, isCurrentLocation:Bool, name: String,   phoneNumber: String, url: URL, timeZone: TimeZone) { 
    self.placemark = placemark //compiler complains "get-only" 
    self.isCurrentLocation = isCurrentLocation //compiler complains "get-only" 
    self.name = name 
    self.phoneNumber = phoneNumber 
    self.url = url 
    self.timeZone = timeZone 

} 

// MARK: NSCoding 

init?(coder decoder: NSCoder) { 

    placemark = (decoder.decodeObject(forKey: "placemark") as! MKPlacemark?)! //compiler complains "get-only" 
    isCurrentLocation = decoder.decodeBool(forKey: "isCurrentLocation") //compiler complains "get-only" 
    name = decoder.decodeObject(forKey: "name") as? String 
    phoneNumber = decoder.decodeObject(forKey: "phoneNumber") as? String 
    url = decoder.decodeObject(forKey: "url") as! URL? 
    timeZone = decoder.decodeObject(forKey: "timeZone") as! TimeZone? 
} 

func encode(with coder: NSCoder) { 

    coder.encode(placemark, forKey: "placemark") 
    coder.encode(isCurrentLocation, forKey: "isCurrentLocation") 
    coder.encode(name, forKey: "name") 
    coder.encode(phoneNumber, forKey: "phoneNumber") 
    coder.encode(url, forKey: "url") 
    coder.encode(timeZone, forKey: "timeZone") 
} 
} 

ответ

0

Я понял.

ломается mapItem в «Func закодировать (с кодером: NSCoder)» и соберем его обратно снова в «INIT (кодер декодере: NSCoder)?»

я воспользоваться инициализатором MKMapItem с метками ,

Вот мой рабочий класс:

import UIKit 
import MapKit 

class Place: NSObject, NSCoding { 

    var mapItem : MKMapItem! 
    var type : Category! 

    init(mapItem: MKMapItem, type: Category) { 
    self.mapItem = mapItem 
    self.type = type 
    } 

// MARK: NSCoding 
    required init?(coder decoder: NSCoder) { 

    //liberate the properties of mapItem and rebuild it 
    // let isCurrentLocation = decoder.decodeObject(forKey: "isCurrentLocation") as! Bool //don't need set already 
     let name = decoder.decodeObject(forKey: "name") as! String? 
     let phoneNumber = decoder.decodeObject(forKey: "phoneNumber") as! String? 
     let url = decoder.decodeObject(forKey: "url") as! URL? 
     let timeZone = decoder.decodeObject(forKey: "timeZone") as! TimeZone? 
     let placemark = decoder.decodeObject(forKey: "placemark") as! MKPlacemark? 

    self.mapItem = MKMapItem(placemark: placemark!) 
    self.mapItem.name = name 
    self.mapItem.url = url 
    self.mapItem.phoneNumber = phoneNumber 
    //self.mapItem.isCurrentLocation = isCurrentLocation //don't need this. Set already 
    self.mapItem.timeZone = timeZone 

    type = decoder.decodeObject(forKey: "type") as! Category? 

    } 

    func encode(with coder: NSCoder) { 
    let placemark = mapItem.placemark 
    let name = mapItem.name 
    let phoneNumber = mapItem.phoneNumber 
    let url = mapItem.url 
    let timeZone = mapItem.timeZone 

    coder.encode(name, forKey: "name") 
    coder.encode(phoneNumber,forKey: "phoneNumber") 
    coder.encode(url, forKey: "url") 
    coder.encode(timeZone, forKey: "timeZone") 
    coder.encode(type, forKey: "type") 
    coder.encode(placemark, forKey: "placemark") 

    } 

}