k-coding

SwiftUI WebView (UIViewRepresentable) 본문

iOS/Swift UI

SwiftUI WebView (UIViewRepresentable)

chkhn_oiiu 2022. 5. 5. 01:30

SwiftUI WebView

 

SwiftUI에서 WebView를 만드는 방법에 대해서 알아보겠습니다!

 

우선 WebView를 다루기 위해서는 

 

import WebKit

 

을 필수로 해주셔야하고, 한가지 더 해주셔야할 것이 있습니다.

 

바로 인터넷에 접속하기위한 준비과정인데요.

 

Info.plist로 가줍시다.

 

보이는 리스트 중에서

 

Supported interface orientations (iPhone) 를 누르고 엔터를 눌러주시면 여러 리스트들이 나옵니다. 그중에서

 

 

App Transport Security Setting를 선택해주시고,

 

App Transport Security Setting 옆에 화살표를 내려주신다음 Allow Arbitrary Loads를 선택해주시고, 값을 YES로 바꿉니다.

 

이 과정을 완료하셨다면 이제 어플리케이션내에서 인터넷에 접급할 수 있게 됩니다.

 

 

자 이제 소스코드로 돌아가봅시다.

 

UIViewRepresentable

 

// uikit의 uiview를 사용할 수 있도록 한다.

struct MyWebView: UIViewRepresentable {


}

 

SwiftUI를 하시다보면 위에 코드처럼 UIViewRepresentable 이란 프로토콜을 자주 보게 될것입니다.

 

도대체 무엇일까요?

 

SwiftUI가 유용하긴 하나 아직 나온지 오래된 언어는 아닙니다.

 

그러다보니 SwiftUI로만으로써는 구현되지 않는 기능들이 존재하고,

 

그러한 부분은 UIKit에서 업어와야하기도 합니다.

 

UIViewRepresentable가 바로 UIKit을 SwiftUI에 맞게 wrapping해주는 기능을 제공합니다.

 

위에 코드처럼 프로토콜을 선언해주면 바로 밑도끝도없이 에러메세지를 만나실 수 있는데

 

이유는 structure가 프로토콜을 준수하지 않아서입니다.

 

 

 

 makeUIView(context:) -> UIView

 

UIView를 생성하는 메소드로, SwiftUI의 View 라이프 사이클동안 "한번" 호출됩니다.

 

구현하고자 하는 View를 해당 구역에 구현하면 되고,

 

여기서 생성한 UIView를 UIViewRepresentable로 래핑하여 SwiftUI의 View가 됩니다.

 

 

- updateUIView(:context:)

 

이 메소드 안에서 view의 정보를 업데이트 할 수 있습니다.

 

또한, @Binding기능을 이용해서 SwiftUI view의 상태도 가져올 수 있다! 단, read only입니다.

 

struct MyWebView: UIViewRepresentable {
    
    var urlToLoad: String
    
    // uiview 만들기
    func makeUIView(context: Context) -> WKWebView {
        
        let webView = WKWebView()
        
        
        return webView
    }
    
    //update uiView
    func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<MyWebView>) {
        
    }
    
}

 위 처럼 2가지 메서드를 충족시켜주면 더이상 에러메세지가 나타나지않게 됩니다!!

 

자 그럼 makeUIView에서 View를 한번 작성해 볼까요?

 


var urlToLoad: String

	func makeUIView(context: Context) -> WKWebView {
        
        guard let url = URL(string: self.urlToLoad) else {
            return WKWebView()
        }
        
        // 웹 뷰 인스턴스 생성
        let webView = WKWebView()
        
        // 웹뷰를 로드한다
        webView.load(URLRequest(url: url))
        
        return webView
    }
    
    //update uiView
    func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<MyWebView>) {
        
    }

 

먼저 당연히 웹 뷰를 리턴 받아와야 하기 때문에 webView라는 인스턴스를 생성하고 리턴 받아와야합니다.

 

그리고 webView를 로드하기 위해서 우선 urlToLoad라는 String 변수를 받고, 해당 url을 거기에 받아주면 되는데

 

원래는

 

webView.load(URLRequest(url: URL(string: urlToLoad)))

 

를 사용해서 웹뷰를 받아오게 됩니다. 그치만 URL()이 자체적으로 Optinal형이기 때문에, 옵셔널 언래핑을 해주기 위해서

 

위에 guard let 문을 사용했다고 이해해주시면 되겠습니다.

 

간단한 웹뷰에서는 해당 View가 업데이트 될 일이 없으니 아무것도 작성을 안해주셔도 괜찮습니다!!

 

자 이제 Preview에서 위에 structure가 나오게 해주고, 돌려주면!!

struct MyWebView_Previews : PreviewProvider {
    static var previews: some View {
        MyWebView(urlToLoad: "https://www.naver.com")
    }
}

 

이쁘게 WebView가 나온것을 확인할 수 있습니다.

 

그럼 이 View를 ContentView에 보이게 하려면 어떻게 해야할까요?

 

전에 포스팅했던 네비게이션을 이용해서 넘겨봅시다.

 

struct ContentView: View {

    var body: some View {
        NavigationView {
            HStack {
                NavigationLink(destination: MyWebView(urlToLoad: "https://www.naver.com")){
                    Text("Naver")
                        .padding(20)
                        .background(Color.green)
                        .cornerRadius(30)
                        .foregroundColor(Color.white)
                    
                }
                NavigationLink(destination: MyWebView(urlToLoad: "https://www.google.com")){
                    Text("Google")
                        .padding(20)
                        .background(Color.blue)
                        .cornerRadius(30)
                        .foregroundColor(Color.white)
                        
                }
            }
            
        }
    }

}

 

다음과 같이 destination을 위~~에서 작업한 MyWebView(urlToLoad: " " )로 해주시고,

 

modifier를 조금 고쳐주시면 다음과 같이 작동 완료하게됩니다!

 

 

이상 SwiftUI를 이용하여 WebView를 구상하는 방법을 알아보았습니다!

'iOS > Swift UI' 카테고리의 다른 글

Swift UI TabBar  (0) 2022.05.23
SwiftUI Divider, Spacer  (0) 2022.05.05
SwiftUI @State, @Binding  (0) 2022.05.01
SwiftUI Navigation 연결  (0) 2022.05.01
SwiftUI (HStack / VStack)  (0) 2022.05.01
Comments