This is my first post, so please be constructive when viewing my posting technique!
Basically, my problem is that I have an array of custom objects that I need to use with today's extension. Objects represent tasks in the to-do list, and their properties are used to store information about each task (name, location, proper character, thumbnail, etc.). Objects are stored in an array, which is used to populate the to-do list. All I want to do is pass this array to my widget so that I can populate the second view of the table, which will act as a compressed version of the first (for widgets).
I must indicate that my widget is configured correctly, since I correctly linked it and the containing application together in “groups”. I have also successfully used NSUserDefaults to pass an NSStrings array to a widget, however, when I try to pass an array of objects to a widget, it crashes and my log reads:
*** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (Xitem)'
I understand that this failure is related to object archiving (Xitem), which seems to be a necessary step for saving user objects to NSUserDefaults. However, I tested saving / loading an array in the same class of the containing application, and it works fine! (code below)
NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:self.Xitems]; NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.AaronTest"]; [defaults setObject:encodedObject forKey:@"myArray"]; [defaults synchronize]; NSUserDefaults *defaults2 = [[NSUserDefaults alloc] initWithSuiteName:@"group.AaronTest"]; NSData *encodedObject2 = [defaults2 objectForKey:@"myArray"]; NSArray *array2 = [NSKeyedUnarchiver unarchiveObjectWithData:encodedObject2]; for (Xitem *t in array2){ NSLog(@"*****%@*****", t.itemName); }
So, as explained, the above code works as expected. However, when I insert the second half of this code into my today's widget, I get the above error. Below, my code shows how I encode / decode an object (maybe it’s worth noting that this object was created for the simplicity of my debugging and contains only the NSString property):
Xitem.h
#import <UIKit/UIKit.h> #import <Foundation/Foundation.h> @interface Xitem : NSObject <NSCoding> { NSString *itemName; } -(void)encodeWithCoder:(NSCoder*)encoder; -(id)initWithCoder:(NSCoder*)decoder; @property NSString *itemName; @end
Xitem.m
#import "Xitem.h" @implementation Xitem @synthesize itemName; -(void)encodeWithCoder:(NSCoder*)encoder { [encoder encodeObject:self.itemName forKey:@"iName"]; } -(id)initWithCoder:(NSCoder*)decoder { self = [super init]; self.itemName = [decoder decodeObjectForKey:@"iName"]; return self; } @end
I could also publish my widget and contain the application code, but it is no different from the first set of published code (except for renamed variables such as "defaults2"). I must point out that I really ran out of resources trying to solve this problem, but the fact that using NSKeyedArchiver exclusively in the containing application works has left me in a dead end.
I understand that this post is very similar to my own problem, but the author decides to choose a workaround, while I really would like to know why this is happening. Do not work. I am a new developer, and I do my best to pick up the best working practices, so any advice would be greatly appreciated.
I think it is also possible to replace my object (class) with NSDictionary? However, I would like to avoid this, if possible, because it will cause a lot of conflict in the main application, but obviously, if this is the right method, I will solve this problem. On the side of the note, if the dictionary is better than an object for my requirements (to-do list with UIImage, CLLocation properties, etc.) For some other reasons (like memory or accessibility), please work through and help me understand why. !
Thanks a lot for any time :)