/Local Pods/GitHubSession/GitHubSession/WatchAppUserSessionSync.swift

https://github.com/GitHawkApp/GitHawk · Swift · 103 lines · 72 code · 18 blank · 13 comment · 18 complexity · cb3291ed464adfbb98d079d76785aa60 MD5 · raw file

  1. //
  2. // WatchAppUserSessionSync.swift
  3. // FreetimeWatch Extension
  4. //
  5. // Created by Ryan Nystrom on 4/28/18.
  6. // Copyright © 2018 Ryan Nystrom. All rights reserved.
  7. //
  8. import Foundation
  9. import WatchConnectivity
  10. import GitHubSession
  11. public protocol WatchAppUserSessionSyncDelegate: class {
  12. func sync(_ sync: WatchAppUserSessionSync, didReceive userSession: GitHubUserSession)
  13. }
  14. public class WatchAppUserSessionSync: NSObject, WCSessionDelegate {
  15. public weak var delegate: WatchAppUserSessionSyncDelegate?
  16. private let userSession: GitHubUserSession?
  17. private let session: WCSession
  18. private let key = "com.freetime.watchappsync.usersession"
  19. public init?(userSession: GitHubUserSession? = nil) {
  20. guard WCSession.isSupported() else { return nil }
  21. self.session = WCSession.default
  22. self.userSession = userSession
  23. }
  24. public func start() {
  25. session.delegate = self
  26. session.activate()
  27. }
  28. public var lastSyncedUserSession: GitHubUserSession? {
  29. guard let data = UserDefaults.standard.value(forKey: key) as? Data else { return nil }
  30. return NSKeyedUnarchiver.unarchiveObject(with: data) as? GitHubUserSession
  31. }
  32. // https://forums.developer.apple.com/thread/11658
  33. public func sync(userSession: GitHubUserSession) {
  34. guard let session = validSession else { return }
  35. for transfer in session.outstandingUserInfoTransfers ?? [] {
  36. if transfer.userInfo[key] != nil {
  37. transfer.cancel()
  38. }
  39. }
  40. let data = NSKeyedArchiver.archivedData(withRootObject: userSession)
  41. session.transferUserInfo([key: data])
  42. }
  43. // MARK: Private API
  44. // https://www.natashatherobot.com/watchconnectivity-user-info/
  45. private var validSession: WCSession? {
  46. #if !os(watchOS)
  47. guard session.isPaired && session.isWatchAppInstalled else {
  48. return nil
  49. }
  50. #endif
  51. return session
  52. }
  53. // MARK: WCSessionDelegate
  54. public func session(
  55. _ session: WCSession,
  56. activationDidCompleteWith activationState: WCSessionActivationState,
  57. error: Error?
  58. ) {
  59. if let error = error {
  60. print(error)
  61. }
  62. // don't auto sync if on watchOS
  63. #if !os(watchOS)
  64. if let userSession = self.userSession {
  65. sync(userSession: userSession)
  66. }
  67. #endif
  68. }
  69. #if !os(watchOS)
  70. public func sessionDidBecomeInactive(_ session: WCSession) {}
  71. public func sessionDidDeactivate(_ session: WCSession) {}
  72. #endif
  73. // will only run on the watch
  74. public func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any] = [:]) {
  75. if let data = userInfo[key] as? Data,
  76. let userSession = NSKeyedUnarchiver.unarchiveObject(with: data) as? GitHubUserSession {
  77. UserDefaults.standard.set(data, forKey: key)
  78. UserDefaults.standard.synchronize()
  79. DispatchQueue.main.async { [weak self] in
  80. guard let strongSelf = self else { return }
  81. strongSelf.delegate?.sync(strongSelf, didReceive: userSession)
  82. }
  83. }
  84. }
  85. }