Reputation: 245
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
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