The object that initiates communication between a WatchKit extension and its companion iOS app. Your iOS app and watchOS app must both create and configure an instance of this class at some point during their execution. When both session objects are active, the two processes can communicate immediately by sending messages back and forth. When only one session is active, the active session may still send updates and transfer files, but those transfers happen opportunistically in the background.
You do this by implementing the following methods in your session delegate:
-
session(_:activationDidCompleteWith:error:)
-
sessionDidBecomeInactive(_:)
-
sessionDidDeactivate(_:)
Figure 1 shows the sequence of events that happen when the user switches from one Apple Watch to another. When automatic switching is enabled, only one Apple Watch at a time actually communicates with the iOS app. The Watch app on each watch stays in the active state, but the iOS app moves to the inactive and deactivated states during a switch.
Use the updateApplicationContext(_:) method to communicate recent state information to the counterpart. When the counterpart wakes, it can use this information to update its own state. For example, an iOS app that supports Background App Refresh can use part of its background execution time to update the corresponding Watch app. This method overwrites the previous data dictionary, so use this method when your app needs only the most recent data values.
Use the sendMessage(:replyHandler:errorHandler:) or sendMessageData(:replyHandler:errorHandler:) method to transfer data to a reachable counterpart. These methods are intended for immediate communication between your iOS app and WatchKit extension. The isReachable property must currently be true for these methods to succeed.
Use the transferUserInfo(_:) method to transfer a dictionary of data in the background. The dictionaries you send are queued for delivery to the counterpart and transfers continue when the current app is suspended or terminated.
Use the transferFile(_:metadata:) method to transfer files in the background. Use this method in cases where you want to send more than a dictionary of values. For example, use this method to send images or file-based documents.
In iOS, use the transferCurrentComplicationUserInfo(_:) method to send data related to your Watch app’s complication. Use of this method counts against your complication’s time budget.
Connectivity
final class Connectivity: NSObject {
static let shared = Connectivity()
private override init() {
super.init()
// You should only start a session if it is supported.
#if !os(watchOS)
guard WCSession.isSupported() else {
return
}
#endif
// When you initialize Connextivity, you tell the device to activate the session whitch lets yopu talk to a paired device.
WCSession.default.activate()
}
}
// The WCSessionDelegate protocol extends NSObjectProtocol. That means for Connectivity to be the delegate, it must inherit from NSObject.
final class Connectivity: NSObject {
static let shared = Connectivity()
private override init() {
super.init()
// MARK: - WCSessionDelegate
extension Connectivity: WCSessionDelegate {
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
}
#if os(iOS) // those methods are part of the delegate on iOS
func sessionDidBecomeInactive(_ session: WCSession) {
}
func sessionDidDeactivate(_ session: WCSession) {
// If the person has more than one aplle watch, and they switch,
// reactivate their session on the new deveice.
WCSession.default.activate()
}
#endif
}
private override init() {
super.init()
#if !os(watchOS)
guard WCSession.isSupported() else {
return
}
#endif
WCSession.default.delegate = self
WCSession.default.activate()
}
public func send(movieIds: [Int]) {
guard WCSession.default.activationState == .activated else {
return
}
#if os(watchOS)
guard WCSession.default.isCompanionAppInstalled else { // THe Apple Watch checks if the app is on the phone.
return
}
#else
guard WCSession.default.isWatchAppInstalled else { // The iOS deveice checks if the app is on the Apple Watch.
return
}
#endif
let userInfo: [String: [Int]] = [
ConnectivityUserInfoKey.purchased.rawValue: movieIds
]
WCSession.default.transferUserInfo(userInfo)
}
final class Connectivity: NSObject, ObservableObject {
@Published var puchaseIds: [Int] = []
func session(_ session: WCSession, didReceiveUserInfo userInfo: [String: Any] = [:]) {
let key = ConnectivityUserInfoKey.purchased.rawValue
guard let ids = userInfo[key] as? [Int] else {
return
}
self.puchaseIds = ids
}