opentok / opentok-ios-sdk-samples

Example applications that use the OpenTok iOS SDK
https://tokbox.com/developer/sdks/ios
MIT License
200 stars 117 forks source link

OTSubscriberKitNetworkStatsDelegate and OTSubscriberKitRtcStatsReportDelegate Methods are not called #261

Open dbagwell opened 2 years ago

dbagwell commented 2 years ago

Issue

OTSubscriberKitNetworkStatsDelegate and OTSubscriberKitRtcStatsReportDelegate Methods are not called unless the subscriber's delegate (OTSubscriberKitDelegate) conforms to the protocol and implements the method. This is fine if the fine if the subscriber's networkStatsDelegate and rtcStatsReportDelegate are the same object as the delegate, but can fail if they are different objects.

A crash can also occur if the delegate does conform to the stats delegate protocols and implements the methods, but the actual networkStatsDelegate and rtcStatsReportDelegate do not implement the methods.

Steps to Reproduce

class SubscriberDelegate: NSObject,
    OTSubscriberKitDelegate,
    OTSubscriberKitNetworkStatsDelegate,
    OTSubscriberKitRtcStatsReportDelegate
{
    ...

    // Uncomment theses lines to get the StatsDelegate to work.
    // func subscriber(_ subscriber: OTSubscriberKit, videoNetworkStatsUpdated stats: OTSubscriberKitVideoNetworkStats) {}
    // func subscriber(_ subscriber: OTSubscriberKit, audioNetworkStatsUpdated stats: OTSubscriberKitAudioNetworkStats) {}
    // func subscriber(_ subscriber: OTSubscriberKit, rtcStatsReport jsonArrayOfReports: String) {}

    ...

}
class StatsDelegate: NSObject,
    OTSubscriberKitNetworkStatsDelegate,
    OTSubscriberKitRtcStatsReportDelegate
{
    // Comment out these methods and uncomment the methods above to observe a crash.
    func subscriber(_ subscriber: OTSubscriberKit, videoNetworkStatsUpdated stats: OTSubscriberKitVideoNetworkStats) {
        print("subscriber video stats")
    }

    func subscriber(_ subscriber: OTSubscriberKit, audioNetworkStatsUpdated stats: OTSubscriberKitAudioNetworkStats) {
        print("subscriber audio stats")
    }

    func subscriber(_ subscriber: OTSubscriberKit, rtcStatsReport jsonArrayOfReports: String) {
        print("subscriber rtc stats")
    }
}
class SessionDelegate: NSObject,
    OTSessionDelegate
{

    ...

    let subscriberDelegate = SubscriberDelegate()
    let statsDelegate = StatsDelegate()

    func session(_ session: OTSession, streamCreated stream: OTStream) {
        guard let subscriber = OTSubscriber(stream: stream) else { return }
        subscriber.delegate = self.subscriberDelegate
        subscriber.networkStatsDelegate = self.statsDelegate
        subscriber.rtcStatsReportDelegate = self.statsDelegate
        DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1), execute: {
            subscriber.getRtcStatsReport()
        })
    }

    ...

}

Solution

I don't have access to the source code, but I am guessing that the reason this happens is because when deciding whether or not to call the stats delegate methods, there is a guard incorrectly checking to see if the subscriber's delegate conforms to the protocol and implements the method, this should be changed to check the networkStatsDelegate/rtcStatsReportDelegate as appropriate.

v-kpheng commented 2 years ago

Thanks, @dbagwell, for letting us know about this. We'll investigate: https://jira.vonage.com/browse/OPENTOK-49082.

Will keep you posted.