강의: 웹뷰 띄우기
웹페이지를 앱 내에서 띄워주기 위해 WKWebView를 사용했다.
요 WKWebView부터 대충 알아보고 가자면, 원래 UIKit에 있었던 UIWebView를 대체하는 것으로, iOS8부터 사용 가능해졌다고 함!
얘는 WebKit의 일부이고, 따라서 사용하려면 WebKit을 import 해줘야 함.
일단 얘가 하는 일은 앱 내부에 HTML, JS, CSS 컨텐츠를 보여줄 수 있게 해 주는 것! 앱의 컨텐츠가 자주 바뀌거나 앱의 원래 뷰보다 웹 기술이 더 레이아웃을 잘 나타내줄 때 사용한다.
URLRequest
로 웹 서버에서 컨텐츠를 로드하거나, 로컬 파일이나 HTML 문자열을 바로 로드할 수도 있다. 로드를 요청하면 이때 웹뷰가 알아서 이미지나 비디오까지 같이 로드해줌! 그런 다음에 뷰 안에 컨텐츠들을 나타내준당.
그니까 대충
앱 뷰 안에서 링크 또는 웹 뷰 띄우는 동작 실행 -> 원하는 컨텐츠 로드 -> 앱 뷰에 디스플레이
이런 식으로 동작하는 것!
이제 코드를 보자.
< MyWebView.swift >
import SwiftUI
import WebKit
// uikit의 uiview를 사용할 수 있도록 해줌
// uiviewcontroller를 사용하고 싶으면 UIViewControllerRepresentable 하면됨
struct MyWebView: UIViewRepresentable {
var urlToLoad: String
//uiview 만들기
func makeUIView(context: Context) -> WKWebView {
//언래핑
guard let url = URL(string: urlToLoad) else{
return WKWebView()
}
//웹뷰 인스턴스 생성
let webview = WKWebView()
//웹뷰 로드
webview.load(URLRequest(url: url))
return webview
}
//uiview 업데이트
//context는 uiviewrepresentablecontext로 감싸야 함.
func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<MyWebView>) {
}
}
struct MyWebView_Previews: PreviewProvider{
static var previews: some View{
MyWebView(urlToLoad: "https://www.naver.com")
}
}
일단 UIViewRepresentable 부터 짚고 넘어가자.
SwiftUI가 생긴지 얼마 안 된 프레임워크다 보니 UIKit의 모든 요소를 포함하고 있지는 않다. 그래서 UIKit의 요소를 래핑해주는 기능이 있음!
여기서는 UIKit의 view를 SwiftUI에 나타낼 것이기 때문에 UIViewRepresentable
프로토콜을 추가했다.
근데 이것만 하면 되는게 아니라!
이 프로토콜을 추가하면 필수적으로 넣어줘야 하는 메소드 두 개가 있다.
바로 makeUIView(context:) -> UIView
메소드와 updateUIView(_:context:)
메소드!
우선 makeUIView(context:) -> UIView
메소드는 말 그대로 uiview를 만들어주는 메소드임. 뷰의 라이프사이클동안 "한번만" 호출되고, 여기서 만들어준 uiview가 UIViewRepresentable를 통해 SwiftUI의 View로 만들어진다!
그다음 호출되는 updateUIView(_:context:)
메소드는 State로 설정해둔 변수가 바뀔 때마다 실행된다. 여기서 우리가 만든 view의 정보를 업데이트 할 수 있음!
위 코드에서는 딱히 업데이트에 대한 기능은 넣지 않았기에 updateUIView를 비워뒀다.
가장 큰 비중을 차지하는 makeUIView를 분석해보자.
우선 원하는 WKWebView를 여기 안에서 생성해주면 된다. 로드할 페이지의 url 문자열을 받아서 로드할 것이기 때문에 urlToLoad를 선언해 주고, 받아온 문자열을 URL의 형태로 인코딩해야 하기 때문에 url = URL(string: urlToLoad)
을 통해 해결해준다.
URL형태로 인코딩한 url이 비어있을 수도 있기 때문에 guard let 구문을 통해 옵셔널 언래핑을 해 주고, 비어있다면 기본 WKWebView()를 하나 생성해주는 것으로 끝낸다.
이후 웹 뷰 인스턴스를 생성해 주고, webView.load(URLRequest(url: url))
를 통해 원하는 url을 로드해준다.
이러면 이제 끝!