NSCoding为不符合的对象(MKMapItem)

问题描述 投票:0回答:3

尝试将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的,但真的希望迅速解决。谢谢。

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")
}
}
swift mapkit nscoding
3个回答
0
投票

我已经想通了。

打破mapItem在“FUNC编码(含编码器:NSCoder)”和“的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")

   }

}

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()
    }
}

0
投票

你总是可以使之符合通过扩展它

extension MKMapItem: NSCoding {
   required init?(coder decoder: NSCoder) {
       // codes
   }

   func encode(with coder: NSCoder) {
       // more codes
   }
}
© www.soinside.com 2019 - 2024. All rights reserved.