func updateApplicationContext([String : Any])
的传输
这个方法的传输会对数据进行优化,连续发送相同的数据,后发的不会被传输。
正如这个函数的名称那样,这个函数用于发送程序状态的信息,如果有多个状态,那么连续发送相同的,只有第一个会被发送。
与WKWatchConnectivityRefreshBackgroundTask的关系
- When transferring data between iOS and watchOS, there must be an
activated WCSession
in the sending app. That is the first condition to check before sending data. - For
sendMessage(_:replyHandler:errorHandler:)
andsendMessageData(_:replyHandler:errorHandler:)
, it is needed to checkisReachable
to be true as well. - For a watchOS app sending data to iOS, you need to check
iOSDeviceNeedsUnlockAfterRebootForReachability
for if the iOS device needs to unlock after rebooting. - For an iOS app sending data to watchOS, you may also check
isPaired
andisWatchAppInstalled
before sending any data.
// iOS app
class AppDelegate: UIResponder, UIApplicationDelegate, WCSessionDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
if WCSession.isSupported() {
let session = WCSession.default()
session.delegate = self
session.activate()
}
return true
}
extension AppDelegate:WCSessionDelegate {
public func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
guard error == nil else { fatalError(error!.localizedDescription) }
}
}
// view controller
class ViewController: UIViewController {
@IBAction func sendButtonClicked(_ sender: Any) {
if WCSession.isSupported() {
let session = WCSession.default()
if session.activationState == .activated {
if session.isWatchAppInstalled && session.isPaired {
session.transferUserInfo(["send test":nil])
}
}
}
}
}
// watchOS app
class ExtensionDelegate: NSObject, WKExtensionDelegate {
func applicationDidFinishLaunching() {
// Perform any final initialization of your application.
let session = WCSession.default()
session.delegate = self
session.activate()
}
func applicationDidBecomeActive() {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillResignActive() {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, etc.
}
var total = 0
func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {
// Sent when the system needs to launch the application in the background to process tasks. Tasks arrive in a set, so loop through and process each one.
for task in backgroundTasks {
// Use a switch statement to check the task type
switch task {
case let backgroundTask as WKApplicationRefreshBackgroundTask:
// Be sure to complete the background task once you’re done.
backgroundTask.setTaskCompleted()
case let snapshotTask as WKSnapshotRefreshBackgroundTask:
// Snapshot tasks have a unique completion call, make sure to set your expiration date
snapshotTask.setTaskCompleted(restoredDefaultState: true, estimatedSnapshotExpiration: Date.distantFuture, userInfo: nil)
case let connectivityTask as WKWatchConnectivityRefreshBackgroundTask:
// Be sure to complete the connectivity task once you’re done.
total += 1
DispatchQueue.main.async {
if let viewController = WKExtension.shared().rootInterfaceController as? InterfaceController {
viewController.activeBurnedEnergyLabel.setText(String(self.total))
}
}
connectivityTask.setTaskCompleted()
case let urlSessionTask as WKURLSessionRefreshBackgroundTask:
// Be sure to complete the URL session task once you’re done.
urlSessionTask.setTaskCompleted()
default:
// make sure to complete unhandled task types
task.setTaskCompleted()
}
}
}
}
extension ExtensionDelegate: WCSessionDelegate {
public func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
guard error == nil else { fatalError(error!.localizedDescription) }
}
/** -------------------------- Background Transfers ------------------------- */
public func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any] = [:]) {
total += 4
DispatchQueue.main.async {
if let viewController = WKExtension.shared().rootInterfaceController as? InterfaceController {
viewController.activeBurnedEnergyLabel.setText(String(self.total))
}
}
}
}