swift pdf 다운 및 열기 리뷰

sanghun Lee·2021년 1월 5일
0

Today I Learned

목록 보기
61/66

간략히 구현된 코드

import UIKit
import PDFKit
import WebKit

public class ViewController: UIViewController {
    @IBOutlet var webview: WKWebView!
		//webview라는 변수에 WKWebView를 연결해주기 위한 @IBOutlet 선언

		//PDFKit을 통해 받아온 PDFView()
    var pdfView = PDFView()
    var pdfURL: URL!

    public override func viewDidLoad() {
        super.viewDidLoad()
        
        DispatchQueue.main.asyncAfter(deadline: .now()+3) {
            self.dismiss(animated: true, completion: nil)
        }
    }
    
    public override func viewDidLayoutSubviews() {
        pdfView.frame = view.frame
    }
    // story board내의 open버튼에 연결된 action
    @IBAction func openPDFButtonPressed(_ sender: Any) {
       let pdfViewController = ViewController()
       pdfViewController.pdfURL = self.pdfURL
        print("self.pdfURL",self.pdfURL!)
        webview.loadFileURL(pdfURL, allowingReadAccessTo: pdfURL)
   }
    // story board내의 down버튼에 연결된 action
    @IBAction func downloadButtonPressed(_ sender: Any) {
        guard let url = URL(string: "https://www.tutorialspoint.com/swift/swift_tutorial.pdf") else { return }
        
        let urlSession = URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue())
        let downloadTask = urlSession.downloadTask(with: url)
        downloadTask.resume()
    }

}

extension ViewController:  URLSessionDownloadDelegate {
    public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        print("downloadLocation:", location)
        // create destination URL with the original pdf name
        guard let url = downloadTask.originalRequest?.url else { return }
        let documentsPath = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
        let destinationURL = documentsPath.appendingPathComponent(url.lastPathComponent)
        // delete original copy
        try? FileManager.default.removeItem(at: destinationURL)
        // copy from temp to Document
        do {
            try FileManager.default.copyItem(at: location, to: destinationURL)
            self.pdfURL = destinationURL
        
        } catch let error {
            print("Copy Error: \(error.localizedDescription)")
        }
    }
}

URL

  • URL을 명확히 알고 있는경우 아래와 같이 선언하며 nil이 될 경우 guard else를 통해 return 시키기도 한다.

    var pdfURL: URL! 의 경우 URL을 명확히 알지 못할경우에 표현하는 방식이다.

    → 위 예시 코드에서의 방식은 추후에 URL을 가져오게 된다.

guard let url = URL(string: "https://www.tutorialspoint.com/swift/swift_tutorial.pdf") else { return }

URLSession

URLSession은 HTTP를 포함한 몇 가지 프로토콜을 지원하고, 인증, 쿠키 관리, 캐시 관리 등을 지원하는 애플에서 제공하는 API 입니다.

let urlSession = URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue())
let downloadTask = urlSession.downloadTask(with: url)

downloadTask.resume()
  • configuration

위의 예시 코드를 보면 configuration: .default 와 같은 설정을 통해 URL유형을 생성한다

.default 가 가장 기본적인 옵션이며 .ephemeral (일회성 사용을 위함)등이 존재한다.

  • delegate

→ delegate 를 통해서 받은 데이터를 위임할 대상을 찾을 수 있다. 다양한 이벤트 발생 시 delegate를 통해 위임 시킬 수있으며 넣지 않게 되면 자동으로 시스템이 별도로 생성한 델리게이트가 이를 처리하게 된다.

인증 실패 , 서버로부터 데이터 받음, 데이터 캐싱할 예정 등일 때 사용한다

  • delegateQueue

→ 설정해주지 않으면 defaultQueue가 생성된다.

  • OperationQueue()

데이터 처리방식을 queue 형태로 실행시키기 위해서 사용된다

→ 더 찾아봐야할것같습니다..

downloadTask

func donwloadTask(with: URLRequest) → uRLSessionDownloadTask

downloadTask는 URLRequest의 obj를가져오고 그 결과를 저장합니다

        let downloadTask = urlSession.downloadTask(with: url)
        downloadTask.resume()

urlSession의 downloadTask 메서드를 url이라고 미리 선언해놓은 것을 이용하여 불러옵니다.

resume()메서드를 통해서 실행한 코드입니다.

  • PDFKit

ios에서 지원하는 api이며 pdf관련 메서드 사용을 위해서 필요하다.

  • @IBOutlet var webview: WKWebView!

viewDidLayoutSubviews()

view controller에 view의 subviews를 꾸며주기 위해 사용 ? 뭐지 ..

import UIKit
   
 public override func viewDidLayoutSubviews() {
				//PDFView()는 UIView클래스를 반환해주는데 그 내부의 메서드? 속성? 이 frame이다.
				//이를 view.frame으로 할당해준 것!
        pdfView.frame = view.frame
    }

viewController의 경계(크기등) 이 변경되면 알아서 변경해주게 되어 있는데 이때 subview의 위치 변경 등이 일어날 때 실행되는 메서드이다

해당 메서드를 override시켜 pdfView.frame을 view.frame과 동일하게 맞춰준 것.

URLSession 확장

기존 viewController 클래스에 URLSessionDownloadDelegate 를 넣어줌 ? 확장함 ??

기존 클래스의 urlSession에 몇가지 속성을 설정해줌→ 추후 기입예정

url을 다시 설정해주고 documentsPath변수에 FileManager를 이용한 default url을 찾아서 넣는다

destinationURL에 마지막 url을 넣어주고 생성된 파일(temp 폴터)을 잠시 지워준다. 그리고 Document폴더에 옮긴다.

해당 위치에 pdfURL이라는 변수에 destinationURL을 설정해준다.

try FileManager.default.copyItem(at: location, to: destinationURL)

나머지는 에러처리

extension ViewController:  URLSessionDownloadDelegate {
    public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        // create destination URL with the original pdf name
        guard let url = downloadTask.originalRequest?.url else { return }
        let documentsPath = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
        let destinationURL = documentsPath.appendingPathComponent(url.lastPathComponent)
        // delete original copy
        try? FileManager.default.removeItem(at: destinationURL)
        // copy from temp to Document
        do {
            try FileManager.default.copyItem(at: location, to: destinationURL)
            self.pdfURL = destinationURL
        
        } catch let error {
            print("Copy Error: \(error.localizedDescription)")
        }
    }
}

참고

  • Swift PDF파일 다운 및 열기 예시 블로그

Download, Store, and View PDF in swift

  • Download file in background 애플 개발자 문서

Apple Developer Documentation

  • Downloading Files from Websites 애플 개발자 문서

Apple Developer Documentation

  • URL

Declaring URL in Swift 3

  • URLSession

Swift, URLSession가 무엇인지, 어떻게 사용하는지 알아봅니다.

Apple Developer Documentation

  • downloadTasks

Apple Developer Documentation

  • viewDidLayoutSubviews()

Apple Developer Documentation

profile
알고리즘 풀이를 담은 블로그입니다.

0개의 댓글