Last active
April 8, 2023 21:33
-
-
Save filsv/55febaea46b6d15d6309a7da7296ec3a to your computer and use it in GitHub Desktop.
WatchConnectivity Singleton (Swift 5+, iOS+WatchOS Targets) + How to (comment below)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import WatchConnectivity | |
class WatchSessionManager: NSObject, WCSessionDelegate { | |
static let sharedManager = WatchSessionManager() | |
private override init() { | |
super.init() | |
} | |
private let session: WCSession? = WCSession.isSupported() ? WCSession.default : nil | |
@available(iOS 9.3, *) | |
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { | |
} | |
#if os(iOS) | |
func sessionDidBecomeInactive(_ session: WCSession) { | |
} | |
func sessionDidDeactivate(_ session: WCSession) { | |
} | |
#endif | |
var validSession: WCSession? { | |
// paired - the user has to have their device paired to the watch | |
// watchAppInstalled - the user must have your watch app installed | |
// Note: if the device is paired, but your watch app is not installed | |
// consider prompting the user to install it for a better experience | |
#if os(iOS) | |
if let session = session, session.isPaired && session.isWatchAppInstalled { | |
return session | |
} | |
#elseif os(watchOS) | |
return session | |
#endif | |
return nil | |
} | |
func startSession() { | |
session?.delegate = self | |
session?.activate() | |
} | |
} | |
// MARK: Application Context | |
// use when your app needs only the latest information | |
// if the data was not sent, it will be replaced | |
extension WatchSessionManager { | |
// Sender | |
func updateApplicationContext(applicationContext: [String : AnyObject]) throws { | |
if let session = validSession { | |
do { | |
try session.updateApplicationContext(applicationContext) | |
} catch let error { | |
throw error | |
} | |
} | |
} | |
// Receiver | |
func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) { | |
// handle receiving application context | |
DispatchQueue.main.async { | |
// make sure to put on the main queue to update UI! | |
} | |
} | |
} | |
// MARK: User Info | |
// use when your app needs all the data | |
// FIFO queue | |
extension WatchSessionManager { | |
// Sender | |
func transferUserInfo(userInfo: [String : AnyObject]) -> WCSessionUserInfoTransfer? { | |
return validSession?.transferUserInfo(userInfo) | |
} | |
func session(_ session: WCSession, didFinish userInfoTransfer: WCSessionUserInfoTransfer, error: Error?) { | |
// implement this on the sender if you need to confirm that | |
// the user info did in fact transfer | |
} | |
// Receiver | |
func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any] = [:]) { | |
// handle receiving user info | |
DispatchQueue.main.async { | |
// make sure to put on the main queue to update UI! | |
} | |
} | |
} | |
// MARK: Transfer File | |
extension WatchSessionManager { | |
// Sender | |
func transferFile(file: NSURL, metadata: [String : AnyObject]) -> WCSessionFileTransfer? { | |
return validSession?.transferFile(file as URL, metadata: metadata) | |
} | |
func session(_ session: WCSession, didFinish fileTransfer: WCSessionFileTransfer, error: Error?) { | |
// handle filed transfer completion | |
} | |
// Receiver | |
func session(_ session: WCSession, didReceive file: WCSessionFile) { | |
// handle receiving file | |
DispatchQueue.main.async { | |
// make sure to put on the main queue to update UI! | |
} | |
} | |
} | |
// MARK: Interactive Messaging | |
extension WatchSessionManager { | |
// Live messaging! App has to be reachable | |
private var validReachableSession: WCSession? { | |
if let session = validSession , session.isReachable { | |
return session | |
} | |
return nil | |
} | |
// Sender | |
func sendMessage(message: [String : AnyObject], | |
replyHandler: (([String : Any]) -> Void)? = nil, | |
errorHandler: ((Error) -> Void)? = nil) | |
{ | |
validReachableSession?.sendMessage(message, replyHandler: replyHandler, errorHandler: errorHandler) | |
} | |
func sendMessageData(data: Data, | |
replyHandler: ((Data) -> Void)? = nil, | |
errorHandler: ((Error) -> Void)? = nil) | |
{ | |
validReachableSession?.sendMessageData(data, replyHandler: replyHandler, errorHandler: errorHandler) | |
} | |
// Receiver | |
func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) { | |
// handle receiving message | |
DispatchQueue.main.async { | |
// make sure to put on the main queue to update UI! | |
} | |
} | |
func session(_ session: WCSession, didReceiveMessageData messageData: Data) { | |
// handle receiving message data | |
DispatchQueue.main.async { | |
// make sure to put on the main queue to update UI! | |
} | |
} | |
} |
for receiver part in interactive messaging, should we write the code logic into singleton file ?
how we can implement the receiver part for both ios and watchOS? Is there any sample code ?
Perfect working
how we can implement the receiver part for both ios and watchOS? Is there any sample code ?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Handlers do not work.