Upgrade to Pro — share decks privately, control downloads, hide ads and more …

既存アプリをiPadOSで複数Window対応/multi_windows_on_ipados

fromkk
June 28, 2019

 既存アプリをiPadOSで複数Window対応/multi_windows_on_ipados

令和最初のDeveloper's Living 〜WWDC2019〜( https://lifull.connpass.com/event/135446/ )というイベントで登壇してきた内容です。
iPadOSで複数ウィンドウに対応する方法を発表しました。

fromkk

June 28, 2019
Tweet

More Decks by fromkk

Other Decks in Programming

Transcript

  1. طଘΞϓϦΛJ1BE04Ͱෳ਺8JOEPXରԠ
    *OUSPEVDJOH.VMUJQMF8JOEPXTPOJ1BE

    4FTTJPO
    ྩ࿨࠷ॳͷ%FWFMPQFST-JWJOHʙ88%$ʙ

    View full-size slide

  2. 1SPpMF
    struct Profile {
    let name = "Kazuya Ueoka"
    let twitter = "@fromkk"
    let github = "fromkk"
    let qiita = "fromkk"
    let company = "Timers Inc."
    }

    View full-size slide

  3. IUUQTEFWFMPQFSBQQMFDPNWJEFPTQMBZXXEDΑΓҾ༻

    View full-size slide

  4. IUUQTEFWFMPQFSBQQMFDPNWJEFPTQMBZXXEDΑΓҾ༻

    View full-size slide

  5. IUUQTEFWFMPQFSBQQMFDPNWJEFPTQMBZXXED

    View full-size slide

  6. )PXUPJNQMFNFOUT

    View full-size slide

  7. ࠷ॳʹνΣοΫΛೖΕΔ
    ☑4VQQPSUTNVMUJQMFXJOEPXT
    IUUQTEFWFMPQFSBQQMFDPNWJEFPTQMBZXXEDΑΓҾ༻

    View full-size slide

  8. *OGPQMJTU
    UIApplicationSceneManifest

    UISceneConfigurations

    UIWindowSceneSessionRoleApplication


    UISceneDelegateClassName
    $(PRODUCT_MODULE_NAME).SceneDelegate
    UISceneConfigurationName
    Default Configuration
    UILaunchStoryboardName
    LaunchScreen.storyboard



    UIApplicationSupportsMultipleScenes


    View full-size slide

  9. "QQ%FMFHBUFʹ௥ه
    @available (iOS 13.0, *)
    func application(_ application: UIApplication,
    configurationForConnecting connectingSceneSession: UISceneSession,
    options: UIScene.ConnectionOptions) -> UISceneConfiguration {
    return UISceneConfiguration(name: "Default Configuration”,
    sessionRole: connectingSceneSession.role)
    }
    ˞OBNF͸*OGPQMJTUʹهड़ͨ͠6*4DFOF$POpHVSBUJPO/BNFͱ߹ΘͤΔ

    View full-size slide

  10. 4DFOF%FMFHBUF
    import UIKit
    @available(iOS 13.0, *)
    final class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?
    func scene(_ scene: UIScene,
    willConnectTo _: UISceneSession,
    options _: UIScene.ConnectionOptions) {
    let rootViewController = RootViewController()
    let window = UIWindow(windowScene: scene as! UIWindowScene)
    window.rootViewController = rootViewController
    window.backgroundColor = .systemBackground
    window.makeKeyAndVisible()
    self.window = window
    }
    }

    View full-size slide

  11. .JHSBUJPO
    IUUQTEFWFMPQFSBQQMFDPNWJEFPTQMBZXXEDΑΓҾ༻

    View full-size slide

  12. ΢Οϯυ΢ͷૢ࡞
    IUUQTEFWFMPQFSBQQMFDPNWJEFPTQMBZXXEDΑΓҾ༻

    View full-size slide

  13. ஫ҙ఺
    w MFUXJOEPX6*8JOEPX XJOEPX4DFOFTDFOFBT6*8JOEPX4DFOF
    PS

    XJOEPXXJOEPX4DFOFTDFOFBT 6*8JOEPX4DFOF͠ͳ͍ͱը໘͕ਅͬ
    ࠇʹͳΔ
    w ಉ͡σʔλΛࢀর͍ͯ͠Δ৔߹ʹίϯϑϦΫτ͢Δࣄ͕͋ΔͷͰ஫ҙ͕ඞཁ
    w ,70ͳͲΛ׆༻


    View full-size slide

  14. ஫ҙ఺
    IUUQTEFWFMPQFSBQQMFDPNWJEFPTQMBZXXEDΑΓҾ༻
    w MFUXJOEPX6*8JOEPX XJOEPX4DFOFTDFOFBT6*8JOEPX4DFOF
    PS

    XJOEPXXJOEPX4DFOFTDFOFBT 6*8JOEPX4DFOF͠ͳ͍ͱը໘͕ਅͬ
    ࠇʹͳΔ
    w ಉ͡σʔλΛࢀর͍ͯ͠Δ৔߹ʹίϯϑϦΫτ͢Δࣄ͕͋ΔͷͰ஫ҙ͕ඞཁ
    w ,70ͳͲΛ׆༻


    View full-size slide

  15. J04ҎԼΛ౿·࣮͑ͨ૷ͷߟ͑ํ
    w 4VQQPSUTNVMUJQMFXJOEPXTʹνΣοΫΛೖΕΔ
    w దٓ*OGPQMJTUΛमਖ਼
    w 4DFOF%FMFHBUFTXJGUΛ࡞੒ˍ"QQ%FMFHBUFʹϝιου௥Ճ
    !BWBJMBCMF J04


    w "QQ%FMFHBUFTXJGUͱॲཧΛڞ௨Խ Ұ౓͔͠ݺ͹Εͨ͘ͳ͍΋ͷͳͲʹ
    ஫ҙ͕ඞཁ

    w ෳ਺8JOEPXಠࣗͷػೳͳͲΛ࣮૷͍ͯ͘͠

    View full-size slide

  16. ڞ௨Ϋϥεͷྫ
    import UIKit
    final class AppEventHandler {
    @available(iOS 13.0, *)
    func createWindow(with windowScene: UIWindowScene) -> UIWindow {
    let window = UIWindow(windowScene: windowScene)
    window.backgroundColor = UIColor.systemBackground
    configureRootViewController(for: window)
    return window
    }
    func createWindow() -> UIWindow {
    let window = UIWindow(frame: UIScreen.main.bounds)
    window.backgroundColor = .white
    configureRootViewController(for: window)
    return window
    }
    private func configureRootViewController(for window: UIWindow) {
    window.rootViewController = UIViewController()
    }
    func willEnterForeground() {}
    func didBecomeActive() {}
    func willResignActive() {}
    func didEnterBackground() {}
    }

    View full-size slide

  17. 4DFOF%FMFHBUFͷྫ
    import UIKit
    @available(iOS 13.0, *)
    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?
    lazy var appEventHandler = AppEventHandler()
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    if let windowScene = scene as? UIWindowScene {
    window = appEventHandler.createWindow(with: windowScene)
    window?.makeKeyAndVisible()
    }
    }
    func sceneDidDisconnect(_ scene: UIScene) {}
    func sceneDidBecomeActive(_ scene: UIScene) {
    appEventHandler.didBecomeActive()
    }
    func sceneWillResignActive(_ scene: UIScene) {
    appEventHandler.willResignActive()
    }
    func sceneWillEnterForeground(_ scene: UIScene) {
    appEventHandler.willEnterForeground()
    }
    func sceneDidEnterBackground(_ scene: UIScene) {
    appEventHandler.didEnterBackground()
    }
    }

    View full-size slide

  18. "QQ%FMFHBUFͷྫ
    import UIKit
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    lazy var appEventHandler = AppEventHandler()
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    if #available(iOS 13.0, *) {} else {
    window = appEventHandler.createWindow()
    window?.makeKeyAndVisible()
    }
    return true
    }
    func applicationWillTerminate(_ application: UIApplication) {}
    func applicationWillEnterForeground(_ application: UIApplication) {
    if #available(iOS 13.0, *) {} else {
    appEventHandler.willEnterForeground()
    }
    }
    func applicationDidBecomeActive(_ application: UIApplication) {
    if #available(iOS 13.0, *) {} else {
    appEventHandler.didBecomeActive()
    }
    }
    func applicationWillResignActive(_ application: UIApplication) {
    if #available(iOS 13.0, *) {} else {
    appEventHandler.willResignActive()
    }
    }
    func applicationDidEnterBackground(_ application: UIApplication) {
    if #available(iOS 13.0, *) {} else {
    appEventHandler.didEnterBackground()
    }
    }
    // MARK: UISceneSession Lifecycle
    @available(iOS 13.0, *)
    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
    return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }
    @available(iOS 13.0, *)
    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {}
    }

    View full-size slide

  19. ·ͱΊ
    w 6*8JOEPX4DFOF4DFOF%FMFHBUFͱ͍͏৽͍֓͠೦͕ग़དྷͨ
    w ಉ͡ΞϓϦ͕ෳ਺ىಈग़དྷΔͷ͸ָ͍͕͠σʔλͷ؅ཧ͕େม
    w ͨ͘͞Μςετ͠Α͏$
    w ೥݄·Ͱʹ͸ରԠ͕ඞཁͳͷͰૣΊʹ४උ

    View full-size slide

  20. • αʔόʔαΠυΤϯδχΞ (PHP, Golang, AWS)
    • AndroidΤϯδχΞ (Kotlin)
    • iOSΤϯδχΞ (Swift)
    TimersͰ͸ݱࡏΤϯδχΞશ৬छ࠾༻தʂ

    ৄ͘͠͸”Timers”Ͱݕࡧ

    View full-size slide

  21. 5IBOLZPV&
    ϕʔλ൛ͷ಺༰ʹ͸มߋ͕ՃΘΔՄೳੑ͕͋Γ·͢ɻ

    ਖ਼֬ੑͷ୲อ͸ग़དྷͳ͍ࢫΛྃ͝ঝ͍ͩ͘͞ɻ

    View full-size slide