Простой способ обновить контент приложения через Apple Watch
Я не мог найти простой способ обновить представление в приложении для iPhone, когда я нажимал кнопку в приложении AppleWatch.
Я попробовал это с NSUserDefaults Observer следующим образом:
Контроллер приложения для iPhone (внутри ViewDidLoad()):
// Create and share access to an NSUserDefaults object.
mySharedDefaults = NSUserDefaults(suiteName: "group.sharedTest")
//Add Observer
NSUserDefaults.standardUserDefaults().addObserver(self, forKeyPath: "test", options: NSKeyValueObservingOptions.New, context: nil)
В контроллере интерфейса Watchkit Extensions я добавил IBAction с кнопкой с этим кодом:
mySharedDefaults!.setObject("testValue", forKey: "test")
mySharedDefaults!.synchronize()
Но когда я нажимаю кнопку, ничего не происходит! Если я установлю объект внутри моего iPhone ViewController, он будет работать, но не тогда, когда он обновляется через приложение! Кто-нибудь может мне помочь?
2 ответа
Тебе не повезло, потому что когда ты писал свой вопрос, в iOS SDK не было API для этого. Три дня назад, 10 декабря 2014 года, Apple выпустила iOS 8.2 beta 2 SDK с двумя важными для этой задачи способами.
В WatchKit Framework, WKInterfaceController
учебный класс
// Obj-C
+ (BOOL)openParentApplication:(NSDictionary *)userInfo
reply:(void (^)(NSDictionary *replyInfo,
NSError *error))reply
При вызове этого метода iOS запустит ваше приложение в фоновом режиме, и AppDelegate приложения получит это сообщение
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply.
Это второй метод, добавленный в iOS SDK Beta 2 (с точки зрения этого вопроса) в UIKit Framework, UIApplicationDelegate
учебный класс.
Вы можете использовать NSDictionary и блок ответа для связи приложения Watch и приложения iOS.
пример
В вашем WKInterfaceController
подкласс
- (IBAction)callPhoneAppButtonTapped
{
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"text to display", @"key", nil];
[InterfaceController openParentApplication:dictionary reply:^(NSDictionary *replyInfo, NSError *error) {
NSLog(@"Reply received by Watch app: %@", replyInfo);
}];
}
а затем в вашем классе iOS AppDelegate
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply
{
NSLog(@"Request received by iOS app");
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"your value to return to Apple Watch", @"key", nil];
reply(dictionary);
}
Когда вы нажмете кнопку на симуляторе Apple Watch, ваше приложение iOS в iOS Simulator будет запущено, и вы сможете увидеть NSLog в нужных местах.
Заметка
Это решение работает для транспортировки объектов между приложениями Watch и iOS. Но если вы планируете передавать больше данных, получать доступ к изображениям, файлам и т. Д., Вам следует использовать Shared app group
, Вы устанавливаете общую группу приложений в Capabilities в вашем файле проекта Xcode. использование containerURLForSecurityApplicationGroupIdentifier
(NSFileManager
класс), чтобы получить URL-адреса файлов в общей группе.
Если вы хотите поделиться настройками initWithSuiteName
от NSUserDefaults
это то, что вы ищете.
Я предполагаю, что приложение расширения WatchKit и ваше приложение для iPhone - это отдельные запущенные экземпляры приложений, и что уведомления относятся к одному экземпляру.
В качестве альтернативы, возможно, вы могли бы создать новую операцию в отдельном потоке в приложении для iPhone, которое регулярно проверяет наличие изменений в определенных ключах и выдает само уведомление при обнаружении этого изменения.