2017-03-13 2 views
0

Ich bin ein neuer iOS-Entwickler.Gibt es Möglichkeiten, MKPlacemark-Instanzen in Realm zu speichern?

Ich möchte MKPlacemark-Instanzen in Realm speichern, aber ich weiß nicht, wie ich es speichern soll. Um in Realm zu speichern, müssen alle Eigenschaften Primitive, NSString, NSDate, NSData, NSNumber, RLMArray, RLMLinkingObjects oder Unterklassen von RLMObject sein.

Also in diesem Fall, wie kann ich MKPlacemark in entsprechende Eigenschaften konvertieren?

Antwort

1

Da Realm-Objekte unterstützt nur primitive Typen und Verweise auf andere Realm Objekte, benötigen Sie einen Mechanismus zu schaffen, der die Komponenten von MKPlacemark zu Realm übersetzen kann und wieder zurück.

Wahrscheinlich wäre der sauberste Weg, um eine öffentliche Variable mkPlacemark (im Anschluss an den Swift 3 Namenskonventionen von Objective-C-Objekten als Eigenschaften wie cgImage :)), dass beim Einstellen oder bekommt, wird führt die Umwandlung intern genannt zu haben sein.

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 
    } 

} 

(Ich schrieb diesen Code von Hand, so dass es einige Optimierungen benötigen könnte, bevor es tatsächlich kompiliert werden kann. :))

+0

Vielen Dank TiM. Deine Herangehensweise ist großartig und ja, es braucht ein paar Feinabstimmungen. Also habe ich eine Antwort mit Arbeitscode hinzugefügt. –

+1

Ich habe diese Antwort überprüft, aber alle Antworten waren sehr hilfreich für mich :-) Danke allen! – chizcake

0

Sie können ein eigenes RLMObject mit MKPlacemark-Eigenschaften erstellen.

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]? 
} 

}

+1

Sie können die Eigenschaft 'CLLocationCoordinate2D' nicht direkt in Realm speichern. Sie müssen es in zwei "Doubles" (Längen- und Breitengrade) aufteilen. – joern

0

Diese Antwort die gezwickt Version von Tims Antwort. Die folgenden Eigenschaften unterliegen einer Änderung:

RLMObject kann keine MKPlacemark Eigenschaftstyp haben. So kann mkPlacemark set nicht haben. Es kann get & es fungiert als Instanzvariable, ohne eine gespeicherte Eigenschaft zu sein. Für iOS 9+ aktualisiert; Verwenden Sie das neue Kontakte-Framework. super.init() haben geändert 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) 
    } 
} 

Es wäre toll, wenn jemand dies hilft. Das Casting von AddressDictionary ist redundant. Sie können es direkt verwenden, aber es wirft eine Warnmeldung & Ich hasse Warnung. ;)

+0

Realm kann andere Eigenschaftstypen haben, solange sie als ignoriert markiert sind. In diesem Fall werden sie in Realm nicht beibehalten. Da die Eigenschaft in diesem Fall nicht als dynamisch gekennzeichnet war, ist sie für die Objective-C-Laufzeit nicht sichtbar (daher wird sie ignoriert). Auf diese Weise ist es möglich, zusätzliche Eigenschaften zu haben, die zu Realm-geschützten Daten gehören, aber nicht gespeichert werden. – TiM

Verwandte Themen