Using WCSession with more than one ViewController

后端 未结 4 911
栀梦
栀梦 2020-12-06 07:19

I found many questions and many answers but no final example for the request:

Can anyone give a final example in Objective C what is best practice t

4条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-06 07:24

    Well, this is simplified version of my solution as requested by Greg Robertson. Sorry it's not in Objective-C anymore; I'm just copy-pasting from existing AppStore-approved project to make sure there will be no mistakes.

    Essentially, any WatchDataProviderDelegate can hook to data provider class as that provides array holder for delegates (instead of one weak var). Incoming WCSessionData are forwarded to all delegates using the notifyDelegates() method.

    // MARK: - Data Provider Class
    
    class WatchDataProvider: WCSessionDelegate {
    
        // This class is singleton
        static let sharedInstance = WatchDataProvider()
    
        // Sub-Delegates we'll forward to
        var delegates = [AnyObject]()
    
        init() {
            if WCSession.isSupported() {
                WCSession.defaultSession().delegate = self
                WCSession.defaultSession().activateSession()
                WatchDataProvider.activated = true;
            }
        }
    
        // MARK: - WCSessionDelegate                
    
        public func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) {
            processIncomingMessage(userInfo)
        }
    
        public func session(session: WCSession, didReceiveApplicationContext applicationContext: [String: AnyObject]) {
            processIncomingMessage(applicationContext)
        }
    
        func processIncomingMessage(dictionary: [String:AnyObject] ) {
            // do something with incoming data<
            notifyDelegates()
        }
    
        // MARK: - QLWatchDataProviderDelegate     
    
       public func addDelegate(delegate: AnyObject) {
           if !(delegates as NSArray).containsObject(delegate) {
               delegates.append(delegate)
           }
       }
    
       public func removeDelegate(delegate: AnyObject) {
           if (delegates as NSArray).containsObject(delegate) {
               delegates.removeAtIndex((delegates as NSArray).indexOfObject(delegate))
           }
       }
    
       func notifyDelegates()
       {
           for delegate in delegates {
               if delegate.respondsToSelector("watchDataDidUpdate") {
                   let validDelegate = delegate as! WatchDataProviderDelegate
                   validDelegate.watchDataDidUpdate()
               }
           }
       }    
    }
    
    
    // MARK: - Watch Glance (or any view controller) listening for changes
    
    class GlanceController: WKInterfaceController, WatchDataProviderDelegate {
    
        // A var in Swift is strong by default
        var dataProvider = WatchDataProvider.sharedInstance()
        // Obj-C would be: @property (nonatomic, string) WatchDataProvider *dataProvider
    
        override func awakeWithContext(context: AnyObject?) {
            super.awakeWithContext(context)
            dataProvider.addDelegate(self)
        }
    
        // WatchDataProviderDelegate
        func watchDataDidUpdate() {
            dispatch_async(dispatch_get_main_queue(), {
                // update UI on main thread
            })
        }}
    }
    
    class AnyOtherClass: UIViewController, WatchDataProviderDelegate {
    
        func viewDidLoad() {
            WatchDataProvider.sharedInstance().addDelegate(self)
        }
    
        // WatchDataProviderDelegate
        func watchDataDidUpdate() {
            dispatch_async(dispatch_get_main_queue(), {
                // update UI on main thread
            })
        }}
    }
    

提交回复
热议问题