뷰 위에 오프라인으로 저장된 HTML 페이지를 표시하는 예제입니다.
1) WebKit View
를 뷰 위에 추가합니다.
2) 뷰 컨트롤러 소스 파일에 웹킷 뷰를 연결한 @IBOutlet
변수를 추가합니다.
3) 다음 프로젝트 폴더에서 마우스 오른쪽 버튼을 누른 뒤 Show in Finder
메뉴를 선택해 파인더 탐색기를 엽니다.
4) 웹페이지 파일을 담을 새로운 폴더를 생성합니다.
5) 다음 이 폴더를 프로젝트 내부로 드래그합니다.
6) 그러면 다음 창이 뜨는데 여기서 Create folder references
를 선택합니다. 이 옵션을 선택해야 이미지 파일 등의 static
파일을 표시할 수 있습니다.
7) 완료하였다면 다음과 같은 파란색 폴더 모양의 폴더 레퍼런스가 생성되었습니다.
8) 위 폴더에 index.html
파일과 이미지 파일등을 생성한 뒤, 페이지를 작성합니다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> h1 { background-color: antiquewhite; } </style> </head> <body> <h1>안녕하세요</h1> <img src="image.png" width="100%"> <a href="https://google.com">하이퍼링크</a> <button id="btn-alert">자바스크립트</button> </body> </html>
image.png
파일은 index.html
파일과 동일한 위치에 있으면 표시됩니다. 앞서 폴더 옵션에서 groups
를 선택했었다면 경로를 알 수 없게 되어 이미지 파일을 지정할 수 없습니다.
9) 뷰 컨트롤러에서 해당 뷰 컨트롤러에 대한 extension
코드를 작성합니다.
import WebKit
extension ViewController: WKUIDelegate, WKNavigationDelegate { func loadHelpPage() { // 웹 파일 로딩 webView.uiDelegate = self webView.navigationDelegate = self let pageName = "index" guard let url = Bundle.main.url(forResource: pageName, withExtension: "html", subdirectory: "webpage") else { return } webView.loadFileURL(url, allowingReadAccessTo: url) } }
WKUIDelegate
와WKNavigationDelegate
프로토콜을 구현하고, 해당 웹킷뷰의 딜리게이트와 뷰 컨트롤러 클래스를 연결합니다.subdirectory
에 폴더 이름을 지정하고, 파일 이름(forResource
)과 확장자(withExtension
)를 입력합니다..loadFileURL
은 로컬 웹 페이지를 읽어옵니다.URL
을 기입합니다.allowingReadAccessTo
부분은 동일한URL
을 지정하면 해당 파일만 접근할 수 있고, 다른 디렉토리를 지정하면 해당 디렉토리 내에 있는 파일에 접근할 수 있는 권한을 가지게 됩니다.
viewDidLoad()
등에서 위 함수를 실행합니다.
override func viewDidLoad() { super.viewDidLoad() loadHelpPage() }
시뮬레이터를 실행하면 다음과 같이 웹 페이지가 열리게 됩니다.
HTML과 CSS를 적용할 수 있습니다. 자바스크립트가 동작하려면 별도 허용 절차가 필요하며 꽤 복잡하기 때문에 여기서는 다루지 않겠습니다.
추가 사항으로, 로컬 웹페이지에서 외부 링크는 해당 웹킷뷰 내에 표시하는 것보다 외부 브라우저에서 표시하는 것이 적당하다고 생각됩니다. 불편하기도 하고 앱스토어 심사 시 외부 웹에 대한 무제한 액세스 허용으로 인식할 수 있기 때문입니다.
하지만 링크 태그에 target="_blank"
등을 적용해도 작동하지 않습니다. 하이퍼링크를 외부 브라우저에서 표시하려면 다음 코드를 추가해야 합니다.
// 링크 클릭시 외부 사파리 브라우저에서 열리게 하기 func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { guard case .linkActivated = navigationAction.navigationType, let url = navigationAction.request.url else { decisionHandler(.allow) return } decisionHandler(.cancel) UIApplication.shared.open(url, options: [:], completionHandler: nil) }
case
문법은switch ~ case
문법의 축약형으로navigationType
이 .linkActivated
타입인지 검사하는 부분입니다. 다음과 같이 바꿔쓸 수 있습니다.guard navigationAction.navigationType == .linkActivated, let url = navigationAction.request.url
url
변수가 생성되었다면UIApplication.shared.open
을 통해 해당 URL을 외부 브라우저에서 열도록 변경합니다.
2개의 댓글
Swift(스위프트): 오프라인 웹 페이지에서 자바스크립트 실행 및 alert, confirm, prompt 띄우기 (스토리보드) - BGSMM · 2021년 8월 26일 10:17 오후
Swift(스위프트): WKWebView에서 Swift 네이티브 앱과 웹 페이지의 자바스크립트간 통신 (스토리보드) + console.log 표시 - BGSMM · 2021년 8월 28일 1:43 오전