Shared/WatchConnectivityManager.swift
/* |
Copyright (C) 2016 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
This file contains the `WatchConnectivityManager` class and its delegate which encapsulate the `WatchConnectivity` behavior of the app. |
*/ |
import WatchConnectivity |
/** |
The `WatchConnectivityManagerDelegate` protocol enables a `WatchConnectivityManager` object to notify another |
object of changes to the activation state of the default `WCSession`. On iOS the receiver is provided with the |
designator and color selected by the user to identify the watch associated with the default session. On the |
Watch app the receiver is provided with any new morse codes. |
*/ |
protocol WatchConnectivityManagerPhoneDelegate: class { |
func watchConnectivityManager(_ watchConnectivityManager: WatchConnectivityManager, updatedWithDesignator designator: String, designatorColor: String) |
} |
protocol WatchConnectivityManagerWatchDelegate: class { |
func watchConnectivityManager(_ watchConnectivityManager: WatchConnectivityManager, updatedWithMorseCode morseCode: String) |
} |
class WatchConnectivityManager: NSObject, WCSessionDelegate { |
// MARK: Static Properties |
static let sharedConnectivityManager = WatchConnectivityManager() |
// MARK: Properties |
#if os(iOS) |
weak var delegate: WatchConnectivityManagerPhoneDelegate? |
#else |
weak var delegate: WatchConnectivityManagerWatchDelegate? |
#endif |
// MARK: Initialization |
private override init() { |
super.init() |
} |
// MARK: Convenience |
func configureDeviceDetailsWithApplicationContext(applicationContext: [String: Any]) { |
#if os(iOS) |
// Extract relevant values from the application context. |
guard let designator = applicationContext["designator"] as? String, let designatorColor = applicationContext["designatorColor"] as? String else { |
// If the expected values are unavailable in the `applicationContext`, inform the delegate using default values. |
delegate?.watchConnectivityManager(self, updatedWithDesignator: "-", designatorColor: "Blue") |
return |
} |
// Inform the delegate. |
delegate?.watchConnectivityManager(self, updatedWithDesignator: designator, designatorColor: designatorColor) |
#endif |
} |
// MARK: WCSessionDelegate |
func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) { |
print("session (in state: \(session.activationState.rawValue)) received application context \(applicationContext)") |
configureDeviceDetailsWithApplicationContext(applicationContext: applicationContext) |
// NOTE: The guard is here as `watchDirectoryURL` is only available on iOS and this class is used on both platforms. |
#if os(iOS) |
print("session watch directory URL: \(session.watchDirectoryURL?.absoluteString)") |
#endif |
} |
func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any] = [:]) { |
#if os(watchOS) |
guard let morseCode = userInfo["MorseCode"] as? String else { |
// If the expected values are unavailable in the `userInfo`, then skip it. |
return |
} |
// Inform the delegate. |
delegate?.watchConnectivityManager(self, updatedWithMorseCode: morseCode) |
#endif |
} |
func session(_ session: WCSession, didFinish userInfoTransfer: WCSessionUserInfoTransfer, error: Error?) { |
if let error = error { |
print("\(error.localizedDescription)") |
} else { |
print("completed transfer of \(userInfoTransfer)") |
} |
} |
// MARK: WCSessionDelegate - Asynchronous Activation |
// The next method is required in order to support asynchronous session activation as well as for quick watch switching. |
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { |
if let error = error { |
print("session activation failed with error: \(error.localizedDescription)") |
return |
} |
print("session activated with state: \(activationState.rawValue)") |
configureDeviceDetailsWithApplicationContext(applicationContext: session.receivedApplicationContext) |
// NOTE: The guard is here as `watchDirectoryURL` is only available on iOS and this class is used on both platforms. |
#if os(iOS) |
print("session watch directory URL: \(session.watchDirectoryURL?.absoluteString)") |
#endif |
} |
#if os(iOS) |
// The next 2 methods are required in order to support quick watch switching. |
func sessionDidBecomeInactive(_ session: WCSession) { |
/* |
The `sessionDidBecomeInactive(_:)` callback indicates sending has been disabled. If your iOS app |
sends content to its Watch extension it will need to stop trying at this point. This sample |
doesn’t send content to its Watch Extension so no action is required for this transition. |
*/ |
print("session did become inactive") |
} |
func sessionDidDeactivate(_ session: WCSession) { |
print("session did deactivate") |
/* |
The `sessionDidDeactivate(_:)` callback indicates `WCSession` is finished delivering content to |
the iOS app. iOS apps that process content delivered from their Watch Extension should finish |
processing that content and call `activateSession()`. This sample immediately calls |
`activateSession()` as the data provided by the Watch Extension is handled immediately. |
*/ |
session.activate() |
} |
#endif |
} |
Copyright © 2016 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2016-10-04