관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 9. 웹 뷰(사파리 앱 호출, WKWebView) 본문

iOS 기본 (swift)

[iOS - swift] 9. 웹 뷰(사파리 앱 호출, WKWebView)

jake-kim 2020. 4. 4. 19:41

1. 사파리 앱 호출

 - 사파리 앱 그대로 호출하는 것이므로 구현하기 가장 단순

 -  장점 : ATS(info.plist에 HTTP보안 허가) 설정이 필요없음, 구현이 쉬움

 -  특징 : 기존 뷰에서 여는게 아닌, 새로 앱을 실행하는 것

1
2
let url = URL(string:"https://ios-development.tistory.com")
 

 

2. SFSafariViewController

- 컨트롤러 객체에 해당 (스토리 보드 UI에 삽입하는 것이 아니라 단순 코드 호출)

- 특징 : 기존 뷰에서 여는 것

1
2
3
4
5
 import SafariServices
  
 @IBAction func btnAction(_ sender: Any) {
        let url = URL(string: "https://ios-development.tistory.com")
        let safariViewController = SFSafariViewController(url: url!)
        present(safariViewController, animated: true)
    }
 
 

3. WKWebView

1) 생성

- 스토리보드에서 WebKit View 드래그 엔 드랍, @IBOutlet를 이용하여 변수 생성

- WapKit프레임워크 사용

- HTTP부를시, info.plist에 ATS에 설정할 것

1
2
3
4
5
6
7
8
9
    import WebKit
 
@IBOutlet var myWebView: WKWebView!
    
    @IBAction func btnAction(_ sender: Any) {
        guard let url = URL(string: "https://ios-development.tistory.com"else {return}
        
        let req = URLRequest(url: url)
        
        self.myWebView.load(req)
    }
 
 

※ load는 비동기식으로 작동

 

2) WKWebView의 메소드

 - load(_:) // URLRequest객체를 인수로 하는 비동기메소드

 - stopLoading() : 웹 페이지 로딩 도중에 중단하고자 할 때 사용

 - isLoading프로퍼티 : 웹 페이지의 로딩 진행 여부 확인 (Bool반환)

 - goBack(), goForward() : 뒤로가기, 앞으로가기

 

3) 델리게이트 패턴

 - WKNavigationDelegate : 웹 페이지 로딩상황 추적, 제어

   (self.myWKWebView.navigationDelegate = self추가)

 

   webView(_:decidePolicyFor:decisionHandler:) // 웹 뷰가 특정 페이지를 읽어올지 말지 결정

1
2
3
4
5
6
7
8
9
10
11
extension ViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        
        // URLRequest로 부터 URL을 추출
        guard let url = navigationAction.request.url?.absoluteString else {return}
        
        if (url.starts(with"http")){ // URL이 "http"로 시작하면 중지
            decisionHandler(.cancel) // 작업 취소
        }
    }
}
 
 

 

   webView(_:didStartProvisionalNavigation) // 웹 뷰가 콘텐츠를 로드하기 시작할 때 호출되는 메소드 (URL이 유효하지 않을때도 호출됨)

   webView(_:didCommit:) // 웹 뷰가 HTML 페이지의 콘텐츠를 읽어 들이기 사작할 때 호출 (위 메소드 실행 후 바로 이 메소드 실행)

   webView(_:didFinish:) // 웹 뷰가 콘텐츠 로딩을 완전히 마쳤을 때 실행

   webView(_:didFail:withError:) // 콘텐츠 로딩이 실패한 경우

 

4) 테이블 뷰에서 클릭시, 웹뷰로 작동하게 하는 응용

 - segue생성 -> prepare메소드에서 세그웨이 id를 탐색 -> cell인스턴스를 참고하여 사용자가 클릭한 셀을 추출 -> segue.destination을 통해 전달하려는 웹뷰를 연결한 뷰컨트롤러에 전달

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if segue.identifier == "segue_detail" {
            
    // sender 인자값을 활용하여 세그웨이를 부른 table view cell인스턴스를 참조
    let cell = sender as! MovieCell
            
    // 사용자가 클릭한 행 참조
    let path = self.tableView.indexPath(for: cell)
            
    // 전역변수에 있던 list에 사용자 클릭한 행의 정보를 획득
    let movieinfo = self.list[path!.row]
            
    // 웹뷰를 띄우려는 목적지 뷰컨트롤러에 이 정보를 넘겨줌
    let destVC = segue.destination as? DestinationViewController
    destVC?.mvo = movieinfo
            
}
 
 

전달받은 url정보를 가지고 viewDidLoad에 웹을 불러오는 코드작성

 

5) 웹 뷰 로딩 표시

- 스토리보드에서 "Activiry Indicator View" 추가 (style:Large White, Color: Black, Behavior: hides When Stopped설정)

- @IBOutlet으로 연결

- webView(_:didCommit)과 webView(_:didFinish)에 적절한 코드 구현

1
2
3
4
5
6
7
8
9
extension ViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
        self.spinner.startAnimating()
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        self.spinner.stopAnimating()
    }
}
 
 

 

웹 뷰 로딩 결과화면)


 

(로딩중)

 

WKWebView는 스토리보드에서 WebKit view 크기를 지정한 만큼 화면에 표현가능

* 내용 출처 : 꼼꼼한 재은 씨의 스위프트 기본편

Comments