首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WatchConnectivity与并发症相结合

WatchConnectivity与并发症相结合
EN

Stack Overflow用户
提问于 2016-04-26 06:02:49
回答 1查看 1.1K关注 0票数 1

我希望我的复杂性通过监视连接从iPhone获取数据。我正在使用sendMessage即时消息技术。

当我试图获取数据时,我不希望我的iPhone应用程序打开,所以这需要在后台工作。

在我的ViewController上,我的iPhone:

代码语言:javascript
复制
import UIKit
import WatchConnectivity

class ViewController: UIViewController, WCSessionDelegate {

var session: WCSession!

override func viewDidLoad() {
    super.viewDidLoad()
    if WCSession.isSupported() {
        self.session = WCSession.defaultSession()
        self.session.delegate = self
        self.session.activateSession()
    }
}

func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
    if message.count != 1 { return }

    if message["request"] != nil {
        replyHandler(["response" : "data"])
    }
}

在我的ComplicationController里

代码语言:javascript
复制
var session: WCSession!

func getCurrentTimelineEntryForComplication(complication: CLKComplication, withHandler handler: ((CLKComplicationTimelineEntry?) -> Void)) {
    if complication.family != .ModularSmall {
        handler(nil)
    }

    if WCSession.isSupported() {
        self.session = WCSession.defaultSession()
        self.session.delegate = self
        self.session.activateSession()
    }

    var respondedString = "not"

    session.sendMessage(["request" : ""], replyHandler: {
        (resp) -> Void in
        respondedString = resp["response"]
    }, errorHandler: nil)

    let circularTemplate = CLKComplicationTemplateModularSmallSimpleText()
    circularTemplate.textProvider = CLKSimpleTextProvider(text: respondedString)
    let timelineEntry = CLKComplicationTimelineEntry(date: NSDate(), complicationTemplate: circularTemplate)
    handler(timelineEntry)
}

我在手表上唯一能看到的就是“没有”。为什么复杂的情况不能显示接收到的数据?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-26 07:01:45

主要问题是,您试图在复杂控制器中进行异步调用。

您的sendMessage:调用之后的代码将在您的回复处理程序得到响应之前执行。这就是为什么在收到回复之前,复杂的情况显示模板的文本已经设置为"not“。

稍后,在getCurrentTimelineEntryForComplication返回之后,sendMessage将收到一个响应并调用reply hander,这只会设置respondedString,然后退出该块。

您应该避免做的事情:

您应该考虑苹果公司的建议,而不是尝试在复杂控制器中获取任何数据。

数据源类的任务是尽快向ClockKit提供任何请求的数据。数据源方法的实现应该是最小的。不要使用数据源方法从网络获取数据、计算值或做任何可能延迟数据传递的操作。如果您需要获取或计算复杂的数据,请在您的iOS应用程序或WatchKit扩展的其他部分中这样做,并将数据缓存在复杂数据源可以访问的地方。数据源方法应该做的唯一一件事就是获取缓存的数据,并将其放入ClockKit所需的格式中。

而且,在数据源中执行的任何活动都将不必要地消耗分配给复杂情况的每日执行时间预算。

如何为您的并发症提供数据?

苹果公司提供了一种手表连接transferCurrentComplicationUserInfo方法,它将立即将复杂信息的字典从手机传输到手表。

当您的iOS应用程序接收到针对您的复杂性的更新数据时,它可以使用Watch连接框架立即更新您的复杂性。transferCurrentComplicationUserInfo: WCSession方法向您的WatchKit扩展发送一条高优先级消息,并根据需要唤醒它以交付数据。接收到数据后,根据需要扩展或重新加载时间线,以强制ClockKit从数据源请求新数据。

在手表方面,您有您的WCSessionDelegate句柄didReceiveUserInfo,并使用您收到的数据来更新您的复杂性:

代码语言:javascript
复制
func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) {
    if let ... { // Retrieve values from dictionary

        // Update complication
        let complicationServer = CLKComplicationServer.sharedInstance()
        guard let activeComplications = complicationServer.activeComplications else { // watchOS 2.2
            return
        }

        for complication in activeComplications {
            complicationServer.reloadTimelineForComplication(complication)
        }
    }
}

苹果公司的工程师通常建议设置一个数据管理器来保存数据。在复杂控制器中,您将从数据管理器中检索用于时间轴的最新信息。

在GitHub上有几个使用这种方法的现有项目。

如果您仍然希望从监视端请求数据:

您可能希望将WCSession代码从复杂控制器中移出,进入监视扩展,并将其激活为WKExtension init的一部分。

关键是一旦接收到数据,就让应答处理程序手动更新复杂的内容。

当您的会话委托的应答处理程序被调用时,您可以使用我先前提供的更新复杂性代码来重新加载复杂事件的时间线。

如果您使用计划中的复杂更新来触发此操作,则该特定方法的缺点是您将执行两个更新。第一个更新将启动数据请求,但不需要使用任何新的数据。第二次(手动)更新发生在接收数据之后,这时新数据将出现在时间线上。

这就是为什么从电话中提供后台数据的方法更好,因为它只需要一次更新。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36856436

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档