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을 명확히 알고 있는경우 아래와 같이 선언하며 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은 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 형태로 실행시키기 위해서 사용된다
→ 더 찾아봐야할것같습니다..
func donwloadTask(with: URLRequest) → uRLSessionDownloadTask
downloadTask는 URLRequest의 obj를가져오고 그 결과를 저장합니다
let downloadTask = urlSession.downloadTask(with: url)
downloadTask.resume()
urlSession의 downloadTask 메서드를 url이라고 미리 선언해놓은 것을 이용하여 불러옵니다.
resume()
메서드를 통해서 실행한 코드입니다.
ios에서 지원하는 api이며 pdf관련 메서드 사용을 위해서 필요하다.
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과 동일하게 맞춰준 것.
기존 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)")
}
}
}
Download, Store, and View PDF in swift
Swift, URLSession가 무엇인지, 어떻게 사용하는지 알아봅니다.