How to save and retrieve NSObject class using NSUserDafaults in iOS

后端 未结 2 875
名媛妹妹
名媛妹妹 2021-01-21 11:50

Hi I want to save and retrieve NSObject class using NSUserDefaults for that I wrote below code but I am getting exception like below

相关标签:
2条回答
  • 2021-01-21 12:31

    You can set object like this:

    NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:savingbean];
    [currentDefaults setObject:data forKey:@"DATA"];
    [currentDefaults synchronize];
    

    and for get object like this:

    NSData *data = [currentDefaults objectForKey:@"DATA"];
    SavingBean *token = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    

    For Custom class you have to edit this methods in you bean class:

    - (void)encodeWithCoder:(NSCoder *)encoder
    {
        [encoder encodeObject:self.userName==nil?@"":self.userName forKey: @"userName"];
        [encoder encodeObject:self.passWord==nil?@"":self.passWord forKey: @"passWord"];
    }
    
    -(id)initWithCoder:(NSCoder *)decoder
    {
        self = [super init];
        if(self)
        {
            self.userName = [decoder decodeObjectForKey: @"userName"];
            self.passWord = [decoder decodeObjectForKey: @"passWord"];
        }
        return self;
    }
    

    Here is most voted similar answer. You can also get good stuff from there.

    You can also use JSON Accelerator to create bean class. This is very simple and powerful tool.

    0 讨论(0)
  • 2021-01-21 12:31

    From good answer of Jayesh Thanki I tried sample from this question.I followed your coding.First I tried Save and Retrieve directly without encoder and decoder method.

    For Save

    NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:savingbean];
    [currentDefaults setObject:data forKey:@"DATA"];
    [currentDefaults synchronize];
    

    For Retrieve

    NSData *data = [currentDefaults objectForKey:@"DATA"];
    savingbean = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    

    Now it shows error

    [SavingBean encodeWithCoder:]: unrecognized selector sent to instance 0x7fc65940fc40

    Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SavingBean encodeWithCoder:]: unrecognized selector sent to instance 0x7fc65940fc40'

    Then I googled most of the answer say

    The NSCoding protocol declares the two methods that a class must implement so that instances of that class can be encoded and decoded. This capability provides the basis for archiving (where objects and other structures are stored on disk) and distribution (where objects are copied to different address spaces).

    encodeWithCoder

    encodeWithCoder: instructs the object to encode its instance variables to the coder provided; an object can receive this method any number of times.

    initWithCoder

    initWithCoder: instructs the object to initialize itself from data in the coder provided; as such, it replaces any other initialization method and is sent only once per object.

    Then I understood that we must implement the encodeWithCoder and inintWithCoder first in NSObject Class.After that only we should save and retrieve the data.

    ->encoder is an archiver object
    ->decoder is an unarchiver object

    Now First we have to implement the encodeWithCoder and initWithCoder in SavingBean.m

    - (void)encodeWithCoder:(NSCoder *)encoder 
    {
      //Encode properties, other class variables, etc
      [encoder encodeObject:@"AbhiRam" forKey:@"username"];
      [encoder encodeObject:@"Test@123" forKey:@"password"];
    }
    
    - (id)initWithCoder:(NSCoder *)decoder 
    {
      if((self = [super init]))
      {
        //decode properties, other class vars
        userName = [decoder decodeObjectForKey:@"username"];
        passWord = [decoder decodeObjectForKey:@"password"];
      }
      return self;
    }
    

    Then in ViewController.m

    For Save

    SavingBean *savingbean = [[SavingBean alloc]init];
    NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:savingbean];
    [currentDefaults setObject:data forKey:@"DATA"];
    [currentDefaults synchronize];
    

    For Retrieve

    NSData *data = [currentDefaults objectForKey:@"DATA"];
    savingbean = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    

    Now when I run the application it does not show any error.It works fine now.

    Why I give these things here is If anybody sees and tries this answer in some case they can get the error like above.So if they prefer two answer for this question they can very easily understand and get the solution very simply.

    encodeWithCoder and initWithCoder of NSCoding

    0 讨论(0)
提交回复
热议问题