[英]iOS 8 widget, sharing data between app groups forward and backward
我有一个消息应用程序,我开始创建一个小部件。 用户打开应用程序时,会使用新消息更新核心数据。 我的愿望是何时:
- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler
调用我将获取UIViewController
并调用获取消息线程。 将UIViewController
链接到我的小部件目标给了我一个错误:
'sharedApplication' is unavailable....
所以我取消了。
我要实现的目标:1.正在调用widgetPerformUpdateWithCompletionHandler 2.应用程序启动获取消息线程/方法3.完成后,它将使用NSUserDefaults将数据发送回小部件
我的代码:
1:
- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler
{
// Perform any setup necessary in order to update the view.
[self startGetMessages];
// If an error is encountered, use NCUpdateResultFailed
// If there's no update required, use NCUpdateResultNoData
// If there's an update, use NCUpdateResultNewData
completionHandler(NCUpdateResultNewData);
}
2:
- (void)startGetMessages
{
NSLog(@"%s", __PRETTY_FUNCTION__);
NSBundle *deviceBundle = [NSBundle mainBundle];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:deviceBundle];
id MainController = [storyboard instantiateViewControllerWithIdentifier:@"MainTableViewController"];
SEL getMessagesSelector = NSSelectorFromString(@"startGetMessages:");
if (MainController)
{
NSThread *startGetMessagesThread = [[NSThread alloc] initWithTarget:MainController
selector:getMessagesSelector
object:StringForInt(HRTableDataSourceKindUpdate)];
[startGetMessagesThread start];
}
}
3:
- (void)notifyWidgetForChanges
{
__block NSMutableDictionary *newMessages = [NSMutableDictionary new];
NSArray *results = [CoreDataPhotoRecord MR_findAllSortedBy:@"message.originalDate"
ascending:NO
withPredicate:[NSPredicate predicateWithFormat:@"(message.delete_message == %@) AND (message.type.integerValue == %d) AND (message.originalDate >= %@)",
@NO, NORMAL_MESSAGE, _notiftWidgetDate]];
NSLog(@"%s, _notiftWidgetDate: %@, newMessages.count: %d", __PRETTY_FUNCTION__, _notiftWidgetDate, newMessages.count);
[results enumerateObjectsUsingBlock:^(CoreDataPhotoRecord *photoDetails, NSUInteger idx, BOOL *stop)
{
if (photoDetails != nil && photoDetails.message != nil)
{
NSString *cleanMobile = [[ABAddressBook sharedAddressBook] getCleanMobile:photoDetails.message.mobile];
Contact *person = [[ABAddressBook sharedAddressBook] findContactWithPhoneNumber:cleanMobile];
ContactWidget *contact = [[ContactWidget alloc] init];
contact.name = (person != nil && person.name != nil && person.name.length > 0) ? person.name : cleanMobile;
[newMessages setObject:contact forKey:cleanMobile];
}
}];
[SharedUtilities archiveObject:newMessages.copy forKey:MESSAGES_KEY_NEW widget:true];
[DEFAULTS_WIDGET setObject:@"111" forKey:@"111"];
[DEFAULTS_WIDGET synchronize];
newMessages = nil;
results = nil;
}
widgetDefaults = [[NSUserDefaults alloc] initWithSuiteName:WIDGET_GROUP_NAME];
由于步骤2中的MainController
为nil,因此没有任何反应。 我能做什么?
出现nil
问题是因为您尝试从小部件访问应用程序的故事板。 这并不简单,因为包含的应用程序和窗口小部件扩展被保存在单独的捆绑包中。 因此,步骤2)中的[NSBundle mainBundle]
与您的应用中的捆绑包不同。
可能的解决方案包括:
通过将应用程序的Main.storyboard
添加到小部件的“目标Build Phases
选项卡上的“ Copy Bundle resources
列表中,或仅将小部件目标添加到目标成员资格的 Main.storyboard
列表中
将负责从MainController startGetMessages:
获取消息的代码移动到可以从应用程序和小部件均可访问的共享框架中,最好是移到专用对象中。
第二个更好。 根据经验,在进行面向对象的编程时最好遵循SOLID原则,其中S代表单一职责 。 视图控制器不应负责在整个系统范围内提供消息获取。 创建一个只有一个任务的专用对象-获取消息-在目标之间共享它是一种方法。
请参阅文档以获取有关如何创建共享框架的详细说明: https : //developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html#//apple_ref/doc/ UID / TP40014214-CH21-SW1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.