handleWatchKitExtensionRequest не отвечает на openParentApplication в расширении Watchkit (Swift)

Я пытаюсь отправить информацию из моего приложения WatchKit в мое основное родительское приложение, и, насколько я понимаю, я должен просто использовать openParentApplication в своем расширении watchkit, которое будет получено handleWatchKitExtensionRequest в AppDelegate.swift, но я не могу получить handleWatchKitExtensionRequest для запуска.

У меня были некоторые проблемы, поэтому на данный момент я просто пытаюсь установить какое-либо соединение, прежде чем беспокоиться о том, какая информация на самом деле передается. так что в настоящее время в моем Watchkit ViewController у меня есть следующее:

 let testDict = [
    "value1" : "Test 1",
    "value2" : "Test 2"
]

@IBAction func saveButtonFunction() {
    openParentAppForBalance(testDict)
}

private func openParentAppForInfo(Dict: [String: String]) {

    WKInterfaceController.openParentApplication(testDict,
        reply: {(reply, error) -> Void in
            println("openParentApplication called in button function")
    })
}

который показывает в выводе, что функция вызывается, но handleWatchKitExtensionRequest просто не отвечает. В настоящее время в AppDelegate.swift установлено следующее, которое никогда не вызывается:

func application(application: UIApplication!, handleWatchKitExtensionRequest userInfo: [NSObject : AnyObject]!, reply: (([NSObject : AnyObject]!) -> Void)!) {

    println("we made it!")

    var retValues = Dictionary<String,String>()

    retValues["retval1"] = "return Test 1"
    retValues["retval1"] = "return Test 2"

    reply(retValues)

}

Я уверен, что мне просто не хватает чего-то действительно фундаментального в моем понимании того, как все это работает, но любая помощь в том, как запустить handleWatchKitExtensionRequest, будет очень признательна!


person Joe Devine    schedule 23.01.2015    source источник


Ответы (2)


Ах, я думаю, что здесь происходит то, что ваш код и правильный, и работает точно так, как должен, и то, что вы здесь интерпретируете, является результатом наложения двух вполне понятных предположений, которые на самом деле неверны и были вводя вас в заблуждение. Итак, хорошая новость в том, что ваш код уже работает.

Ты говоришь,

... который показывает в выводе, что функция вызывается...

Если под этим вы подразумеваете, что в консоли вы видите сообщение openParentApplication called in button function, то вот что происходит:

Эта часть вашего кода представляет собой быстрое закрытие:

{(reply, error) -> Void in
        println("openParentApplication called in button function")
}

Когда ваше расширение WatchKit вызывает WKInterfaceController.openParentApplication, оно передает вашему родительскому приложению iPhone словарь (ваш testDict), который приложение iPhone может использовать для возврата вам данных — при условии, что данные были сериализованы. Он также возвращает вам замыкание, которое вы передали. Это позволяет вашему расширению WatchKit запускать код, который он сам определил, позже, когда будет получен ответ. Вы можете включить в это закрытие использование как возвращаемых данных в testDict, так и других переменных, которые были локально доступны во время вызова openParentApplication. Ваше расширение WatchKit автоматически выполняет код в закрытии, когда оно получено обратно.

Таким образом, когда вы видите openParentApplication called in button function, это означает, что ответ от приложения iPhone получен и закрытие выполнено. Следовательно, ваш тестовый код WatchKit действительно должен изменить оператор println следующим образом:

WKInterfaceController.openParentApplication(testDict,
    reply: {(reply, error) -> Void in
        println("Reply to openParentApplication received from iPhone app")
    })

Теперь причина, по которой вы по вполне понятным причинам не поняли, что код выполняется правильно, заключалась в том, что вы ожидали увидеть отклонение в консоли, что этот код был выполнен в вашем приложении для iPhone:

println("we made it!")

