Простой способ обновить контент приложения через 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, которое регулярно проверяет наличие изменений в определенных ключах и выдает само уведомление при обнаружении этого изменения.

Другие вопросы по тегам