본문 바로가기

iOS

[iOS] MyWebBrowser 정리

MyWebBrowser




Index

1. 인터페이스

2. 공식문서

3. 코드리뷰

4.정리



1. 인터페이스

본 문서는 MyWebBrowser 프로젝트를 진행하며 배운 내용들을 정리하도록 한다.

뷰 컨트롤러 scene 에는 WebViewActivity Indicator 그리고 Toolbar Item을 이용해 scene 을 구성하였다.

image

웹 뷰를 화면 전체에 뿌려주기 위해 제약을 걸어주고 화면 중간에 Activity Indicator 그리고 하단에 툴 바를 추가하고 툴 바 아이템들을 배치하였다.



2. 공식문서

이번 프로젝트의 핵심기능은 WKWebView이다.

따라서 원활한 기능 수행을 위해 관련 문서를 우선적으로 살펴보도록 한다.

WKWebView

dev.apple.com/WKWebView

WKWebView 클래스는 앱 내 브라우저등과 같은 interactive한 웹 컨텐츠를 표시하기 위해 이용되는 객체이다.

선언은 아래와 같이 한다.

Declaration


class WKWebView: UIView

WKWebView 클래스는 UIView 클래스를 상속받고있다.

앱 내에 웹 컨텐츠를 내장하기 위해서는 WKWebView 클래스를 이용해야 한다.

이를 위해서는 WKWebView 객체를 생성하고, request를 보내 해당 요청에 대한 응답값을 load 하여 사용한다.

POST request를 보내기 위해서는 httpBody 프로퍼티를 사용해야 한다.

init(frame: configuration:) 메서드를 이용해 WKWebView 객체를 생성한 이후에는 웹 컨텐츠를 load 해야 한다.

예시 코드를 살펴보자.

import UIKit
import WebKit

class ViewController: UIViewController, WKUIDelegate {

    var webView: WKWebView! // WebView 인스턴스 선언

    override func loadView() {

        let webConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webView.uiDelegate = self)
        view = WebView
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let myURL = URL(string:"https://www.apple.com")
        let myRequest= URLRequest(url: myURL!)
        webView.load(myRequest)
    }
}

만일, 사용자에게 뒤로가기 & 앞으로가기 기능을 제공하고 싶다면 , goBack() 메소드와 goForward() 메소드를 Button 과 같은 인스턴스에 액션으로 연결해주면 된다.

새로고침은 reload() 메소드를 이용하도록 한다.

UserDefaults

dev.apple.com/UserDefaults

UserDefaults 클래스는 사용자의 기본값들을 저장해놓은 데이터베이스와의 접점을 제공한다.
해당 데이터베이스는 앱 실행시 지속적으로 키-값 쌍의 데이터를 저장한다.

Declaration

선언은 아래와 같이 한다.

class UserDefaults: NSObject

UserDefaults 클래스는 NSObject 클래스를 상속받고 있다.

UserDefaults 클래스는 기본 시스템과의 interacting을 위한프로그래밍 방식의 인터페이스를 제공한다.

기본 시스템을 통해 앱을 사용자의 취향에 맞게 커스텀 또한 가능하다.

런타임시, UserDefaults 객체를 이용하여 앱이 사용자의 기본 데이터베이스에서 사용하는 기본값을 읽는다.

UserDefaults 다양하고 편리한 메소드를 제공한다.

3. 코드 리뷰


//ViewController.swift
//
//  ViewController.swift
//  MyWebBrowser
//
//  Created by Yeojaeng on 2020/04/12.
//  Copyright © 2020 Yeojaeng. All rights reserved.
//

import UIKit
import WebKit



class ViewController: UIViewController {
    // MARK: - Properties
    // MARK: IBOutlets

    @IBOutlet var webView: WKWebView!                                   // 인터페이스 빌더에서 올려줬던 인스터스와 연결해준다.
    @IBOutlet var activityIndicator: UIActivityIndicatorView!

    // MARK: - Methods
    // MARK: Life Cycle
    override func viewDidLoad() {                                       // view가 로드된 이후 실행할 코드
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        self.webView.navigationDelegate = self                          // webView의 딜리게이트를 ViewController로 초기화

    }

    override func viewDidAppear(_ animated: Bool) {                     // view가 띄워진 이후 실행할 코드
        super.viewDidAppear(animated)

        let firstPageURL: URL?

        if let lastURL: URL = UserDefaults.standard.url(forKey: lastPageURLDefaultKey) {    // UserDefaults 객체를 통해 DB에서 마지막 URL값 가져오기
            firstPageURL = lastURL
        } else {
            firstPageURL = URL(string: "https://www.google.com")                            // lastURL 값이 없다면 firstpageURL을 구글로 초기화
        }

        guard let pageURL: URL = firstPageURL else {
            return
        }

        let urlRequset: URLRequest = URLRequest(url: pageURL)                               // 지정 URL로 Request 보내기
        self.webView.load(urlRequset)                                                       // 요청 결과값 뿌려주기
    }

