Xcode11에서 프로젝트를 생성하면 iOS13 이후에서 사용할 수 있는 타입을 사용하기 때문에 iOS 13 이전 버전에서도 동작하는 앱을 작성하려면 약간의 조작을 해야 한다.

 

Xcode11에서 프로젝트를 생성하는 과정에서 스토리보드와 SwiftUI 선택할 수 있다. SwiftUI는 iOS 13 이후부터 사용할 수 있으므로 스토리보드를 선택한다.

 

SwiftUI와 Storyboard 중 선택

 

프로젝트를 생성하고 Deployment info에서 동작 버전을 설정할 수 있다.

 

최소 동작 버전 설정하기

최소 동작 버전을 iOS13 이전으로 낮추면 다음과 같은 에러가 발생한다.

 

버전 에러

 

UIScene, UISceneDelegate 등이 iOS13에 추가된 타입이다 보니 에러가 발생한다. @available 를 사용하라는 권고?가 있지만 다 지워버리도록 하자!

 

프로젝트 내비게이터에서 SceneDelegate.swift 파일 삭제

 

AppDelegate.swift 를 다음과 같이 편집한다.

 

- UIScene에 관련된 코드 제거

- window 프로퍼티 추가

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    // 추가!
    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        return true
    }
    
    // 아래 제거
    // MARK: UISceneSession Lifecycle
}

 

Info.plist 에서 Scene에 관련된 항목을 삭제한다.

이제 iOS13 이전 버전에서도 에러 없이 동작한다.

 

과거 버전의 시뮬레이터를 설치하려면 Xcode의 Preferences의 Components 메뉴에서 필요한 버전의 시뮬레이터를 다운로드한다.

 

시뮬레이터 다운로드

시뮬레이터 다운로드를 마치면 Window -> Devices and Simulators 에서 다운로드한 버전에 맞춰서 시뮬레이터 설치한다.

특정 버전의 시뮬레이터 추가하기

 

이제 iOS13 이전 버전에서도 동작한다.

반응형

웹킷의 웹뷰에서 window.webkit.messageHandlers를 이용하면 네이티브 영역(Swift 코드 부분)으로 메세지를 전달할 수 있다.

 

WKUserContentController 를 이용해서 메세지의 이름과 메세지가 전달될 때의 처리할 대상(self)를 등록해야 한다. 다음과 같이 작성하면 될 줄 알았다.....

let contentController = WKUserContentController()
contentController.add(self, name: "hello")
webView.configuration.userContentController = contentController

웹뷰에서 webkit.messageHandlers를 통해서 보내는 메세지는 다음과 같이 작성한 메소드에 메세지 이름과 메세지의 바디 부분을 얻을 수 있다.

extension ViewController: WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "hello", let messageBody = message.body as? String {
            print("Hello Message body :", messageBody)
        }
    }
}

다음은 웹뷰에서 webkit.messageHandlers로 메세지를 전달하는 코드다.

window.webkit.messageHandlers.hello.postMessage('Hello WebKit');

코드는 상당히 간단한 편인데 생각대로 동작하지 않았다.

원인을 찾다보니 웹뷰에서 webkit의 값이 undefined이고 그래서 메세지 전달이 안되고 있었다. 다음 그림은 사파리로 웹뷰 콘솔을 확인하는 모습이다. (사파리 -> 개발자용 -> 시뮬레이터 -> Document)

문제가 된 부분은 다음 코드였다.

let contentController = WKUserContentController()
contentController.add(self, name: "hello")
webView.configuration.userContentController = contentController

웹뷰의 configuration.userContentController 와 contentController가 서로 다른 객체였기 때문에 메세지와 메세지 핸들러가 등록되지 않았다. 대충 이러면 되겠지~ 하는 생각으로 코드를 짜다가 몇 시간이나 날린건지..

 

웹뷰의 configuration 객체에는 userContentController가 기본 생성되어 있기 때문에 다음과 같이 작성하면 된다.

let contentController = webView.configuration.userContentController
contentController.add(self, name: "hello")

 

반응형

+ Recent posts