尝试将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子类化并提供" new"初始化程序,即使在其他地方需要相当多的代码更改。但这导致"无法分配给财产:'地标'是一个只有获得的财产"。两个'地标'和' 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 :(得分:0)
我已经弄清楚了。
在" func编码(使用编码器:NSCoder)"中分解mapItem。并在" init?(编码器解码器:NSCoder)"
中重新构建它我确实利用了带有地标的MKMapItem初始化程序。
MKMapItem(placemark: placemark!)
这是我的工人阶级:
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")
}
}
答案 1 :(得分:0)
MKMapItem使用NSSecureCoding,因此您可以使类符合NSSecureCoding,如以下示例所示,而不必重新创建MKMapItem:
class BGFPlaceItem: NSObject, NSSecureCoding {
static var supportsSecureCoding: Bool {
return true
}
func encode(with aCoder: NSCoder) {
aCoder.encode(loadedAs.rawValue, forKey: "loadedAs")
aCoder.encode(favorited, forKey: "favorited")
aCoder.encode(mapItem, forKey: "mapItem")
}
required convenience init?(coder aDecoder: NSCoder) {
let la = aDecoder.decodeObject(forKey: "loadedAs") as! String
let fav = aDecoder.decodeBool(forKey: "favorited")
let mi = aDecoder.decodeObject(forKey: "mapItem") as! MKMapItem
let la2 = LoadedType(rawValue: la)!
self.init(loadedAs: la2, isFavorited: fav, with: mi)
}
enum LoadedType: String {
case generalPlace
case favorite
case searchResult
var color: UIColor {
switch self {
case .generalPlace: return UIColor(named: "generalPlaceColor")!
case .favorite: return UIColor(named: "favoriteColor")!
case .searchResult: return UIColor.yellow
}
}
}
var loadedAs: LoadedType
var favorited: Bool
var mapItem: MKMapItem
init(loadedAs: LoadedType, isFavorited favorited: Bool, with mi: MKMapItem) {
self.loadedAs = loadedAs
self.favorited = favorited
self.mapItem = mi
super.init()
}
}
答案 2 :(得分:0)
您始终可以通过扩展使其符合要求
extension MKMapItem: NSCoding {
required init?(coder decoder: NSCoder) {
// codes
}
func encode(with coder: NSCoder) {
// more codes
}
}