    //MARK: IBActions
    @IBAction func goBack(_ sender: UIBarButtonItem) {                                      // 네비게이팅 뒤로가기 기능
        self.webView.goBack()
    }

    @IBAction func goForward(_ sender: UIBarButtonItem) {                                   // 네비게이팅 앞으로가기 기능
        self.webView.goForward()
    }

    @IBAction func refresh(_ sender: UIBarButtonItem) {                                     // 네비게이팅 새로고침 기능
        self.webView.reload()
    }

    //MARK: Custom Methods
    func showNetworkingIndicator() {
        self.activityIndicator.isHidden = false                                             // 액티비티네비게이터 프로퍼티 설정
        self.activityIndicator.startAnimating()                                             // 애니메이션 작동시키기
        UIApplication.shared.isNetworkActivityIndicatorVisible = true                       // 앱 인스턴스의 네트워크 활동 상태 제어
    }

    func hideNetworkingIndicator() {
        self.activityIndicator.isHidden = true
        self.activityIndicator.stopAnimating()
        UIApplication.shared.isNetworkActivityIndicatorVisible = false
    }

}

extension ViewController: WKNavigationDelegate {

    //MARK: WKNavigationDelegate
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        print("did finish navigation")

        if let appDelegate: AppDelegate = UIApplication.shared.delegate as? AppDelegate {
            appDelegate.lastPageURL = webView.url
        }

        webView.evaluateJavaScript("document.title") { (value: Any?, error:Error?) in
            if let error: Error = error {
                print(error.localizedDescription)
                return
            }

            guard let title: String = value as? String else {
                return
            }

            self.navigationItem.title = title
    }
        self.hideNetworkingIndicator()
    }

    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        print("did fail  navigation")
        print("\(error.localizedDescription)")

        self.hideNetworkingIndicator()
        let message: String = "오류발생\n" + error.localizedDescription


        // alert 인스턴스 생성
        let alert: UIAlertController
        alert = UIAlertController(title: "알림", message: message, preferredStyle: .alert)

        // alert창 내 ok 버튼 클릭시의 Action 생성
        let okAction: UIAlertAction
        okAction = UIAlertAction(title: "확인", style: UIAlertAction.Style.cancel, handler: nil)

        // alert에 Action 연결
        alert.addAction(okAction)

        self.present(alert, animated: true, completion: nil)
    }

    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        print("did start navigaion")
        self.showNetworkingIndicator()
    }
}
//AppDelegate.swift
//
//  AppDelegate.swift
//  MyWebBrowser
//
//  Created by Yeojaeng on 2020/04/12.
//  Copyright © 2020 Yeojaeng. All rights reserved.
//

import UIKit

/// 웹 뷰 마지막 페이지 주소를 UserDefaults 에서 관리하기 위한 키 값
let lastPageURLDefaultKey: String = "lastURL"


@available(iOS 13.0, *)
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    // MARK: - Properties
    var window: UIWindow?
    var lastPageURL: URL?


    //MARK: - Methods
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        self.lastPageURL = UserDefaults.standard.url(forKey: lastPageURLDefaultKey)         // 앱이 끝날때 URL 가져와서 저장하기.
        return true
    }

    func applicationWillResignActive(_ application: UIApplication) {
        let userDefaults: UserDefaults
        userDefaults = UserDefaults.standard

        userDefaults.set(self.lastPageURL, forKey: lastPageURLDefaultKey)                   // 앱이 종료될 떄 저장해놨던 lastPageURL을 userDefaults에 셋팅
        userDefaults.synchronize()
        // 비동기 업데이트를 통해
    }


    // MARK: UISceneSession Lifecycle

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    }


}


4. 정리


  • WKWebView 클래스는 앱 내 브라우저등과 같은 interactive한 웹 컨텐츠를 표시하기 위해 이용되는 객체이다.

  • 앱 내 웹 컨텐츠를 사용하기 위해서는 WKWebView 객체를 생성하고, request를 보내 해당 요청에 대한 응답값을 load 하여 사용한다.

  • UserDefaults 클래스는 사용자의 기본값들을 저장해놓은 데이터베이스와의 접점을 제공한다.
    해당 데이터베이스는 앱 실행시 지속적으로 키-값 쌍의 데이터를 저장한다.

  • 런타임시, UserDefaults 객체를 이용하여 앱이 사용자의 기본 데이터베이스에서 사용하는 기본값을 읽는다.

'iOS' 카테고리의 다른 글

[iOS] Delegate Pattern  (0) 2020.04.17
[iOS] UITableView 공식문서 번역 및 공부  (0) 2020.04.16
[iOS] TableView 정리  (0) 2020.04.16
[iOS] 옵셔널 , 함수, 클로저  (0) 2020.04.14
[iOS] 내 소개 어플리케이션  (0) 2020.04.14