Однако Xcode не поддерживает одновременное подключение к двум процессам. Поэтому, когда вы подключены к своему приложению WatchKit, вы не увидите никаких сообщений журнала вашего приложения для iPhone. Ваше приложение для iPhone также не будет реагировать на точки останова, если оно не является присоединенным процессом. Оба они верны независимо от того, работает ли оно в фоновом режиме (пробуждено openParentApplication) или работает на переднем плане (если вы запускаете его вручную в симуляторе после запуска приложения WatchKit. Вы можете увидеть эффекты активности приложения iPhone, но не можете напрямую изучить его, пока вы подключены к приложению WatchKit.

Итак, во-первых, ваш код работает правильно. Вы можете пройти мимо своего тестового кода! А в отношении самоанализа работы на стороне iPhone, когда он отвечает на ваше приложение WatchKit, есть частичное решение. Запустите приложение WatchKit из симулятора и после его запуска в Xcode активируйте пункт меню Отладка > Присоединить к процессу... и выберите процесс приложения для iPhone в разделе Вероятные цели вверху. Теперь вы будете видеть сообщения консоли вашего приложения для iPhone, и ваше приложение для iPhone будет реагировать на точки останова, но, конечно же, вы больше не увидите их со стороны приложения WatchKit. Вы по-прежнему можете взаимодействовать с обоими приложениями в симуляторах и можете переключаться между ними во время выполнения.

person Duncan Babbage    schedule 23.01.2015
comment
Спасибо вам большое за это! выбор моего приложения для iPhone под вероятными целями, похоже, по-прежнему не показывает мне вывод из приложения для iPhone (на самом деле он вообще не показывает никакого вывода), но я сделал частичное решение для частичного решения, передав «.description» назад как элемент в ответе для каждой вещи, которую я хотел показать, и распечатал их в выводе расширения Watchkit. но теперь все работает отлично - спасибо за помощь! - person Joe Devine; 26.01.2015
comment
Пример кода о том, как использовать фоновый режим, который гарантирует, что у основного приложения есть время для отправки ответа, см. в разделе Вызов родительского приложения из приложения Watch (stackoverflow.com/questions/30000274/) - person vomako; 02.05.2015
comment
Один важный момент: Xcode может подключаться к нескольким процессам одновременно для отладки этого: после запуска приложения Watch Kit в iPhone Simulator щелкните значок вашего основного приложения (чтобы запустить его), а затем вернитесь в Xcode. В строке меню в меню «Отладка» выберите «Присоединить к процессу» и выберите свое основное приложение. Теперь вы отлаживаете как расширение Watch Kit, так и основное приложение! - person Nils Ziehn; 11.05.2015
comment
Упс, только что увидел второй ответ .. nvm. - person Nils Ziehn; 11.05.2015

Просто примечание: вы на самом деле можете подключиться к двум процессам одновременно в Xcode, и это очень полезно для отладки WatchKit. Создайте и запустите цель расширения WatchKit из Xcode, и она начнет работать в симуляторе. Теперь в симуляторе запустите приложение для iOS. После этого перейдите в Debug->Attach to Process->[Name of your app process]. Теперь вы увидите, что оба процесса выполняются в Xcode, и вы сможете вести журнал, отлаживать и т. д. в обоих случаях.

person Sean    schedule 06.03.2015
comment
Разве присоединение к одному процессу не отсоединяется от другого? По моему опыту, вы можете переключаться между процессами во время сеанса, но не можете просматривать отчеты журнала и т. Д. От них одновременно. Возможно, я что-то пропустил/пропустил недавнее изменение? - person Duncan Babbage; 31.03.2015
comment
Я не вижу журнал из основного приложения при использовании println(Debug). Как вы можете увидеть журнал после подключения основного приложения к XCode Debug? - person Peacemoon; 23.04.2015
comment
Я могу подтвердить, что действительно, отладка двух процессов, как описано выше, действительно работает, и я смог выполнить как расширение моего набора часов, так и сопутствующее приложение, когда я запустил openParent. - person EricWasTaken; 30.04.2015