I have an iPhone app that presents information about a video playing on a kiosk-like device. The kiosk is running a python script that sends out video information via MQTT.
The iPhone uses CocoaMQTT
to listen for video information. When the information (title etc.) is received the app presents it modally in NowPlayingVC
with a segue from MenuVC
. When the video is finished, the kiosk sends a 'finished' message and NowPlayingVC
triggers an unwind segue to MenuVC
. This process works fine the first time through, but fails after the first time.
To handle the MQTT communication I am using a shared instance of a model called MQTTManager
that defines various protocol functions that are called in response to MQTT messages published by the kiosk. One of these functions is vhPlayingVideoInfoLoaded
and provides the information about the playing video sent from the kiosk (e.g. MQTT Manager
calls self.delegate?.vhPlayingVideoInfoLoaded!(description: String(descriptParts[1]), videoFile: String(descriptParts[0]))
)
After the first time through and the unwind segue MQTTManager
does what it's supposed to, but MenuVC
, the delegate of MQTTManager
, stops responding as the delegate -- it's as if the unwind segue has broken the delegation.
As an experiment, I replaced the unwind segue with a storyboard segue from NowPlayingVC
to MenuVC
and everything work exactly as it should the first time and after. The problem with that approach is that one ends up with a big memory-consuming stack of VCs that are confusing to the user.
Can anyone explain why the unwind segue is breaking the protocol/delegate? Is there a way to fix it? I'm happy to provide code, but I am guessing, being self-taught, that I am missing an obvious issue with my approach.
I have tired to refresh the delegate by putting mqtt.delegate=self
in various view functions, but that had no effect.
Any thoughts would be gratefully received, thanks. I'm using Xcode 13.3 and targeting iOS 13.
CodePudding user response:
Assuming:
- your "present
NowPlayingVC
modally" segue has an identifier of "didStart" - your unwind segue has an identifier of "unwind"
You would have code along these lines:
class MenuVC: UIViewController, MQTTDelegate {
let mqtt = MQTTObject.sharedInstance
override func viewDidLoad() {
super.viewDidLoad()
// set mqtt delegate to self
mqtt.delegate = self
}
// mqtt sends a "player started playing" to its delegate (which is self)
func didStart() {
performSegue(withIdentifier: "didStart", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? NowPlayingVC {
// set mqtt delegate to the segue destination controller
mqtt.delegate = vc
}
}
@IBAction func unwind( _ seg: UIStoryboardSegue) {
// set mqtt delegate to self again
mqtt.delegate = self
}
}
class NowPlayingVC: UIViewController, MQTTDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
// mqtt sends a "player finished playing" to its delegate (which is self)
func didFinish() {
performSegue(withIdentifier: "unwind", sender: self)
}
}