使用NSKeyedArchiver代替NSUserDefault出现问题

时间:2018-07-10 16:31:59

标签: nsdata nskeyedarchiver nskeyedunarchiver

我正在编写一个代码,其中每次位置更新时都需要保存和使用默认坐标。我使用了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”。我不知道该怎么办。如果您需要控制台输出或更多代码来获取更多上下文,请添加它。任何可以帮助我解决此问题的有用方向或建议都将受到欢迎。

0 个答案:

没有答案