首页 文章

使用Realm保存数据或自定义类的数组

提问于
浏览
1

我有一个包含大量信息的自定义类 . 它是一个位置跟踪应用程序,所以我稍后需要位置(基本上只有x,y,z,但我为了方便而使用CLLocations) . 现在我有一个自定义类,包含有关每个跟踪的所有信息,如记录/保存文件) . 我使用Realm来保存它,Realm用我的Doubles和Strings做得很好,但是我对数据数组有困难 .

我能找到的最方便的解决方案是将数据转换为NSData . 在Google的帮助下,我找到了两种编码和解码方法 . 但我没有这方面的经验,所以我不确定它是否有效 . 而我认为它不起作用 .

我可以很好地加载双打和字符串,但我的NSData似乎是空的 . 我试图将我的类编码为NSData并将其保存为Realm,但这似乎不起作用,因此我的理论是编码/解码功能无法正常工作 .

TL; DR我有我想用Realm保存的自定义类(数据记录) . 我怎么来这个最好的?

我的课:

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

Realm类与我的记录几乎相同,因此更容易对记录进行编码并将其保存到Realm . 但这里是:

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
}

2 回答

  • 0

    Realm仅支持基本数据类型,因此您可以将 CLLocation 中的数据转换为Realm可以存储的内容 .

    在这种情况下,不是尝试将 CLLocation 序列化为 NSData ,而是只需要创建另一个包含与 CLLocation 相同数据的Realm Object 子类,并且可以动态创建该类型的对象 .

    此外,虽然它有一些限制,但Realm只能在其 List 属性中存储其他Realm 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>()
    }
    
  • 3

    如果您的模型类确认了NSCoding协议,那么您可以将它放在Realm中 .

    示例:Route是我的模型结构 .

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

    RouteRealm包装为Route可以将对象保存到Realm

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

    存储:

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

相关问题