스펜서 개발블로그

[iOS/Swift] 웹앱 JS to iOS 브릿지 통신 (WKWebView, javascript Interface) 본문

iOS/Swift

[iOS/Swift] 웹앱 JS to iOS 브릿지 통신 (WKWebView, javascript Interface)

스펜서 2023. 4. 6. 21:09

 

웹앱은 유지보수가 쉽고 하나의 웹을 구축하여 Android와 iOS 환경 모두에서 사용할 수 있다는 장점이 있습니다.

그래서 최근 웹앱과 네이티브 언어(Kotlin, Swift, Java, 등)를 활용한 하이브리드앱을 많이 볼 수 있는것 같습니다.

 

 

우선 웹 환경에서 자바스크립트를 활용하여 네이티브(iOS) 파트를 호출하고 이를 활용하여 코드를 작성하는 법을 보겠습니다.

 

	
    // 1. 디바이스 구분하기
    const userAgent = navigator.userAgent;			// 실행하는 디바이스 정보
	const android = userAgent.match(/Android/i);	// 안드로이드 포함 여부 확인
	const iphone = userAgent.match(/iPhone/i);		// 아이폰 포함 여부 확인

	let message = "";

	// 2. 브릿지 통신 로직
    if (android !== null) {
    	console.log("Android");
        // BRIDGE가 안드로이드 코드에서 호출 받을때 구분하는 Handler
    	return window.BRIDGE.sendMessage(message);
	
    } else if (iphone !== null) {
    	console.log("iOS");
        // 원래 webkit 앞에 window를 써주기도 하나 안써도 통신이 되어 제거함
        // bridge 자리가 아이폰에서 호출 받을때 구분하는 Handler
    	return webkit.messageHandlers.bridge.postMessage(message);
  	
    } else {
    	return window.opener.postMessage(message);
  	}

 

먼저 사용하는 디바이스를 구분할때는 navigation에 있는 userAgent를 사용합니다.

userAgent 내에는 웹 엔진과 사용하는 디바이스 정보가 표시되어 있어 위와 같이 Android 혹은 iPhone 등의 문구를 가지고 있는지 체크 합니다.

만약 iPad를 구분하고 싶다면 iPhone을 구분하는 코드에 /iPad/를 추가해주시면 됩니다.

 

그리고 난 뒤 조건문을 통해 OS를 구분하여 메시지를 보냅니다.

여기서 messageHandlers 뒤에 들어가는 'bridge'가 iOS에서 해당 호출 받을 때 사용하는 구분자가 됩니다.

따라서 해당 문구를 원하시는대로 변경해서 사용하시면 편리합니다.

 

 

이제 iOS에서 브릿지 호출을 받아서 사용하는 방법을 보겠습니다.

여기서는 생략하겠지만 우선 웹뷰를 등록해주신 상태라고 생각하고 진행하겠습니다.

 

// 브릿지 통신 처리를 위한 extension 작성
extension ViewController: WKScriptMessageHandler {

	func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    
		switch message.name {

		case "bridge":
            	print("back 호출")
				let alert = UIAlertController(title: nil, message: "Back 버튼 클릭", preferredStyle: .alert)
				let action = UIAlertAction(title: "확인", style: .default, handler: nil)
				alert.addAction(action)
				self.present(alert, animated: true, completion: nil)
				self.sendMessageToVue()

		case "outLink":
				guard let outLink = message.body as? String, let url = URL(string: outLink) else {
					return
                }

				let alert = UIAlertController(title: "OutLink 버튼 클릭", message: "URL : \(outLink)", preferredStyle: .alert)
            	let openAction = UIAlertAction(title: "링크 열기", style: .default) { _ in
                	UIApplication.shared.open(url, options: [:], completionHandler: nil)
                }
                    
				let cancelAction = UIAlertAction(title: "취소", style: .cancel, handler: nil)
				alert.addAction(openAction)
				alert.addAction(cancelAction)
				self.present(alert, animated: true, completion: nil)

		default:
				print("bridge default")
				break
}

 

웹뷰에서 브릿지 통신을 시도하면 userContentController의 didReceive가 message타입으로 이를 받게 됩니다.

그럼 messageHandlers.bridge를 Swift에서 message.name으로 받아서 switch문 혹은 if문 등을 통해 로직을 구분하여 사용합니다.

 

위 코드는 bridge를 호출했을때 iOS 시스템 alert을 띄우도록 해봤습니다.

 

 

 

 

'iOS > Swift' 카테고리의 다른 글

[iOS/Swift] TMap(티맵) 연동하기  (3) 2023.01.09
[iOS/Swift] 카카오내비 연동하기  (0) 2023.01.06
Comments