Yousef Abu Sallamah
Yousef Abu Sallamah

Reputation: 245

Passing data between interface controller in WatchKit

I have issue with implementing data passing between two WatchKit interface controllers. I want to pass data from first interface controller to another one. The first interface controller is working fine without any issue, but the second interface controller not getting the data from the first one.

Here is my struct :

struct gameStruct: Codable {
    var id: String
    var image: String
    var gameName: String
    var gameDate: String
    var gameVideo: String
    var gameSite: String   
}

Here is the code in first interface controller:

var gameWatchArray = [gameStruct]()
let getDataURL = "http://ya-techno.com/gameApp/gameData.php"

class InterfaceController: WKInterfaceController {
    @IBOutlet var tableView: WKInterfaceTable!

    override func awake(withContext context: Any?) {
        super.awake(withContext: context)

        let URLgame = URL(string: getDataURL)
        URLSession.shared.dataTask(with: URLgame!) { (data, response, error) in
            do {
                guard let data = data else { return }
                gameWatchArray = try JSONDecoder().decode([gameStruct].self, from: data)

            } catch {
                print("error parse")
            }
            DispatchQueue.main.async {
                self.tableView.setNumberOfRows(gameWatchArray.count, withRowType: "gameRow")

                for (gameNameIndex, game) in gameWatchArray.enumerated() {
                    let row = self.tableView.rowController(at: gameNameIndex) as! gameRow
                    let url  = NSURL(string: "http://www.ya-techno.com/gamesImage/\(game.image)")
                    guard let data = NSData(contentsOf: url! as URL) else { return }
                    row.gameImage.setImageData(data as Data)
                }
                for index in gameWatchArray {
                    index.gameName
                    index.gameDate
                    index.image
                    print("JSON V3 array is :\(index.gameName)")

                }
                print("JSON V3 array is :\(gameWatchArray.count)")

            }

            }.resume()
        }



    override func table(_ table: WKInterfaceTable, didSelectRowAt rowIndex: Int) {

        self.pushController(withName: "showDetails", context: gameWatchArray[rowIndex])
    }

and here is the Detail interface in my project:

override func awake(withContext context: Any?) {
    super.awake(withContext: context)

    if let detailData = context as? String {
        gameNameLabel.setText(detailData)
    }

}

I'm using json to parse data.

Upvotes: 0

Views: 1050

Answers (1)

David Pasztor
David Pasztor

Reputation: 54795

The issue is that you are passing a gameStruct instance using self.pushController(withName: "showDetails", context: gameWatchArray[rowIndex]) from your first interface controller to your second one, but then you are trying to cast gameStruct to String, which will obviously fail.

You should modify awake(withContext:) in your second interface controller to conditionally cast context to gameStruct and then access the gameName property of that struct when assigning the String name to the label's text.

In the future you should always handle the cases when a conditional casting fails so that you can find issues more easily by printing a message in case of a failed cast. Or if you are 100% sure that context will always be of a certain type, you can even do force casting, which will enable you to catch programming errors early on in the development stage.

override func awake(withContext context: Any?) {
    super.awake(withContext: context)

    if let gameDetails = context as? gameStruct {
        gameNameLabel.setText(gameDetails.gameName)
    } else {
        print("Passed context is not a gameStruct: \(context)")
    }
}

You should also conform to the Swift naming convention, which is UpperCamelCase for type names, so change gameStruct to GameStruct.

Upvotes: 3

Related Questions