deprecated/트립플랜(iOS 프로젝트)

[iOS] WebView javaScript 함수 호출

lgvv 2021. 10. 25. 15:35

[iOS] WebView javaScript 함수 호출

 

목차

  • 1️⃣ 웹 환경설정 
  • 2️⃣ iOS 환경설정

 

 

1️⃣ 웹 환경설정

웹 개발자가 이미 있다면 생략해도 되는데, 없다면 학습용을 위해 작성

 

 

🔶 1. VSCode를 설치한다.

🔶 2. node.js를 설치한다.

https://nodejs.org/ko/

 

Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

 

위의 사이트에 접속하면 이런 사이트가 나올건데, 대부분 iOS 개발자들은 맥북을 사용할테니까, 저기서 설치하면 된다.

나는 그냥 왼쪽에 있는 안정적, 신뢰도 높음을 설치했음.

 -> 예전에 자바 버전을 올려둬서 지원을 하지 않는 몇몇 문제에 부딪혀서 결국 다운그레이드 했던 기억이 있어서 최신보다는 안정적으로 잘 돌아가는게 최고

LTS 환경설정

🔶 3. 설치가 잘 되었는지 확인하고 터미널로 작업하기

VSCode를 열어서 상단 메뉴바에 새 터미널 클릭!

상단바에 새 터미널 클릭!
새 터미널 클릭시 하단에 나타나는 화면

여기서 터미널에 

node --version

npm --version (node.js를 설치하면서 함께 설치된다.)

 

를 입력하면 정상적으로 설치가 되었다면 v ~ 라고 나옴.

정상적으로 설치된 결과

 

자 그럼 정상적으로 설치된 것을 확인했다면 터미널에 다음과 아래의 코드를 작성해 주면 돼

 

npm install -g nodemon

-> 만약 권한 에러가 난다면 sudo npm install -g nodemon로 입력하기

설치 후에

npm install -g express-generator

-> 만약 권한 에러가 난다면 sudo npm install -g express-generator로 입력하기

 

🔶 4. 위의 작업을 우선적으로 잘 수행했다면 이제는 폴더열기를 할 예정인데, 폴더를 열어서 내가 원하는 프로젝트 파일명을 작성하고 프로젝트를 열기!

 

폴더명은 마음대로 하기~!

 

폴더를 만들었다면 터미널의 시작 위치가 자기가 만든 폴더명의 위치로 바뀌어 있을건데,

우리가 아까 설치한 express 패키지를 사용하여 터미널에 (터미널이 닫혀 있다면 새 터미널 열어주기)

 

express --ejs 폴더명

 

(예시) 만약 내가 폴더 열기를 통해 폴더명을 TestExpress로 만들었다면

express --ejs TestExpress 를 터미널에 입력해준다.

 

이 과정이 끝나면 아래 이미지처럼 파일이 똭! 하고 생길 것이다.

똭!

 

views - index.ejs 파일을 일단 보자.

 

🔶 5. index.ejs에 작성해줄 코드

<!DOCTYPE html>
<html>
  <head>
    <!-- <title><%= title %></title> -->
    <link rel='stylesheet' href='/stylesheets/style.css' />
    


  <script type="text/javascript" charset="UTF-8">
    
    function callNative() {
       try {
          webkit.messageHandlers.callbackHandler.postMessage("MessageBody");
          print("callNative");
       } catch(err) {
           alert(err);
       }
    }


    function redHeader() {
       alert('redHeader() CALL');
       document.querySelector('h1').style.color = "red";
    }

    function funcName() {
       return "OK";
    }
  </script>
  </head>
  <body>
       
    <h1>IOS용 메시지</h1>
    <br><input type="button" onclick= 'callNative()' value="네이티브 함수 호출"/>
    <h1><%= title %></h1>
    <p>Welcome to <%= title %></p>
    
  </body>
</html>

🔶 6. 웹에서 보기 위해 실행하는 과정 

터미널에

nodemon ./bin/www

또는 nodemon start

둘중에 하나 입력해주면 돼.

 

그 이후에 크롬 브라우저에서 

http://localhost:3000/ 입력해주기.

 

웹에 나타난 결과

 

이런 웹 사이트를 확인할 수 있어.

 

2️⃣ iOS 환경설정

여기 부분은 Swift를 이용해서 작업할 예정이야.

Xcode열고 하는 작업이니까 부담없이 레츠고고!

 

🔶 1. 스토리보드 세팅

 

스토리보드

 

웹뷰를 넣은 다음에 레이아웃 잡아주면 끝!

 

