|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "[iOS] WKWebView์ ์ด์ฉํ iOS ์ฑ๊ณผ ์นํ์ด์ง ๊ฐ์ ํต์ (2) - Control Flow" |
| 4 | +tags: [iOS, WKWebView, Javascript, if, switch, statement] |
| 5 | +--- |
| 6 | +{% include JB/setup %} |
| 7 | + |
| 8 | +์ด์ ๊ธ์์ `WKScriptMessageHandler` ํ๋กํ ์ฝ์ ๋ฉ์๋ `func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)`๋ฅผ ๊ตฌํํ์ฌ ์น ํ์ด์ง์์ iOS ์ฑ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด์์ต๋๋ค. |
| 9 | + |
| 10 | +์ด๋ฒ ๊ธ์์๋ `userContentController` ๋ฉ์๋์์ ๊ตฌํ๋๋ if ๋ฌธ๊ณผ switch ๋ฌธ๊ณผ ๊ฐ์ ํ๋ฆ์ ์ด(Control Flow) ์ฝ๋๋ก ์ธํด `WKWebView`์ ๋ค๋ฅธ ๋๋ฉ์ธ๊ณผ์ ๊ฐํ ๊ฒฐํฉ ๊ด๊ณ๊ฐ ํ์ฑ๋๋ ๊ฒ์ ์ดํด๋ณด๋ ค๊ณ ํฉ๋๋ค. |
| 11 | + |
| 12 | +### Control Flow |
| 13 | + |
| 14 | +Swift๋ if, switch ๋ฌธ๊ณผ ๊ฐ์ด ์ ์ด๋ฌธ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ ํ๋ก๊ทธ๋จ์ ํ๋ฆ์ ์ ์ดํ๋๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์น์์ ์ ๋ฌ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ฆํ๊ณ , ์ ํจํ ๋ฐ์ดํฐ๊ฐ ์๋ ๊ฒฝ์ฐ ๋ค์ ์น์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๋ฑ์ ํ๋ฆ์ ์ ์ดํ ์ ์์ต๋๋ค. |
| 15 | + |
| 16 | +์ ์ดํ๋ค๋ ์๋ฏธ๋ ์ด๋ค ์กฐ๊ฑด์ ๋ฐ๋ผ ์ฝ๋์ ์คํ์ ์ค๋จํ๊ฑฐ๋, ์ฝ๋์ ์คํ์ ๊ณ์ํ ์ง ๊ฒฐ์ ํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ์ฌ๊ธฐ์์ ๊ฐ ๋๋ฉ์ธ์์ ํ์ํ Action์ ์ฒ๋ฆฌํ๊ณ ์ ๋ฌํด์ผํ๋ค๋ฉด `userContentController` ๋ ๋ง์ ๋๋ฉ์ธ๊ณผ ๊ฐํ ๊ฒฐํฉ ๊ด๊ณ๋ฅผ ํ์ฑํฉ๋๋ค. |
| 17 | + |
| 18 | +๋ค์ ์ฝ๋๋ ์นํ์ด์ง์์ ์ ๋ฌ๋ฐ์ message์ action์ ๊ตฌ๋ถํ์ฌ ์ฒ๋ฆฌํ๋ ์ฝ๋์
๋๋ค. |
| 19 | + |
| 20 | +```swift |
| 21 | +// WKScriptMessageHandler ํ๋กํ ์ฝ ๋ฉ์๋ ๊ตฌํ |
| 22 | +func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { |
| 23 | + guard |
| 24 | + message.name == "actionHandler", |
| 25 | + let messageBody = message.body as? [String: Any], |
| 26 | + let action = messageBody["action"] as? String |
| 27 | + else { return } |
| 28 | + |
| 29 | + switch action { |
| 30 | + case "loading": loading(body: messageBody) |
| 31 | + case "openCard": openCard(body: messageBody) |
| 32 | + case "payment": payment(body: messageBody) |
| 33 | + case "log": log(body: messageBody) |
| 34 | + default: break |
| 35 | + } |
| 36 | + |
| 37 | + func loading(body: [String: Any]) { |
| 38 | + guard let value = body["show"] as? Bool else { return } |
| 39 | + |
| 40 | + switch value { |
| 41 | + case true: ShowLoading() |
| 42 | + case false: HideLoading() |
| 43 | + } |
| 44 | + } |
| 45 | + func payment(body: [String: Any]) { |
| 46 | + guard |
| 47 | + let id = body["paymentId"] as? String |
| 48 | + let info = body["paymentInfo"] as? [String: String] |
| 49 | + else { return } |
| 50 | + |
| 51 | + cardPayment(paymentId: id, paymentInfo: info) |
| 52 | + } |
| 53 | +} |
| 54 | +``` |
| 55 | + |
| 56 | +์ ์ฝ๋์ switch ๋ฌธ์์ loading, openCard, payment, log Action์ ๊ตฌ๋ถํ์ฌ ์ฒ๋ฆฌํ๊ณ ์์ต๋๋ค. ๊ฐ action์ ์๋ก ๋ค๋ฅธ ์ญํ ์ ์ํํ๋๋ก ๊ตฌํ๋์ด ์์ต๋๋ค. |
| 57 | + |
| 58 | +์ฆ, switch ๋ฌธ์ ๋ค์ํ ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ ์ ์๋ ์ฅ์ ์ด ์์ง๋ง, ์นํ์ด์ง์์ ์ ๋ฌ๋ฐ์ action์ด ๋ง์์ง ๊ฒฝ์ฐ, ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ๋ ์ฝ๋๊ฐ ๋ณต์กํด์ง๊ณ , ์ฝ๋์ ๊ฐ๋
์ฑ์ด ๋จ์ด์ ธ, ์ ์ง๋ณด์๊ฐ ์ด๋ ค์์ง๋ ๋จ์ ์ด ์์ต๋๋ค. |
| 59 | + |
| 60 | +๊ทธ๋ ๋ค๋ฉด, ๋ค์ํ Action์ ์ฒ๋ฆฌํ๋ ์ฝ๋๋ฅผ ์ฃผ์
๋ฐ์ ์ฒ๋ฆฌํ ์ ์๋๋ก ํ๋ฉด ์ด๋จ๊น์? |
| 61 | + |
| 62 | +### Inject Action Handler |
| 63 | + |
| 64 | +`Action`์ Key๋ก ์ฌ์ฉํ๊ณ , `messageBody`๋ฅผ ๋ฐ์ ์ํํ๋ `Closure`๋ฅผ ๊ฐ์ง๋ Dictonary์ ๋ง๋ค ์ ์์ ์ ์์ต๋๋ค. |
| 65 | + |
| 66 | +```swift |
| 67 | +struct WKScriptMessageActioHandler { |
| 68 | + let closure: (_ body: [String: Any], _ webView: WKWebView?) -> Void |
| 69 | +} |
| 70 | + |
| 71 | +class ViewController: UIViewController, WKScriptMessageHandler { |
| 72 | + var actionHandlers: [String: ActioHandler] = [:] |
| 73 | + var webView: WKWebView? |
| 74 | + |
| 75 | + init(actionHandlers: [String : ActioHandler]) { |
| 76 | + self.actionHandlers = actionHandlers |
| 77 | + |
| 78 | + super.init(nibName: nil, bundle: nil) |
| 79 | + } |
| 80 | + ... |
| 81 | + |
| 82 | + // WKScriptMessageHandler ํ๋กํ ์ฝ ๋ฉ์๋ ๊ตฌํ |
| 83 | + func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { |
| 84 | + guard |
| 85 | + message.name == "actionHandler", |
| 86 | + let messageBody = message.body as? [String: Any], |
| 87 | + let action = messageBody["action"] as? String |
| 88 | + else { return } |
| 89 | + |
| 90 | + actionHandlers[action]?.closure(messageBody, webView) |
| 91 | + } |
| 92 | +} |
| 93 | +``` |
| 94 | + |
| 95 | +`userContentController` ๋ฉ์๋์์ `actionHandlers` Dictionary์ ๋ฑ๋ก๋์ด ์๋ `WKScriptMessageActioHandler`๋ฅผ ์ฐพ์ `closure`๋ฅผ ํธ์ถํฉ๋๋ค. ์ด์ ๊ณผ ๊ฐ์ด switch ๋ฌธ์ ํตํด action์ ๊ตฌ๋ถํ์ฌ ์ฒ๋ฆฌํ์ง ์๊ธฐ ๋๋ฌธ์, ์นํ์ด์ง์์ ์ ๋ฌ๋ฐ์ action์ด ๋ง์์ง๋๋ผ๋, ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ๋ ์ฝ๋๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ ์ง๋ณด์๊ฐ ์ฌ์์ง๋๋ค. |
| 96 | + |
| 97 | +`WKScriptMessageActioHandler`๋ Closure๋ง ๊ฐ์ง๊ณ ์์ด, ๊ฐ ActionHandler๊ฐ messageBody์ ๊ฐ์ ๊ฒ์ฆํ์ฌ ์ ํจํ ๊ฐ์ธ ๊ฒฝ์ฐ์๋ง Closure๋ฅผ ํธ์ถํ ์ ์๋๋ก ์ฝ๋๋ฅผ ์ข ๋ ๊ตฌ์กฐํํ ์ ์์ง ์์๊น์? |
| 98 | + |
| 99 | +๊ทธ ๋ด์ฉ์ ๋ค์ํธ์์ ๋ค๋ฃจ๊ฒ ์ต๋๋ค. |
0 commit comments