์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- node.js
- RxSwift
- MVVM
- combine
- realm
- Swfit
- rxcocoa
- XCTest
- BFS
- tableView
- Lv2
- TCA
- designpattern
- CollectionView
- arkit
- Kuring
- raywenderlich
- UIKit
- ios
- Xcode
- reactorkit
- ๋ฐฑ์ค
- SwiftUI
- ํ๋ก๊ทธ๋๋จธ์ค
- swift
- BOJ
- visionOS
- Flutter
- SnapKit
- ํจ์คํธ์บ ํผ์ค
- Today
- Total
lgvv98
[iOS] WebView javaScript ํจ์ ํธ์ถ๐จ ๋ณธ๋ฌธ
[iOS] WebView javaScript ํจ์ ํธ์ถ๐จ
๐ฅ ์บ๋ฟ๋งจ 2021. 10. 25. 15:35โ ์ด๋ฒ ์๊ฐ์๋ ์น๋ทฐ๋ฅผ ํตํด javaScript๋ก ์์ฑ๋ ํจ์๋ฅผ ํธ์ถํ๊ณ ์ฒ๋ฆฌํ๋ ๊ณผ์ ์ ๋ํด์ ์์๋ณผ ์์ ์ด์ผ.
ํ๋ํ๋ ๊ผผ๊ผผํ ๋ณด๋ค๋ณด๋ฉด ๋ถ๋ช ํ ๋ค ์ดํดํ ์ ์๋ ๊ฒ๋ค์ด์์ง๋ง, WebView ๊ฐ๋ฐ๋ก js๋ฅผ ์ฐ๊ฒฐํด์ ์์ ํ๋๊ฒ ์ต์ํ์ง ์๋ ๋ด๊ฒ, ์๊ฐ๋ณด๋ค ์ด๋ ค์ด ์์ ์ด์์ด... (์์ฒญ๋ ์ฝ์ง์ ๊ณผ์ s)
(๊ทธ๋๋ง ๋คํ์ธ๊ฑด, ์ง๋ก๋ฅผ ์ ํ๊ฒ ๋ค๊ณ js๋ฅผ ๊ณต๋ถํ์ฌ ์น ํ๋ก์ ํธ๋ฅผ ์ํํ๋ ๊ฒ์ด ์ ๋ง์ ๋ง ํฐ ๋์์ด ๋์๋ค๋ ์ฌ์ค!)
โ ๋ชฉ์ฐจ
1๏ธโฃ ์น ํ๊ฒฝ์ค์
2๏ธโฃ iOS ํ๊ฒฝ์ค์
1๏ธโฃ ์น ํ๊ฒฝ์ค์
- ์ฐ์ ๋ชจ๋ฐ์ผ ๊ฐ๋ฐ์์๋ค๋ฉด, ์น ํ์ด์ง๋ฅผ ์ด๋ป๊ฒ ๋ง๋ค์ด์ ํ ์คํธ ํด๋ณผ์ง์ ๋ํด์ ์ ๋ง ๋ง๋งํ๊ฒ ์ง?
๊ทธ! ๋! ์!
๋ด๊ฐ ๊ฐ๋จํ๊ฒ ํ์ธํ ์ ์๋๋ก ์ ๋ฆฌํด์ค ์์ ์ด์ผ.
๐ถ 1. VSCode๋ฅผ ์ค์นํ๋ค.
๐ถ 2. node.js๋ฅผ ์ค์นํ๋ค.
์์ ์ฌ์ดํธ์ ์ ์ํ๋ฉด ์ด๋ฐ ์ฌ์ดํธ๊ฐ ๋์ฌ๊ฑด๋ฐ, ๋๋ถ๋ถ iOS ๊ฐ๋ฐ์๋ค์ ๋งฅ๋ถ์ ์ฌ์ฉํ ํ ๋๊น, ์ ๊ธฐ์ ์ค์นํ๋ฉด ๋๋ค.
๋๋ ๊ทธ๋ฅ ์ผ์ชฝ์ ์๋ ์์ ์ , ์ ๋ขฐ๋ ๋์์ ์ค์นํ์
-> ์์ ์ ์๋ฐ ๋ฒ์ ์ ์ฌ๋ ค๋ฌ์ ์ง์์ ํ์ง ์๋ ๋ช๋ช ๋ฌธ์ ์ ๋ถ๋ชํ์ ๊ฒฐ๊ตญ ๋ค์ด๊ทธ๋ ์ด๋ ํ๋ ๊ธฐ์ต์ด ์์ด์ ์ต์ ๋ณด๋ค๋ ์์ ์ ์ผ๋ก ์ ๋์๊ฐ๋๊ฒ ์งฑ!
๐ถ 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
https://ios-development.tistory.com/701
'โ ๏ธ deprecated โ ๏ธ > ํธ๋ฆฝํ๋(TripPlan)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[iOS] UIPasteboard ํด๋ฆฝ๋ณด๋ ๋ณต์ฌํ๊ธฐ (0) | 2022.02.07 |
---|---|
[iOS15] ์์น ๊ถํ ํ์ธํ๋ ํจ์ ๐ (0) | 2021.11.04 |
[iOS15] Alert์ ํตํด ์ค์ ์ฐฝ์ผ๋ก ๋ค์ด๊ฐ๊ธฐ โ๏ธ (0) | 2021.11.04 |
[iOS] WKWebView์ ๋ํด์ ์์๋ณด์ (iOS ๋ธ๋ก๊ทธ ์ถ์ฒ!)๐ (0) | 2021.10.26 |
[iOS] viewDidLoad() vs. loadView() ์ ์ฐจ์ด (0) | 2021.10.26 |