1

我一直在为 WCSession 使用 NatashaTheRobot 单例,但无法让 sendMessage 正常工作。

我的目标是从 Watch 应用程序向 iOS 应用程序发送消息,并将字典从 iOS 应用程序传输到手表应用程序。

这是我在ExtensionDelegate中的代码

import WatchKit
import WatchConnectivity

class ExtensionDelegate: NSObject, WKExtensionDelegate, WCSessionDelegate {

var session:WCSession!
var boolCheck = Int()

func applicationDidFinishLaunching() {

    WatchSessionManager.sharedManager.startSession()
    print("Here i am")
}

func applicationDidBecomeActive() {
    print("I AWOKE")
}

func applicationWillResignActive() {

}

}

class WatchSessionManager: NSObject, WCSessionDelegate {

static let sharedManager = WatchSessionManager()
private override init() {
    super.init()
}

private let session: WCSession = WCSession.defaultSession()

func startSession() {
    session.delegate = self
    session.activateSession()
    if WCSession.isSupported(){
        self.session.sendMessage(["b":"peek"], replyHandler: nil, errorHandler: nil)
        print("works")
    } else {
        print("don't work")
    }

func session(session: WCSession, didReceiveMessage message: [String : AnyObject]) {
    let sweetN = message["b"]! as? String
    dispatch_async(dispatch_get_main_queue(), {
        if sweetN == "insertData1" {
            NSNotificationCenter.defaultCenter().postNotificationName("sweetData1", object: nil)
    })
}
func sendMessage(message: [String : AnyObject],
    replyHandler: (([String : AnyObject]) -> Void)? = nil,
    errorHandler: ((NSError) -> Void)? = nil)
{
    session.sendMessage(message, replyHandler: replyHandler, errorHandler: errorHandler)
    print("this is message \(replyHandler)")
    var pretty = replyHandler
}

这是我在 iOS 应用程序的WCSingleton中的代码(与 AppDelegate 分开)

import WatchConnectivity

@available(iOS 9.0, *)
class WatchSessionManager: NSObject, WCSessionDelegate {

static let sharedManager = WatchSessionManager()
private override init() {
    super.init()
}

private let session: WCSession? = WCSession.isSupported() ? WCSession.defaultSession() : nil

private var validSession: WCSession? {

    if let session = session where session.paired && session.watchAppInstalled {
        return session
    }
    return nil
}

func startSession() {
    session?.delegate = self
    session?.activateSession()
}
func session(session: WCSession, didReceiveMessage message: [String : AnyObject]) {
    //receieve messages from watch
    print(message["b"]! as? String)
    let sweetN = message["b"]! as? String
    dispatch_async(dispatch_get_main_queue(), {
        if sweetN == "peek"{
            NSNotificationCenter.defaultCenter().postNotificationName("giveMeInfo", object: nil)
        }
     }
    })
}

@available(iOS 9.0, *)
extension WatchSessionManager {

func sendMessage(message: [String : AnyObject],
    replyHandler: (([String : AnyObject]) -> Void)? = nil,
    errorHandler: ((NSError) -> Void)? = nil)
{
    session!.sendMessage(message, replyHandler: replyHandler, errorHandler: errorHandler)
}

}

这是我在ViewController中使用的方法(从 触发NSNotificationCenter)。然而,这部分代码永远不会被执行(这很奇怪,因为当我使用 applicationContext 时它工作得很好)。

func giveMeInfo(){
        let linesAdd1 = linesAdd as! AnyObject
        WatchSessionManager.sharedManager.sendMessage(["a":linesAdd1])
}

任何关于如何让所有这些部分协同工作的见解都非常受欢迎!

4

1 回答 1

3

您的代码对我来说有点令人困惑并且看起来不错,但是由于以下原因,您会遇到这种方法的麻烦:

  • 如果您在 ViewController 中收到通知并且 Watch 变为非活动状态,则 sendMessage() 方法将无法发送回数据:

    在 WatchKit 扩展程序处于活动状态并运行时调用此方法会在后台唤醒相应的 iOS 应用程序并使其可访问。从您的 iOS 应用程序调用此方法不会唤醒相应的 WatchKit 扩展。如果您调用此方法并且对应方无法访问(或在消息传递之前变得无法访问),则会执行 errorHandler 块并出现适当的错误。如果消息参数包含非属性列表数据类型,也可以调用 errorHandler 块。

  • 如果你想取回数据,那么你应该使用回复块。但是在您的配置中,这些块不会被调用,因为:

sendMessage(reply==nil) --> didReceiveMessage(... message: )

sendMessage(reply!=nil) --> didReceiveMessage(... message: replyHandler:)

  • 另一方面,如果您使用 contextMethod:

    使用此方法将数据项字典传输到对应应用程序。当机会出现时,系统会发送上下文数据,目标是在对方醒来时准备好使用数据。对方的会话将数据传递给其委托的 session:didReceiveUpdate: 方法。对方也可以从其会话的 receivedApplicationContext 属性中检索数据。

我希望这有帮助 ;)

于 2016-04-26T13:16:13.193 回答