toshi0383 / TVMLKitchen

Swifty TVML template manager with or without client-server
MIT License
81 stars 12 forks source link

"UIMainStoryboardFile" setting conflicts with Kitchen #95

Closed toshi0383 closed 8 years ago

toshi0383 commented 8 years ago

Problem

If Info.plist's UIMainStoryboardFile is set, the app happen to have 2 UIWindows in parallel. Either one who is keyWindow gets focused.

Currently Kitchen holds its own UIWindow in private sharedKitchen instance, and uses it to create a TVApplicationController instance. See: https://github.com/toshi0383/TVMLKitchen/blob/swift2.2/Sources/Kitchen.swift#L264 Looks like this UIWindow conflicts with UIMainStoryboardFile's UIWindow.

Expected

The app have one UIWindow and Kitchen will share that instance. That's said, Views appears in same view hierarchy, not in parallel in different windows.

Possible solutions (Investigation Needed)

  1. Detect other UIWindow existence in prepare phase and yell out that something is wrong.
  2. Add capability to pass a specific UIWindow instance to Kitchen, so Kitchen can use it to instantiate a TVApplicationController in prepare phase. (Don't know if it works)
  3. Make Kitchen's UIWindow always on top. (Maybe configurable via windowLevel property?)
toshi0383 commented 8 years ago

Current behavior can be observed in this branch's SampleRecipe app.

toshi0383 commented 8 years ago

In this session in WWDC 2016, multi UIWindow solution is mentioned... https://developer.apple.com/videos/play/wwdc2016/212/ tvml-as-subapp

"Host the navigationController" is our current only solution.

I know we can do something like this to avoid conflicting window.

    var mainWindow: UIWindow {
        return (UIApplication.shared.delegate as! AppDelegate).window!
    }
    ...
    func presentTVML() {
        mainWindow.resignKey()
        mainWindow.isHidden = true
        Kitchen.window.makeKey()
        Kitchen.serve(xmlFile: "Foo.tvml")
    }

But I don't know what the trigger should be for going back to the mainWindow scene yet.

toshi0383 commented 8 years ago

But I don't know what the trigger should be for going back to the mainWindow scene yet.

Looks like UINavigationConrollerDelegate can answer this question.

    // AppDelegate.swift
        // push empty viewcontroller at index 0 after `prepare`.
        _ = Kitchen.prepare(cookbook)
        Kitchen.navigationController.pushViewController(UIViewController(), animated: false)
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        print(viewController)
        if viewController == Kitchen.navigationController.viewControllers[0] {
            Kitchen.window.resignKey()
            mainWindow.isHidden = false
            mainWindow.makeKey()
        }
    }
toshi0383 commented 8 years ago

So here is another solution. Support multiple window! #98 Just supports Kitchen.serve(urlString:...) for now.