Search code examples
iosswiftwatchkitwatchos-2watchconnectivity

How to send Array to Watch using sendMessage | Error: Could not cast value of type '__NSCFArray' to 'NSString'


I am using WatchConnectivity to send an array of string values from the iPhone to the Watch, but when doing so I get the following error.

Could not cast value of type '__NSCFArray' (0x591244) to 'NSString' (0x9f7458).

I have been having some slight trouble sending an array of strings within a dictionary to the watch and then saving the array to use in a WKInterfaceTable.

Does anybody know where I am going wrong and how I can display the array on the watch ?

iPhone

After receiving the first message from the watch to send the data the iPhones didRecieveMessage does the following.

There is an array called objectsArray and each object has a string property called title. I create a new array for all the title values and use the array in a dictionary to send to the watch.

func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {

  var watchArray = [""]

  for object in self.objectsArray {
     watchArray.append(object.title)
  }

  print("Received message from watch and sent array. \(watchArray)")
  //send a reply
  replyHandler( [ "Value" : [watchArray] ] )

}

Watch

var objectTitlesArray = ["String"]


//Display Array in WKInterfaceTable

func loadTableData() {
    table.setNumberOfRows(self.tasks.count, withRowType: "CellRow")
    if self.tasks.count > 0 {
        for (index, objectTitle) in self.objectTitlesArray.enumerate() {
            let row = self.table.rowControllerAtIndex(index) as! CellRowController
            row.tableCellLabel.setText(objectTitle)
        }
     }
}  


//Saving the Array

func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {

    let value = message["Value"] as! [String]

    dispatch_async(dispatch_get_main_queue()) {
        self.objectTitlesArray = value
        print("Received Array and refresh table")
        loadTableData()
    }

    //send a reply
    replyHandler(["Value":"Yes"])

}  

UPDATE

The error mentioned seems to have something to do with the refresh action when setting label text to value. However after commenting the lines out, the array still seems to not be displaying in the WKInterfaceTable and none of the print statements are outputted to the console.


Solution

  • The sendMessage method should handle the reply from the phone. And their is no reason to use a didRecieveMessage method on the watch if the iPhone does not use a sendMessage method.

    @IBAction func fetchData() {
    
        let messageToSend = ["Value":"Hello iPhone"]
        session.sendMessage(messageToSend, replyHandler: { replyMessage in
    
            if let value = replyMessage["Value"] {
                    self.objectTitlesArray = value as! [String]
                    self.loadTableData()
            }
    
            }, errorHandler: {error in
                // catch any errors here
                print(error)
        })
    
    }