2016-09-12 6 views
1

多くの情報を保持するカスタムクラスがあります。それは場所を追跡するアプリケーションなので、私は後で場所が必要です(基本的にはx、y、zのみですが、便宜上CLLocationsを使用しています)。 今、レコード/保存ファイルのように、各追跡に関するすべての情報を保持するカスタムクラスがあります。私はこれを保存するためにレルムを使用し、レルムは私のダブルスとストリングでうまくいくが、データの配列に問題がある。Realmでデータまたはカスタムクラスの配列を保存

最も便利な解決策は、データをNSDataに変換することです。 Googleの助けを借りて、私はエンコードとデコードの2つの方法を見つけました。しかし、私はこれで経験がないので、私はそれが動作するかどうかはわかりません。そして、私はそれが動作するとは思わない。

DoublesとStringsを正しくロードできますが、NSDataは空のようです。私はクラスをNSDataにエンコードしてレルムで保存しようとしましたが、それはうまくいかないので、エンコード/デコード関数が正しく機能しないという理論です。

TL; DRレルムに保存したい私のカスタムクラス(データレコード)があります。どのように私はこの最高の周りに来るのですか?

私のクラス:

class DataRecord { 
    var startLocation : CLLocation = CLLocation.init() 
    var endLocation : CLLocation = CLLocation.init() 
    var duration : Double = 0.0 
    var distance: Double = 0.0 

    var avgSpeed : Double = 0.0 
    var topSpeed : Double = 0.0 

    var locations : [CLLocation] = [] 
    var altitudes : [Double] = [] 
    var angles : [Double] = [] 
    var speeds : [Double] = [] 
} 

マイNSDataのエンコード/デコード

func encode<T>(value: T) -> NSData { 
    var val = value 
    return withUnsafePointer(&val) { p in 
     NSData(bytes: p, length: sizeofValue(value)) 
    } 
} 

func decode<T>(data: NSData) -> T { 
    let pointer = UnsafeMutablePointer<T>.alloc(sizeof(T.Type)) 
    data.getBytes(pointer, length: sizeof(T)) 

    return pointer.move() 
} 

レルムクラスは、したがって、それは容易になるだろう理由は、単にレコードをエンコードするために、ほとんど私のレコードと同じ持っていますそれをレルムに保存します。しかし、ここにある:あなたがCLLocationからレルムを保存することができます何かにデータを「変換」する必要が正しいですので

class Record: Object { 
    dynamic var name = "" 
    dynamic var locations = NSData() 
    dynamic var altitudes = NSData() 
    dynamic var angles = NSData() 
    dynamic var speeds = NSData() 
    dynamic var distance = 0.0 
    dynamic var duration = 0.0 
    dynamic var topSpeed = 0.0 
    dynamic var avgSpeed = 0.0 
    dynamic var topAngle = 0.0 
    dynamic var avgAngle = 0.0 
} 

答えて

3

レルムは、基本的なデータ型をサポートしています。この場合

は、代わりにCLLocationNSDataにをシリアル化しようとする、それだけでCLLocationと同じデータを保持し、その場でその型のオブジェクトを作成することができ、別のレルムObjectサブクラスを作るために非常に簡単になります。

また、Realmは幾分限定されていますが、Listプロパティには、他のレルムObjectを格納することしかできません。したがって、この場合、他の値(例えば、高度など)を自分のRealm Objectサブクラスにラップする必要があります。

class Location: Object { 
    dynamic var latitude = 0.0 
    dynamic var longitude = 0.0 
    var clLocation: CLLocation { 
     return CLLocation(latitude: self.latitude, longitude: self.longitude) 
    } 

    init(clLocation: CLLocation) { 
     self.latitude = clLocation.latitude 
     self.longitude = clLocation.longitude 
    } 
} 

class Altitude: Object { 
    dynamic var altitudeValue = 0.0 
} 

class Angle: Object { 
    dynamic var angleValue = 0.0 
} 

class Speed: Object { 
    dynamic var speedValue = 0.0 
} 

class Record: Object { 
    dynamic var name = "" 

    dynamic var startLocation: Location? 
    dynamic var endLocation: Location? 

    dynamic var distance = 0.0 
    dynamic var duration = 0.0 
    dynamic var topSpeed = 0.0 
    dynamic var avgSpeed = 0.0 
    dynamic var topAngle = 0.0 
    dynamic var avgAngle = 0.0 

    let locations = List<Location>() 
    let altitudes = List<Altitude>() 
    let angles = List<Angle>() 
    let speed = List<Speed>() 
} 
+0

万歳:RouteRealmはルートのためにラップされて

struct Route { fileprivate (set) var locations: [CLLocation] init() { locations = [] } init(withLocations locations: [CLLocation]) { self.locations = locations } } 

は、ストレージ

class RouteRealm: Object { dynamic var locations: Data? = nil convenience init(route: Route) { self.init() self.locations = NSKeyedArchiver.archivedData(withRootObject: route.locations) } func route() -> Route { if let locations = locations, let clLocations = NSKeyedUnarchiver.unarchiveObject(with: locations) as? [CLLocation] { return Route(withLocations: clLocations) } return Route() } } 
にレルムにオブジェクトを保存することが可能になります!それは働いている! :) ありがとうございました。私は各オブジェクトから値を取得するためにいくつかの余分を追加する必要があるので、実際には非常に保存するのが便利ですが、それほど便利ではありません。私自身のために、toDataRecordをRecordオブジェクトに入れて、DataRecordクラスに変換して、アプリケーション全体で意図した通りに動作させるようにしました。これに関して最も大きな議論はCLLocationsの使用でしたが、基本的に他のリストはそのまま残すことができました。しかし、一貫性のために、私は物事をずっと簡単にするtoDataRecord関数を作った:) – dkcas11

+0

優秀!私はそれが働いていることを聞いてうれしい! :)ああ、十分なフェア!あなたが考えることもできることの1つは、 'NSData'ではなく' String'に変換することです。私は 'CGRect'値を保存するために自分のアプリケーションの一つでRealmを使ってやってしまいました。 – TiM

0

モデルクラスがNSCodingプロトコルを確認している場合は、これをどのようにしてレルムに配置できますか。

例: 経路は私のモデル構造です。

struct RealmStore: DataStore { 
    let realm = try! Realm() 

    func store(route: Route) { 
     let routeRealm = RouteRealm(route: route) 
     try! realm.write { 
      realm.add(routeRealm) 
     } 
    } 

    func routes() -> [Route] { 
     let routesRealm = realm.objects(RouteRealm.self) 
     let routes = routesRealm.map() { $0.route() } 
     return Array(routes) 
    } 
} 

protocol DataStore { 
    func store(route: Route) 
    func routes() -> [Route] 
} 
関連する問題