我正在编写一个代码,其中每次位置更新时都需要保存和使用默认坐标。我使用了2种默认值-一种在应用程序域下,另一种在寄存器域下(首次启动应用程序时的默认设置)。 现在,我想发生的事情是使用NSKeyedArchiver存储坐标数据,使用NSKeyedUnarchiver读取坐标数据。纬度和经度这两个值都应存储在一个键下。这是我的viewcontroller-
WhereamiViewController.h
@interface WhereamiViewController : UIViewController <CLLocationManagerDelegate,MKMapViewDelegate,UITextFieldDelegate>
{
CLLocationManager *locationManager;
NSArray *coordinateData;
NSUserDefaults *userDefault;
NSData *serializedData;
__weak IBOutlet MKMapView *worldView;
__weak IBOutlet UIActivityIndicatorView *activityIndicator;
__weak IBOutlet UITextField *locationTitleField;
__weak IBOutlet UISegmentedControl *mapTypeControl;
}
-(IBAction)buttonDidGetPressed:(id)sender;
-(BOOL)textFieldShouldReturn:(UITextField *)textField;
-(void)findLocation;
-(void)foundLocation:(CLLocation *)loc;
@end
WhereamiViewController.m
@interface WhereamiViewController ()
@end
NSString *const WhereamiMapTypePrefKey= @"WhereamiMapTypePrefKey";
NSString *const CenterCoordinatePrefKey= @"CenterCoordinatePrefKey";
@implementation WhereamiViewController
+(void)initialize{
NSLog(@"initializing custom factory settings"); //THE factory settings are not saved to disk.. These take effect at runtime..
//Setting the default as Hybrid view for map
NSNumber *hybridViewNumber= [NSNumber numberWithInt:1];
//Setting a default coordinate for location Mumbai, India..
NSNumber *latitude=[NSNumber numberWithDouble:19.11961470];
NSNumber *longitude= [NSNumber numberWithDouble:72.85616440];
NSArray *coordData=@[latitude, longitude];
NSDictionary *defaults= @{CenterCoordinatePrefKey: coordData, WhereamiMapTypePrefKey:hybridViewNumber};
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
}
-(IBAction)buttonDidGetPressed:(id)sender{
NSLog(@"%@",NSStringFromSelector(_cmd));
NSLog(@"%@",sender);
[[NSUserDefaults standardUserDefaults] setInteger:[sender selectedSegmentIndex] forKey:WhereamiMapTypePrefKey];
if([sender selectedSegmentIndex]==0){
[worldView setMapType:MKMapTypeStandard];
}
else if([sender selectedSegmentIndex]==1){
[worldView setMapType:MKMapTypeHybrid];
}
else if([sender selectedSegmentIndex]==2){
[worldView setMapType:MKMapTypeSatellite];
}
}
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
NSLog(@"%@", NSStringFromSelector(_cmd));
if (self=[super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
locationManager= [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager requestWhenInUseAuthorization];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
}
NSLog(@"test");
return self;
}
-(void) viewDidLoad{
NSLog(@"%@",NSStringFromSelector(_cmd));
[worldView setShowsUserLocation:YES]; //This calls mapView:didUpdateUserLocation
NSInteger mapTypeValue= [[NSUserDefaults standardUserDefaults] integerForKey:WhereamiMapTypePrefKey]; NSLog(@"mapTypeValue- %d",(int)mapTypeValue);
//Update the UI
[mapTypeControl setSelectedSegmentIndex:mapTypeValue];
//Update the map
[self buttonDidGetPressed:mapTypeControl];//resetting IBAction message..Returns 1 after first run. (2nd view- Hybrid view)
}
-(void)findLocation{
NSLog(@"%@",NSStringFromSelector(_cmd));
[locationManager startUpdatingLocation];//This calls locationManager:didUpdateLocations:
NSLog(@"location updated");
[activityIndicator startAnimating];
NSLog(@"hiding locationTitle field");
[locationTitleField setHidden:YES];
// NSLog(@"end of find loc");
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
NSLog(@"%@",NSStringFromSelector(_cmd));
[self findLocation];
[textField resignFirstResponder];
return YES;
}
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
NSLog(@"%@",NSStringFromSelector(_cmd));
userDefault= [NSUserDefaults standardUserDefaults];
if (![NSData dataWithContentsOfFile:[self dataObjectArchivePath]]) {
coordinateData= [userDefault objectForKey:CenterCoordinatePrefKey];
NSLog(@"user default center coordinate-- %@", coordinateData);
}
else{
coordinateData= [NSKeyedUnarchiver unarchiveObjectWithData:serializedData]; //This is supposed to return @[latitude, longitude]
NSLog(@"unarchived center coordinate-- %@", coordinateData);
}
CLLocationCoordinate2D defaultCenter= {[[coordinateData objectAtIndex:0] doubleValue], [[coordinateData objectAtIndex:1] doubleValue]};
MKCoordinateSpan span= MKCoordinateSpanMake(250, 250);
MKCoordinateRegion mapPortionToDisplay= MKCoordinateRegionMakeWithDistance(defaultCenter, span.latitudeDelta, span.longitudeDelta);
[worldView setRegion:mapPortionToDisplay animated:YES];
}
-(void)foundLocation:(CLLocation *)loc{
NSLog(@"%@",NSStringFromSelector(_cmd));
CLLocationCoordinate2D coord= [loc coordinate];
NSDateFormatter *formatter= [[NSDateFormatter alloc] init];
NSDate *currentDate= [[NSDate alloc] init];
[formatter setDefaultDate:currentDate];
BNRMapPoint *bmp= [[BNRMapPoint alloc] initWithCoordinate:coord title:[locationTitleField text] subTitle:[[formatter defaultDate] description]];
NSLog(@"current map point- %@",bmp);
[worldView addAnnotation:bmp];
//Setting user default in application domain..
NSNumber *latitude= [NSNumber numberWithFloat:coord.latitude];
NSNumber *longitude= [NSNumber numberWithFloat:coord.latitude];
coordinateData= @[latitude,longitude];
serializedData= [NSKeyedArchiver archivedDataWithRootObject:coordinateData];
[serializedData writeToFile:[self dataObjectArchivePath] atomically:YES];//archived to disk
NSLog(@"serialized data- %@", serializedData);
[userDefault setObject:coordinateData forKey:@"CenterCoordinateKey"];
//End of setting
MKCoordinateRegion region= MKCoordinateRegionMakeWithDistance(coord,250,250);
[worldView setRegion:region animated:YES];
//RESET the UI
[locationTitleField setText:@" "];
[activityIndicator stopAnimating];
[locationTitleField setHidden:NO];
[locationManager stopUpdatingLocation];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ //CLLocationManagerDelegate method implementation
NSLog(@"%@", NSStringFromSelector(_cmd));
CLLocation *centerLocation=(CLLocation *)[locations lastObject];
NSLog(@"current location–– %@", centerLocation);
NSTimeInterval t= [[(CLLocation *)[locations lastObject] timestamp] timeIntervalSinceNow];
if (t<-180) {
NSLog(@"%@ location made more than 3 min ago.",[locations lastObject]);
return; //No op
}
[self foundLocation:centerLocation];
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
NSLog(@"Could not find location: %@",error);//CLLocationManagerDelegate method implementation
}
-(NSString *)dataObjectArchivePath{
NSArray *documentDirectories= NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory= [documentDirectories objectAtIndex:0];
NSString *finalPath= [documentDirectory stringByAppendingPathComponent:@"coordinate.archive"];
NSLog(@"Data archiving path- %@", finalPath);
return finalPath;
}
@end
当我使用NSKeyedUnarchiver取消归档序列化数据的内容时,[NSKeyedUnarchiver unarchiveObjectWithData:serializedData]消息返回nil。因此,coordinateData更新为“ nil”。我不知道该怎么办。如果您需要控制台输出或更多代码来获取更多上下文,请添加它。任何可以帮助我解决此问题的有用方向或建议都将受到欢迎。