3qnexx / nexxPLAY-iOS

nexxPLAY SDK for iOS
3 stars 2 forks source link

NexxPLAYView.startPlay(streamType:_, mediaID:_, configuration:_) breaks supportedInterfaceOrientations on iOS16 #18

Closed Heidi0039 closed 2 years ago

Heidi0039 commented 2 years ago

Hi,

in my AppDelegate class I have the following:

var orientationLock = UIInterfaceOrientationMask.portrait
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    return self.orientationLock
}

The general Idea is, to change the orientationLock variable at runtime to lock/unlock certain modes. The App is mostly used in PortraitMode. But when viewing an Image in Fullscreen the orientationLock variable gets set to All or Landscape.

Now with iOS16 I also have to call setNeedsUpdateOfSupportedInterfaceOrientations() on the RootViewController to have the desired effect.

As soon as I call the startPlay(streamType:_, mediaID:_, configuration:_) Method of my PlayView, the logic above no longer works.

It appears as if the func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) from then on always returns .portrait regardless of the value in orientationLock

Some pseudocode to show the desired/working behaviour:

// Unlock the orientation to support all InterfaceOrientations
AppDelegate.orientationLock = .all
vc.setNeedsUpdateOfSupportedInterfaceOrientations()
// Rotating the device to Landscape works, as expected
// Rotating the device back to Portrait works, as expected

// If we now lock the orientation to .portrait we can no longer view the App in Landscape mode
AppDelegate.orientationLock = .portrait
vc.setNeedsUpdateOfSupportedInterfaceOrientations()
// Rotating the device to Landscape does not work, as expected

However, when calling the startPlay method first, the pseudocode above no longer works:

NexxPLAYView.startPlay(streamType:_, mediaID:_, configuration:_)
AppDelegate.orientationLock = .all
vc.setNeedsUpdateOfSupportedInterfaceOrientations()
// Rotating the device to Landscape does not work!
DanielLeberle commented 2 years ago

Hi,

how do you add the player to your view hierarchy? Is it always fullscreen? Can you provide the NexxPLAYEnvironment and NexxPLAYConfiguration objects you initialise the player with?

Heidi0039 commented 2 years ago

The View is not always in fullscreen. The Interface ist mostly written using SwiftUI. In the View hierarchy is a ScrollView, which contains (among other Views) also my Custom PlayerView. This PlayerView is a UIViewControllerRepresentable.

fileprivate struct NexxVC: UIViewControllerRepresentable {
    private let viewController: NexxController

    init(data: VideoData, width: CGFloat, playerAction = PassthroughSubject<PlayerAction, Never>()) {
        self.viewController = NexxController(data: data, width: width, playerAction: playerAction)
    }

    func makeUIViewController(context: Context) -> NexxController {
        return self.viewController
    }

    func updateUIViewController(_ uiViewController: NexxController, context: Context) {}
}

The here referenced NexxController is a UIViewController, which on its viewDidLoad adds the frameworks NexxPlayView to its subViews.

The Env and Config are completely basic: NexxPLAYEnvironment(domain: VideoIDString) NexxPLAYConfiguration() In some instances the configurations disableAds gets set, which should be irrelevant here.

DanielLeberle commented 2 years ago

I had a deeper look into the code but the nexxPLAY SDK does not make any restrictions to orientations. The only thing regarding orientation in the SDK is that the player listens to OrientationDidChange notifications. But when the orientation changes the player only updates its own layout.

Is it possible for you to provide a minimal SwiftUI project where the issue appears?

Heidi0039 commented 2 years ago

I am unable to reproduce this in a clean Project. It seems that the Problem lies elsewhere.

Sorry for jumping to conclusions too quickly and opening this issue. However I am still unable to finde the root cause of my issue.

I'll look further into what happens when the Video is played. It appears to be related to this: https://developer.apple.com/forums/thread/713281

Edit: I found the issue. Now in iOS 16 the viewControllers setNeedsUpdateOfSupportedInterfaceOrientations needs to be called after changing the supportedInterfaceOrientations So far i did that using UIApplication.shared.windows?.first.rootViewController!.setNeedsUpdateOfSupportedInterfaceOrientations This worked until a Video was played. When playing a Video the .windows array gets changed, and setting the calling setNeedsUpdateOfSupportedInterfaceOrientations on the .first? window is no longer enough.

This made it seem like the Video was the cause for the problem. If instead of the first window i call setNeedsUpdateOfSupportedInterfaceOrientations on all windows the orientationChange works.

for w in UIApplication.shared.windows { w.rootViewController!.setNeedsUpdateOfSupportedInterfaceOrientations() }

This seems to be a Bug from Apple, but with this workaround everything works fine again. Feel free to close this issue!

DanielLeberle commented 2 years ago

ah perfect, glad you found a solution. I will close the issue and if there is a problem again just create a new one!