[英]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.