ios - 保存自定义 Objective-c 对象层次结构以实现持久性的最佳方法

标签 ios objective-c serialization

我正在编写一个应用程序,允许用户为他们可能选择到不同位置的多条路线计时,然后拥有他们可以查看的已保存数据的存档。我遇到的问题是保存数据以供持久使用。我已经阅读了 NSCoding 协议(protocol),但它似乎不适合我的对象需求,因为我的对象中存在不兼容的属性,例如 CLCoordinateLocation2D(我知道这个我可以分解成更多的组件,例如纬度和经度,但我是认为必须有更好的方法)但还有其他方法。我来自 Java,在那里我需要做的就是实现可序列化接口(interface),我很高兴,但我是 Objective-C 的新手,不确定解决问题的最佳方法。

这是我需要序列化的对象结构。

@interface BestRouteBrain : NSObject < CLLocationManagerDelegate, NSCoding > {
    NSDictionary *segments;
    BestRouteTimer *timer;
    BestRouteSegment *currentSegment;
    //Manages attributes that communicate with GPS
    CLLocationManager *locationManager;
    Firebase *firebase;
   //NSDictionary *routesByTimeOfDay;
   //NSDictionary *routesByAverage;
}

@property ( strong ) CLLocationManager *locationManager;
@property BestRouteSegment *currentSegment;
@property BestRouteTimer *timer;
@property NSDictionary *segments;
@property Firebase *firebase;

基本上,我需要序列化的是 NSDictionary *segments。这是一个片段的样子

@interface BestRouteSegment :NSObject <NSCoding>{
    // Name of segment
    NSString *segmentName;
    // String reprsenting starting location for segment
    NSString *startingLocation;
    // String representing ending location for segment
    NSString *endingLocation;
    //Key is name of route and value is a route object;
    NSDictionary *routesForSegment;
    CLLocationCoordinate2D startCoord;
    CLLocationCoordinate2D endCoord;
}

@property CLLocationCoordinate2D startCoord;
@property CLLocationCoordinate2D endCoord;
@property NSString *startingLocation;
@property NSString *endingLocation;
@property NSString *segmentName;
@property NSDictionary *routesForSegment;

此对象中的所有属性也需要序列化,包括 NSDictionary *routesForSegment。这是路线的样子,

@interface Route : NSObject {
    // Name of route given by user
    NSString *routeName;
    // The total average time for all trips using this route
    double  avgRouteTime;
    // Array of trips which used this route
    NSArray *allTripsFromRoute;
}

@property NSString *routeName;
@property double avgRouteTime;
@property NSArray *allTripsFromRoute;

所有这些属性也需要序列化。最后,这是一次旅行的样子。

@interface BestRouteTrip : NSObject {
    // Time elapsed for current trip
    double tripTime;
    // String representing time of day - Departure time is
    NSString *timeOfDay;
    NSDate *morningBeforeTrafic;// from 12:00am to 6:30am
    NSDate *morningTrafic; // from 6:30am to 9:30am
    NSDate *morningAfterTrafic; // from 9:30am to 12:00pm
    NSDate *afternoon;    // from 12:00pm to 3:30pm
    NSDate *eveningTrafic; // from 3:30pm to 6:30pm
    NSDate *eveningAfterTrafic; // from 6:30pm to 12:00p
}

@property double tripTime;
@property NSString *timeOfDay;
@property NSDate *morningBeforeTrafic;// from 12:00am to 6:30am
@property NSDate *morningTrafic; // from 6:30am to 9:30am
@property NSDate *morningAfterTrafic; // from 9:30am to 12:00pm
@property NSDate *afternoon;    // from 12:00pm to 3:30pm
@property NSDate *eveningTrafic; // from 3:30pm to 6:30pm
@property NSDate *eveningAfterTrafic; // from 6:30pm to 12:00p

这里我需要序列化的唯一两个值是 double tripTimeNSString *timeOfDay

总结:大脑有一个需要序列化的片段字典。该段具有要序列化的属性,包括路由字典(另一个自定义对象)。路线有其要序列化的属性,包括一组旅行。最后,trips 有两个需要序列化的值。

在此先感谢您的帮助。

最佳答案

好的,所以我通过在 BestRouteSegment 中实现 NSCoding 协议(protocol)解决了这个问题,该协议(protocol)无误地编码了我的段。以下是遵守上述协议(protocol)的方法。

- (void)encodeWithCoder:(NSCoder *)encoder {
    NSLog(@"Encode in segment was called");
    [ encoder encodeDouble:self.startCoord.latitude
                    forKey:@"startCoord.latitude" ];
    [ encoder encodeDouble:self.startCoord.longitude
                    forKey:@"startCoord.longitude" ];
    [ encoder encodeDouble:self.endCoord.latitude
                    forKey:@"endCoord.latitude" ];
    [ encoder encodeDouble:self.endCoord.longitude 
                    forKey:@"endCoord.longitude" ];
    [ encoder encodeObject:self.segmentName
                    forKey:@"segmentName" ];
    [ encoder encodeObject:self.startingLocation
                    forKey:@"startingLocation" ];
    [ encoder encodeObject:self.endingLocation
                    forKey:@"endingLocation" ];
    [ encoder encodeObject:self.routesForSegment
                    forKey:@"routesForSegment" ];
}

- (id)initWithCoder:(NSCoder *)adecoder {
    NSLog(@"Init with coder was called in segment");
    if ( self = [ super init ] ) {
        self.startCoord =
        CLLocationCoordinate2DMake(
                                   [ adecoder decodeDoubleForKey:@"startCoord.lattitude" ],
                                   [ adecoder decodeDoubleForKey:@"startCoord.longitude" ]
                                   );
        self.endCoord =
        CLLocationCoordinate2DMake(
                                   [ adecoder decodeDoubleForKey:@"endCoord.lattitude" ],
                                   [ adecoder decodeDoubleForKey:@"endCoord.longitude" ]
                                   );
        self.segmentName =
        [ adecoder decodeObjectForKey:@"segmentName" ];
        self.startingLocation =
        [ adecoder decodeObjectForKey:@"startingLocation" ];
        self.endingLocation =
        [ adecoder decodeObjectForKey:@"endingLocation" ];
        self.routesForSegment =
        [ adecoder decodeObjectForKey:@"routesForSegment" ];

    }
    return self;
}

关于ios - 保存自定义 Objective-c 对象层次结构以实现持久性的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19647812/

相关文章:

java - 如何序列化包含 BufferedImages 的对象

iOS 应用程序因启动时崩溃而被拒绝(无法重现)

自调整单元格的 ios 动态约束属性

objective-c - 如何在 iOS 6 中使用 attributedText 添加可点击链接到 UILabel

ios - 如何创建一个打开/关闭 collectionView 部分

python - numpy.array2string 未检测 native 类型

Java 未经检查或不安全操作消息

ios - iOS-AFNetworking GET方法中不兼容的 block 指针类型

ios - 无法获取 Facebook 用户信息(生日、工作、教育程度)

ios - 将 UIView 显示为弧线