🔶 2. ViewController.Swift 파일 작성하기

import UIKit
import WebKit

class ViewController: UIViewController,
                      WKNavigationDelegate,
                      WKUIDelegate,
                      WKScriptMessageHandler
{

	@IBOutlet weak var webView: WKWebView! // 스토리보드의 웹뷰 연결한 아웃렛 변수
    
    var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView() 
    // 웹뷰가 로드될 때 필요한 인디케이터

    override func viewDidLoad() {
        super.viewDidLoad()
       
        let myBlog = "http://localhost:3000" // express 통해서 연 URL 링크
        let url = URL(string: myBlog) // URL 타입으로 변경
        let request = URLRequest(url: url!) // Request 준비
        
        let contentController = WKUserContentController() // js랑 통신해서 받아온 값 다룰 핸들러
        let config = WKWebViewConfiguration() // 웹 뷰를 스토리보드 형식으로 만들 시 사용 불가능. 하지만 알아두기
        
        // native -> js call (문서 시작시에만 가능한, 환경설정으로 사용함), source부분에 함수 대신 HTML직접 삽입 가능
        let userScript = WKUserScript(source: "redHeader()", injectionTime: .atDocumentEnd, forMainFrameOnly: true)
        contentController.addUserScript(userScript)
        
        // js -> native call : name의 값을 지정하여, js에서 webkit.messageHandlers.NAME.postMessage("");와 연동되는 것, userContentController함수에서 처리한다
        contentController.add(self, name: "callbackHandler")
        
        config.userContentController = contentController
        
        webView.uiDelegate = self
        webView.navigationDelegate = self
        
        // native -> js call page에 js를 주입하는 방법
        webView.evaluateJavaScript("javascript:redHeader()", completionHandler: { msg, err in
            print(msg)
            print(err?.localizedDescription)
        })
        webView.load(request) // 웹뷰를 로드해야지 사용할 수 있어.
    }
    
    
    // JS -> Native CALL
    @available(iOS 8.0, *)
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage){
        // message.name으로 판단한다.
        if(message.name == "callbackHandler"){
            print(message.body)
            abc()
        }
    }
    
    func abc(){
        print("abc call")
    }
    
    // WebView가 로드가 끝난 시점에 호출하는 함수
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    
        webView.evaluateJavaScript("javascript:redHeader()", completionHandler: { msg, err in
            print(msg)
            print(err?.localizedDescription)
        })
    }
    
} // ViewController

여기까지가 ViewController 파일에 대한 코드이다.

 

아주 간단한 기능들만 담고 있어서, 자세한 부분은 참고로 가서 확인해보면 더욱 좋다.

 

🔶 3. 결과물 

결과물

 

결과물을 보면 redHeader() CALL이 호출되고, iOS용 메시지가 빨간색 글씨로 바뀐 것을 확인할 수 있다.

 

🔶 4. override func viewDidLoad() 와 override func loadView()의 차이점

다른 블로그를 참고하다 보니 viewDidLoad()가 아니라 loadView()를 작성해서 개발한 코드를 찾아볼 수 있었다.

 

 

(참고)

https://zetal.tistory.com/entry/WKUserContentController

 

WKUserContentController 뽀개기

WKUserContentController 뽀개기 이번 포스팅에서는 WKWebView 기능 중에 하나인 WKUserContentController 기능을 살펴보겠습니다. WKWebView기능 중에 좋은 기능이 있습니다. 기존 UIWebView에서는 지원이 안됐던..

zetal.tistory.com

https://ios-development.tistory.com/701

 

[iOS - swift] 2. WKWebView 사용 방법 (웹뷰, 쿠키, WKScriptMessageHandler, WKNavigationDelegate, WKUIDelegate)

1. WKWebView 개념1 (UIWebView, AJAX, XHR, 캐시, 쿠키) 2. WKWebView 사용 방법 (웹뷰, 쿠키, WKScriptMessageHandler, WKNavigationDelegate, WKUIDelegate) WKWebView를 사용하기 전 알아야할 기본 개..

ios-development.tistory.com

https://yagom.net/forums/topic/loadview%EC%99%80-viewdidload-%EC%B0%A8%EC%9D%B4%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A7%88%EB%AC%B8%EC%9E%85%EB%8B%88%EB%8B%A4/

 

loadView와 viewDidLoad 차이에 대한 질문입니다. - 야곰닷넷

안녕하세요. Swift를 공부한지 시간이 흐르니 스토리보드와 인터페이스 빌더로 UI를 구성하는 거 보다 코드만으로 View를 그리는 […]

yagom.net