Reputation: 796
I am writing an app that allows the user to time multiple routes they may choose to various locations and then have an archive of saved data they can view. The problem I am having is saving the data for persistent use. I have read up on NSCoding protocol but it doesn't seem to fit my objects needs due to incompatible properties that exits in my objects such as CLCoordinateLocation2D( I know this one I can break into more components such as latitude and longitude, but I am thinking there has to be a better way) but there are others. I am coming from java where all I need to do is implement the serializable interface and I am good to go but I am new to Objective-C and unsure of the best way to approach the problem.
Here are the object structures of what I need serialized.
@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;
Basically, all I need to serialize is the NSDictionary *segments
. Here is what a segment looks like
@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;
All properties in this object need to be serialized as well, including the NSDictionary *routesForSegment
. Here is what a route looks like,
@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;
All of these properties need to be serialized as well. Finally, here is what a trip looks like.
@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
The only two values I need to serialize here are, double tripTime
and NSString *timeOfDay
.
Summary: The brain has a dictionary of segments which needs to be serialized. The segment has it's properties to be serialized including a dictionary of routes(another custom object). Routes has its' properties to be serialized including an array of Trips. Finally, trips has its' two values that need to be serialized.
Thanks in advance for any assistance.
Upvotes: 1
Views: 299
Reputation: 796
Ok, so I solved this problem by implementing the NSCoding
protocol inside of BestRouteSegment
which encodes my segments without error. Here are the methods that abide by the mentioned 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;
}
Upvotes: 1