2016-09-12 4 views
1

많은 정보가 들어있는 사용자 정의 클래스가 있습니다. 그것은 위치 추적 응용 프로그램입니다, 그래서 나중에 (기본적으로 x, y, z 만 위치가 필요하지만 편리하게 CLLocations를 사용합니다). 지금은 레코드/저장 파일과 같은 각 추적에 관한 모든 정보를 담고있는 사용자 정의 클래스가 있습니다. 이 영역을 저장하기 위해 영역을 사용하고 영역은 내 복식과 문자열로도 잘되지만 데이터 배열에 문제가 있습니다.Realm을 사용하여 데이터 또는 사용자 정의 클래스의 배열 저장

가장 편리한 해결책은 데이터를 NSData로 변환하는 것입니다. Google의 도움을 받아 인코딩 및 디코딩하는 두 가지 방법을 발견했습니다. 그러나 나는 이것에 대한 경험이 없기 때문에 그것이 작동하는지 잘 모르겠습니다. 그리고 나는 그것이 효과가 있다고 생각하지 않는다.

두 번 및 문자열을로드 할 수는 있지만 NSData는 비어있는 것 같습니다. 내 클래스를 NSData로 인코딩하고 Realm과 함께 저장하려고했지만 작동하지 않는 것 같습니다. 따라서 인코딩/디코딩 함수가 제대로 작동하지 않는다는 내 이론이 있습니다.

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 서브 클래스를 만들기 위해 훨씬 쉽게 될 것이며, 즉시 해당 유형의 개체를 만들 수 있습니다.

또한 다소 제한적이지만 영역은 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

만세! 작동 중! :) 고맙습니다. 실제로는 꽤 편리하지만 저장하기가 편리하지는 않습니다. 왜냐하면 각 객체에서 값을 가져 오기 위해 약간의 추가 작업을해야하기 때문입니다.필자 만의 목적으로 toDataRecord를 Record 객체에 넣어 DataRecord 클래스로 변환하여 내 응용 프로그램 전체에서 의도 한대로 작동하도록했습니다. 이것에 대한 가장 큰 논쟁은 CLLocations의 사용 이었지만, 기본적으로 다른 목록은 그대로 유지 될 수있었습니다. 하지만 일관성을 위해 모든 것을 훨씬 쉽게 해주는 toDataRecord 함수를 만들었습니다. – dkcas11

+0

Excellent! 나는 그것이 작동하고있어 기쁘다! :) 충분히 공정한 Ahh! 여러분이 생각할 수있는 한 가지는 NSData 대신에'String'으로 변환하는 것입니다. 나는 CGRect 값을 저장하기 위해 자신의 응용 프로그램 중 하나에서 Realm을 사용하여 작업을 마무리했습니다. – TiM

0

모델 클래스가 NSCoding 프로토콜을 확인한 경우이 방법을 영역에 넣을 수 있습니다.

예 : 경로가 내 모델 구조입니다.

struct Route { 
    fileprivate (set) var locations: [CLLocation] 

    init() { 
     locations = [] 
    } 

    init(withLocations locations: [CLLocation]) { 
     self.locations = locations 
    } 
} 

RouteRealm이 경로에 대한 포장되어 영역

에 객체를 저장할 수 있습니다
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] 
}