Search code examples
iosuiimageviewnsuserdefaultsunrecognized-selector

save image in nsuserdeafult from image picker and get other view controller


I save image using NSUaerDefaults from image picker using this code:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    UIImage *image=[info objectForKey:UIImagePickerControllerOriginalImage];
    NSData *imagedata=[NSData dataWithData:UIImagePNGRepresentation(image)];
    NSUserDefaults *default_bg=[NSUserDefaults standardUserDefaults];
    [default_bg setObject:imagedata forKey:@"image"];
    [default_bg synchronize];
    [self dismissViewControllerAnimated:YES completion:nil];
}

and getting in other view controller using this code:

NSUserDefaults *defaults_bgvw = [NSUserDefaults standardUserDefaults];
[defaults_bgvw synchronize];

UIImageView *bgImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[defaults_bgvw objectForKey:@"image"]]];

//bgImageView.contentMode=UIViewContentModeScaleAspectFit;
bgImageView.frame = self.view.bounds;
[self.view addSubview:bgImageView];
[self.view sendSubviewToBack:bgImageView];

When I run this code getting error like

"Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFData hasPrefix:]: unrecognized selector sent to instance 0x147c8590'"


Solution

    1. Never user NSUserDefaults to store images or other large amounts of data. You should simply store the file on the file system.

    2. That aside, your code to create an image from the stored data is flawed. You want this instead:

      NSData *imageData = [defaults_bgvw objectForKey:@"image"];
      UIImage *bgImage = [UIImage imageWithData:imageData];
      UIImageView *bgImageView = [[UIImageView alloc] initWithImage:bgImage];
      

    Note how the code is split up. This is easier to read and much easier to debug.

    But again, do not store images in NSUserDefaults.

    Unrelated but the following line:

    NSData *imagedata=[NSData dataWithData:UIImagePNGRepresentation(image)];
    

    can simply be:

    NSDate *imagedata = UIImagePNGRepresentation(image);
    

    No need to create the extra NSDate instance.

    And don't needlessly call synchronize. The following:

    NSUserDefaults *defaults_bgvw = [NSUserDefaults standardUserDefaults];
    [defaults_bgvw synchronize];
    

    should simply be:

    NSUserDefaults *defaults_bgvw = [NSUserDefaults standardUserDefaults];
    

    A call to synchronize is rarely needed at all and it definitely is never needed just to read values.