Swift에서 사용하기
Swift 런타임은 Swift로 작성되어 있으며 WKWebView의 웹 메시지를 받아 request/command handler를 실행하고 event를 웹으로 보냅니다. TypeScript는 contract 분석과 Swift 코드 생성에만 사용됩니다.
설치
저장소 루트의 Package.swift를 Swift Package로 추가합니다. 개발 중에는 Xcode의 Add Local Package로 이 저장소를 선택할 수 있고, 릴리스 태그 이후에는 저장소 URL을 Swift Package dependency로 사용합니다.
contract가 있는 프로젝트에서 Swift 코드를 생성해 iOS target에 포함하세요.
npx webview-bridge-kit-gen \
--contract ./bridge-contract.ts \
--lang swift \
--out ./ios/BridgeTypes.swift생성 파일은 Codable DTO, BridgeHandlers protocol, NativeBridge.bind, 타입 안전한 event 함수를 포함합니다.
WKWebView 연결
import UIKit
import WebKit
import WebViewBridgeKit
final class AppBridgeHandlers: BridgeHandlers {
func kakaoLogin() async throws -> KakaoLoginResponse {
KakaoLoginResponse(accessToken: try await login(), expiresIn: nil, nickname: nil)
}
func sendLogs(_ payload: SendLogsPayload) async throws {
logger.write(payload.lines)
}
func openCamera() async throws {
// 화면 전환
}
}
@MainActor
final class WebViewController: UIViewController {
private let webView = WKWebView()
private var bridge: NativeBridge?
override func viewDidLoad() {
super.viewDidLoad()
let transport = WKWebViewTransport(webView: webView)
let bridge = NativeBridge(transport: transport)
bridge.bind(AppBridgeHandlers())
self.bridge = bridge
}
func photoTaken(_ payload: PhotoTakenPayload) throws {
try bridge?.emitPhotoTaken(payload)
}
deinit {
bridge?.dispose()
}
}NativeBridge를 화면 수명 동안 강하게 보관해야 합니다. dispose()는 script message handler를 제거하고 등록된 handler를 해제합니다.
웹 쪽 기본 transport는 window.webkit.messageHandlers.webviewBridgeKit을 자동 감지하므로 별도 JavaScript shim이 필요하지 않습니다. 다른 handler 이름을 쓰면 웹에 custom Transport를 전달해야 합니다.
오류 처리
- 등록되지 않은 request는
UNKNOWN_MESSAGEresponse를 반환합니다. - payload가 생성된
Decodable타입과 다르면VALIDATION_FAILED를 반환합니다. - handler가
BridgeHandlerError를 던지면 지정한 code/message를 반환합니다. - 그 밖의 오류는
HANDLER_ERROR로 반환합니다.
신뢰하는 콘텐츠만 로드하세요
네이티브 기능을 노출하는 WebView에는 앱이 관리하는 HTTPS origin이나 번들 콘텐츠만 로드하세요. 외부 페이지를 같은 WebView에 열지 않는 것이 안전합니다.