ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 네이티브 & React 배포 버전 이슈 처리
    Language/iOS,AOS 2024. 7. 10. 15:48

    React <-> iOS Native로 통신하는 구조에서 iOS에 없는데 웹소스가 배포 되거나, 웹소스 배포 후 네이티브가 배포되면 문제가 발생한다.

    매번 예외 처리는 하지만 그떄마다 신경쓰는게 꽤 많이 많이 귀찮다.

    이번 기회에 자바스크립트에서 네이티브에 통신하였는데 해당 함수가 없어도 문제가 없도록 개선해 보자.

     

    JavaScript

    common.js

    window.openExternalLinkCallback 함수를 미리 정의해 두고 네이티브에서 콜백해주자.

    class Common {
      ...
     
      static openExternalLink(url) {
        if (Util.Browser.isAndroidApp()) {
          Common.open2(url);
        } else if (Util.Browser.isIosApp()) {
          window.openExternalLinkCallback = (jsonData) => {
            if (jsonData['result'] === false) {
              Common.open2(url);
            }
          };
    
          const message = {
            action: 'openExternalLink',
            params: { url: Util.getFullUrl(url) },
            callback: 'window.openExternalLinkCallback',
          };
          window.webkit.messageHandlers.IosBridge1.postMessage(message);
        } else {
          Common.open2(url);
        }
      }
      
      ...
    }
    
    export default Common;

     

    호출

    Common.openExternalLink('https://naver.com');

     

    Swift (네이티브)

    MainViewController

    웹에서 요청한 action에서 openExternalLink등 정의된 action이 없을때 default에서 정의된 callback이 있으면 result : false로 리턴해 준다.

    // MARK: - iOS Bridge
    // 웹 액션 정의 : WebAction을 구분하는데 사용되는 타입
    enum WebAction: String {
        ...
        
        case setAppData
        case getAppData
        case getAppVersion
        case getVersionCode
        case loginWithKakao
        case loginWithNaver
        case loginWithFacebook
        case loginWithApple
        case windowFullPDF
        case windowFull
        case windowFrame
        case openExternalLink
        case windowClose
        case windowCloseAndOpenerReload
        case getNotificationId
        case getDeepLink
        case share
        
        ...
    }
    extension MainViewController: WKScriptMessageHandler {
        func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
            guard message.name == IOS_BRIDGE_NAME,
                  let messageBody = message.body as? [String: Any],
                  let action = messageBody["action"] as? String else { return }
            
            let webAction = WebAction(rawValue: action)
            
            Utils.Log("@@@@@@@@@@@@@@@@@@@@@@@ \(action)")
            
            switch webAction {
            ...
            
            case .openExternalLink:
                ...
            ...
                
            default:
                Utils.Log("undefined action")
                
                // 콜백 함수 실행
                guard let callback = messageBody["callback"] as? String else { return }
    
                let jsonData: [String: Any] = [
                    "result": false,
                    "message": "undefined action"
                ]
                if let jsonString = Utils.convertDictionaryToJSONString(dictionary: jsonData) {
                    self.executeJavasScript(wKWeb: self.getActiveWkWebView(), callback: "\(callback)(\(jsonString));")
                } else {
                    Utils.Log("Failed to convert dictionary to JSON string.")
                }
            }
        }
    }

     

    Utils

    import Foundation
    import UIKit
    import WebKit
    
    class Utils: NSObject {
        ...
        
        static func convertDictionaryToJSONString(dictionary: [String: Any]) -> String? {
            do {
                let jsonData = try JSONSerialization.data(withJSONObject: dictionary, options: [])
                if let jsonString = String(data: jsonData, encoding: .utf8) {
                    return jsonString
                }
            } catch {
                Utils.Log("Error converting dictionary to JSON string: \(error.localizedDescription)")
            }
            return nil
        }
        
        ...
    }

     

    이제 해당코드로 네이티브가 개시되어 있다면 웹상 코드에서 callback함수만 잘 정의해 두면 예외처리가 가능하다.

    댓글

Designed by Tistory.