본문 바로가기

개발

RxSwift로 웹뷰 로직 만들기

728x90

RxSwift를 사용한 웹뷰 로직 구현

RxSwift를 사용하여 웹뷰 로딩, URL 변경 감지, JavaScript 호출 등 다양한 웹뷰 기능을 효율적으로 구현할 수 있습니다.

1. 요구 사항 정의

  • 웹뷰에 특정 URL을 로딩합니다.
  • 사용자가 웹뷰에서 링크를 클릭하면 새로운 페이지로 이동합니다.
  • JavaScript를 사용하여 웹뷰와 앱 간의 상호 작용을 수행합니다.

2. UI 설정 및 WebView Delegate 설정

  • ViewController에서 UIWebView 인스턴스를 생성하고 레이아웃에 추가합니다.
  • WebView Delegate를 설정하여 웹뷰 로딩 및 이벤트 처리를 담당합니다.
import UIKit

import RxSwift

import WebKit



class WebViewController: UIViewController {



    @IBOutlet weak var webView: UIWebView!



    private let disposeBag = DisposeBag()



    override func viewDidLoad() {

        super.viewDidLoad()



        setupWebView()

    }



    private func setupWebView() {

        webView.delegate = self

        let url = URL(string: "https://www.example.com")!

        webView.loadRequest(URLRequest(url: url))

    }

}



extension WebViewController: UIWebViewDelegate {



    func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {

        print("웹뷰 로딩 오류: \(error.localizedDescription)")

    }



    func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: WKNavigationType) -> Bool {

        if navigationType == .linkClicked {

            // 링크 클릭 시 새로운 페이지로 이동

            let newURL = request.url!

            webView.loadRequest(URLRequest(url: newURL))

            return false

        }

        return true

    }

}

 

3. RxSwift를 사용한 웹뷰 로딩 및 이벤트 처리

  • RxSwift의 Observable을 사용하여 웹뷰 로딩 완료, URL 변경, JavaScript 함수 호출 등의 이벤트를 감지하고 처리합니다.
import RxSwift

import WebKit



extension WebViewController {



    // 웹뷰 로딩 완료 감지

    var webViewDidFinishLoad: Observable<Void> {

        Observable.create { observer in

            webView.addObserver(self, forKeyPath: "loading", options: .new, context: nil)

            return Disposables.create {

                webView.removeObserver(self, forKeyPath: "loading")

            }

        }

        .filter { $0 }

        .ignoreFirst()

        .share()

    }



    // URL 변경 감지

    var currentURL: Observable<URL> {

        Observable.create { observer in

            webView.addObserver(self, forKeyPath: "URL", options: .new, context: nil)

            return Disposables.create {

                webView.removeObserver(self, forKeyPath: "URL")

            }

        }

        .map { $0.newValue as! URL }

        .share()

    }



    // JavaScript 함수 호출

    func callJavaScriptFunction(functionName: String, arguments: [String]? = nil) {

        let javaScriptString = """

            \(functionName)(\(arguments?.joined(",") ?? ""))

        """

        webView.stringByEvaluatingJavaScriptFromString(javaScriptString)

    }



    // KVO를 통해 웹뷰 로딩 및 URL 변경 감지

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

        if keyPath == "loading" {

            if !(change![NSKeyValueChangeNewKey] as! Bool) {

                webViewDidFinishLoad.onNext(())

            }

        } else if keyPath == "URL" {

            currentURL.onNext(change![NSKeyValueChangeNewKey] as! URL)

        }

    }

}

 

4. UI 및 로직 처리

  • ViewController에서 webViewDidFinishLoad Observable을 구독하여 웹뷰 로딩 완료 후 UI 작업을 수행합니다.
  • currentURLObservable을 구독하여 URL 변경 시 새로운 페이지로 이동하거나 데이터 처리를 수행합니다.
  • callJavaScriptFunction메서드를 사용하여 JavaScript 함수를 호출하고 앱과 웹뷰 간의 상호 작용을 구현합니다.