How do I properly pass a NSMutableArray to NSUserD

2019-09-21 07:52发布

Let me preface that my code has been obscured a little on purpose. I know the name won't be good. I am trying to add a widget to my app with the new iOS 8 functionality. I am using this link as a tutorial

Now, so far I have this in my ViewController when my submit button is called in my app. By this time I have all my data in that array to be passed on.

//Passes the array of times to the shared group to be called by the notification center widget.
NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.myGroup.TodayExtensionSharingDefaults"];
NSData *encodedArray = [NSKeyedArchiver archivedDataWithRootObject:tableViewController.TimeArray];
[sharedDefaults setObject:encodedArray  forKey:@"TimesArray"];
[sharedDefaults synchronize];

However, my array stores a custom data model I created, so in my data model I have:

- (void)encodeWithCoder:(NSCoder *)encoder {
    //Encode properties, other class variables, etc
    [encoder encodeInt:_stopNumber forKey:@"stopNumber"];
    [encoder encodeObject:_route forKey:@"route"];
    [encoder encodeObject:_number forKey:@"number"];
    [encoder encodeInt:_time forKey:@"time"];
    [encoder encodeObject:_minutesOrApproaching forKey:@"@minutesOrApproaching"];
    [encoder encodeObject:_noPrediction forKey:@"noPrediction"];
}

- (id)initWithCoder:(NSCoder *)decoder {
    self = [super init];
    if(self) {
        //decode properties, other class vars
        _stopNumber = [decoder decodeIntForKey:@"stopNumber"];
        _route = [decoder decodeObjectForKey:@"route"];
        _number = [decoder decodeObjectForKey:@"number"];
        _time = [decoder decodeIntForKey:@"time"];
        _minutesOrApproaching = [decoder decodeObjectForKey:@"minutesOrApproaching"];
        _noPrediction = [decoder decodeObjectForKey:@"noPrediction"];
    }
    return self;
}

And then in my Widget I have this code being called:

NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.myGroup.TodayExtensionSharingDefaults"];
    NSData *myDecodedObject = [defaults objectForKey: @"TimesArray"];
    NSArray *decodedArray =[NSKeyedUnarchiver unarchiveObjectWithData: myDecodedObject];

    int i = 0;
    for (ETA *eta in decodedArray) {
        if(i == 0){
            _stopNumber.text = eta.number;
        }
        UILabel *label = [timeSlots objectAtIndex:i];
        label.text = eta.minutesOrApproaching;
        i++;
    }

My issue is that I keep getting:

* Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '* -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (ETA)' enter code here

So I am a little off put because I don't know what I am doing wrong here. It would be really great if someone could help point me in the right direction. Thanks again!

1条回答
Bombasti
2楼-- · 2019-09-21 08:18

So, turns out passing custom classes can be a pain. And although all the code seems to be right, I am still getting the error. So I stepped back and looked at my custom object and asked myself "What is it that I really need from this?" and using that process decided I only needed certain values, so with that I encrypted only those values and not the object. Since those values were ints and strings, they are built into iOS on how to encode and decode. From there, I was able to pass the values around thanks to @meda's answer and my idea.

查看更多
登录 后发表回答