iosswiftwatchoswatchconnectivity

((Any) throws -> Bool) throws -> Optional<Any>') cannot conform to 'BinaryInteger'


I am facing an issue trying to convert message from apple watch's WC session [String: Any] as I am customizing a sample project that retrieves heart rate from apple watch and send it to iPhone. I am hoping that I can get some help as I am already struggling with watchconnectivity for 3 days.

I do see that I am receiving the message properly from Apple Watch and I am close to utilize the message received to update heart rate at iOS app side. But I think the "guard let" statement is causing the didReceiveMessage function to stop half way.

I am not sure, but I think if I can "unwrap" the message ["rate": 61] into 61 in double format, I should be able to pass the guard let function and get this function working.

enter image description here

enter image description here

On top of that I am seeing another error saying "NO with WCErrorCodeDeliveryFailed", but I am not sure why this is being populated as I already implemented suggested solutions from other SO answers. But I think this error is redundant/unrelated to above error message.

enter image description here

Would appreciate help.

import Foundation
import WatchConnectivity

protocol WatchKitConnectionDelegate: AnyObject {
    func didFinishedActiveSession()
    func updateLatestHeartRate(_ LatestHeartRate: Double)
}

protocol WatchKitConnectionProtocol {
    func startSession()
    func sendMessage(message: [String : AnyObject], replyHandler: (([String : AnyObject]) -> Void)?, errorHandler: ((NSError) -> Void)?)
}

class WatchKitConnection: NSObject {
    static let shared = WatchKitConnection()
    weak var delegate: WatchKitConnectionDelegate?
    
    private override init() {
        super.init()
    }
    
    func sendHeartRate(rate: Int) {
        WCSession.default.sendMessage(["rate": rate], replyHandler: nil) { error in
            print("Failed to send message: \(error)")
        }

        print("from iOS watchkit connection")
    }

extension WatchKitConnection: WatchKitConnectionProtocol {
    func startSession() {
        session?.delegate = self
        session?.activate()
    }
    
    func sendMessage(message: [String : AnyObject],
                     replyHandler: (([String : AnyObject]) -> Void)? = nil,
                     errorHandler: ((NSError) -> Void)? = nil)
    
    {
        validReachableSession?.sendMessage(message, replyHandler: { (result) in
            print(result)
            print("success in phone sendmessage function")
        }, errorHandler: { (error) in
            print("error in phone sendmessage function")
            print(error)
        })
    }
    
}

extension WatchKitConnection: WCSessionDelegate {

func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
        print("didReceiveMessage from watch")
        print(message)
        
        delegate?.updateLatestHeartRate(Double(message.values.first))
        
        guard let heartRate = message.values.first as? String? else {
            return
        }
        guard let heartRateDouble = Double(heartRate!) else {
            return
        }
        
        print("printing heartRate double from message\(heartRateDouble)")
        
        delegate?.updateLatestHeartRate(heartRateDouble)
        
        print("updateLatestHeartRate")
      }

WatchKitConnection Swift file at iOS App


Solution

  • With help from @Rob in the comments, I was able to unwrap the message properly and remove unnecessary guard let statements to run my delegate function. Below is the updated piece of code.

    1. Changed message.values.first? as Int as the rate was in an integer format.
    2. Removed guard let statements in converting the heartRate into the double format, as it was non-optional.
    extension WatchKitConnection: WCSessionDelegate {
    
    func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
            print("didReceiveMessage from watch")
            print(message)
            
    //        delegate?.updateLatestHeartRate(Double(message.values.first))
            
            guard let heartRate = message.values.first as? Int else {
                return
            }
            
            let heartRateDouble = Double(heartRate)
            
            print("printing heartRate double from message\(heartRateDouble)")
            
            delegate?.updateLatestHeartRate(heartRateDouble)
            
            print("updateLatestHeartRate")
            
        }
    }