使用NSUserDefaults与Today Extension(小部件)共享自定义对象数组

5

这是我第一次在Stack上发布文章,请在审查我的发布技术时提供建设性的意见!

基本上,我的问题是我有一个自定义对象数组,需要与今天的小部件共享。这些对象表示待办事项列表中的任务,它们的属性用于存储有关每个任务的信息(名称、位置、到期日期、缩略图等)。对象存储在数组中,该数组用于填充我的待办事项列表。我想做的就是将此数组传递给我的小部件,以便我可以填充第二个表格视图,该视图将充当第一个表格视图的压缩版本(用于小部件视图)。

我应该指出的是,我的小部件已经正确设置,即我已经在“组”中正确链接了它和包含应用程序。我还成功使用NSUserDefaults将NSStrings数组传递给小部件,但是,当我尝试将对象数组传递给小部件时,它会崩溃,我的日志显示:

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

我理解这个崩溃与存档对象(Xitem)有关,这似乎是将自定义对象保存在NSUserDefaults中必要的步骤。但是,我已经测试过在包含应用程序的同一类中保存/加载数组,那样是正常的!(下面是代码)
        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);
        }

好的,如上所述,以上代码按预期工作。然而,当我将此代码的第二个“unarchiver”部分插入到我的今天小部件中时,就会出现上述错误。以下是我的代码,展示了我如何对对象进行编码/解码(值得注意的是,这个对象是为了方便我的调试而创建的,只包含一个NSString属性):

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

我也可以发布我的小部件和包含应用程序的代码,但它与我发布的第一组代码没有区别(除了重命名的变量,例如“defaults2”)。我应该指出,我在尝试解决这个问题时已经耗尽了所有资源,但是仅在包含应用程序中使用NSKeyedArchiver有效的事实让我感到困惑。
我意识到这篇文章与我的问题非常相似,但作者决定选择解决方法,而我实际上想知道为什么这不起作用。我是一个新开发人员,正在尽力掌握最佳工作实践,因此任何建议都将不胜感激。
我认为还可以用NSDictionary替换我的对象(类)?但是,如果可能的话,我希望避免这样做,因为它会在主应用程序中引起许多冲突,但是如果那是正确的方法,我将解决这个问题。顺便说一句,如果字典对于我的要求(具有UIImage、CLLocation等属性的待办事项列表)来说比对象更好,出于任何其他原因(例如内存或可访问性),请详细说明并帮助我理解为什么!

非常感谢任何人的时间 :)


有人能给我提供一些意见吗?我把这个问题搁置了,因为它似乎应该按照这种方式工作,如果有人知道为什么它不起作用,请指出来。很抱歉打扰了,但已经过去一周了。 - Swankzilla
1个回答

3
好的,我刚刚解决了这个问题。如果有人遇到相同的问题,请按照以下步骤操作:进入“目标”->“小部件”->“构建阶段”->“编译源代码”->在那里添加自定义类(Xitem.m)。

请注意,这样做会导致您的应用程序包增加不必要的重复内容。实际上,您正在构建两个单独的对象文件,这些文件将内联链接到您的应用程序和应用程序扩展中。对于较小的应用程序来说并不是什么大问题,但是重复此模式可能会使您的二进制文件比必要更多。最终,我认为一个更好的长期模式是将您的(在应用程序和应用程序扩展之间共同的)代码提取到一个框架中,然后将您的应用程序应用程序扩展链接到该框架。 - fullofsquirrels

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接