有没有办法将MKPlacemark实例保存到Realm?

时间:2017-03-13 12:31:19

标签: ios swift realm

我是一名新的iOS开发人员。

我想将MKPlacemark实例保存到Realm,但我不知道如何保存它。要在Realm中保存,所有属性必须是基元,NSString,NSDate,NSData,NSNumber,RLMArray,RLMLinkingObjects或RLMObject的子类。

所以在这种情况下,我如何将MKPlacemark转换为适当的属性?

3 个答案:

答案 0 :(得分:1)

由于Realm对象仅支持基本类型和对其他Realm对象的引用,因此您需要创建一种机制,可以将MKPlacemark的组件转换为Realm并再返回。

可能最简单的方法是将一个名为mkPlacemark的公共变量(遵循Swift 3的Objective-C对象的命名约定作为cgImage :)等属性,在设置或获取时,将在内部执行转换。

class Placemark: Object {
   dynamic var latitude = 0.0
   dynamic var longitude = 0.0
   dynamic var street: String?
   dynamic var city: String?
   dynamic var zipCode: String?
   dynamic var country: String?

   public var mkPlacemark: MKPlacemark {
      set {
         latitude = newValue.coordinate.latitude
         longitude = newValue.coordinate.longitude
         street = newValue.addressDictionary[kABPersonAddressStreetKey]
         city = newValue.addressDictionary[kABPersonAddressCityKey]
         zipCode = newValue.addressDictionary[kABPersonAddressZipCodeKey]
         country = newValue.addressDictionary[kABPersonAddressCountryKey]
      }
      get {
         let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
         let addressDictionary = [kABPersonAddressStreetKey: street,
                                  kABPersonAddressCityKey: city,
                                  kABPersonAddressZipCodeKey: zipCode,
                                  kABPersonAddressCountryKey: country]
         return MKPlacemark(coordinate: coordinate, addressDictionary: addressDictionary)
      }
   }

   convinience init(placemark: MKPlacemark) {
      super.init()
      self.mkPlacemark = placemark
   }

}

(我手工编写了这段代码,因此在实际编译之前可能需要进行一些调整。:))

答案 1 :(得分:0)

您可以创建自己的RLMObject包含MKPlacemark属性。

class RLMPlacemark: Object {
var coordinate: CLLocationCoordinate2D?
var addressDictionary: [String: Any]?

required convenience init?(placemark: MKPlacemark) {
    self.init()
    self.coordinate = placemark.coordinate
    self.addressDictionary = placemark.addressDictionary as! [String : Any]?
}

}

答案 2 :(得分:0)

这个答案是TiM答案的调整版本。以下属性可能会发生变化:

RLMObject不能拥有MKPlacemark属性类型。所以mkPlacemark不能有set。它可以有get&它作为实例变量而不是存储属性。针对iOS 9+更新;使用新的Contacts框架。 super.init()必须更改为self.init()

import Foundation
import MapKit
import RealmSwift
import Contacts

class RLMPlacemark: Object {
    dynamic var latitude = 0.0
    dynamic var longitude = 0.0
    dynamic var street: String?
    dynamic var city: String?
    dynamic var state: String?
    dynamic var zipCode: String?
    dynamic var country: String?
    dynamic var countryCode: String?

    public var placemark: MKPlacemark {
        get {
            let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
            let addressDictionary = [CNPostalAddressStreetKey : street,
                                     CNPostalAddressCityKey : city,
                                     CNPostalAddressStateKey : state,
                                     CNPostalAddressPostalCodeKey : zipCode,
                                     CNPostalAddressCountryKey : country,
                                     CNPostalAddressISOCountryCodeKey : countryCode]
            let warningFreeAddressDictionary = (addressDictionary as Any) as? [String : Any]
            return MKPlacemark(coordinate: coordinate, addressDictionary: warningFreeAddressDictionary)
        }
    }

    convenience init(lat: Double, long: Double, street: String?, city: String?, state: String?, zipCode: String?, country: String?, countryCode:String?) {
        self.init()
        self.latitude = lat
        self.longitude = long
        self.street = street
        self.city = city
        self.state = state
        self.zipCode = zipCode
        self.country = country
        self.countryCode = countryCode
    }

    convenience init(placemark: MKPlacemark) {
        self.init(lat: placemark.coordinate.latitude,
                  long: placemark.coordinate.longitude,
                  street: placemark.addressDictionary?[CNPostalAddressStreetKey] as? String,
                  city: placemark.addressDictionary?[CNPostalAddressCityKey] as? String,
                  state: placemark.addressDictionary?[CNPostalAddressStateKey] as? String,
                  zipCode: placemark.addressDictionary?[CNPostalAddressPostalCodeKey] as? String,
                  country: placemark.addressDictionary?[CNPostalAddressCountryKey] as? String,
                  countryCode: placemark.addressDictionary?[CNPostalAddressISOCountryCodeKey] as? String)
    }
}

如果这可以帮助任何人,那就太好了。铸造AddressDictionary是多余的。你可以直接使用它,但它会抛出一个警告信息&我讨厌警告。 ;)