Sharing an array of custom objects using Today Extension (widget) using NSUserDefaults

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 :)

+5
source share
1 answer

Good, so I just fixed it. If someone has the same problem, go to: "Goals"> "Widget"> "Generate phases"> "Compile sources"> add your own class there (Xitem.m)

+3
source

Source: https://habr.com/ru/post/1206427/


All Articles