[iOS - Swift] WKWebview에서 S3에 있는 파일 다운받기

신태원·2023년 2월 9일
0

iOS

목록 보기
3/3

사내 어플 기능중 이루미(현재 업무를 도와주시는분..! 피고용자라고 생각하면 편함)와의 채팅 페이지에서 이루미 혹은 고객이 보낸 파일이 안열리는 이슈가 발생했음.

크롬 혹은 사파리를 통한 웹 브라우저에서는 정상적으로 작동하는데, 네이티브앱(안드로이드 포함)에서 작동이 안된다는건 앱에서 access를 거부하고 있다는 의미.. 인것 같았음.

그래서 삽질을 꽤 많이했음. S3 SDK도 깔아보고(파일이 S3 서버에 올라가있기때문) info.plist도 열심히 건들여보고, ChatGPT한테 이것저것 물어보고 각종 시도를 해봤지만 실패…

그리고 끝내 해결한 방법은

위 사진처럼 info.plist 설정 YES 로 추가해주고 현재 WKWebview를 띄워주고있는 View Controller에 아래와 같은 코드 추가

//MARK: - WKDownloadDelegate
extension MainWebViewController: WKDownloadDelegate {
    
    @available(iOS 14.5, *)
    func webView(_ webView: WKWebView, navigationAction: WKNavigationAction, didBecome download: WKDownload) {
        download.delegate = self
    }
    
    @available(iOS 14.5, *)
    func download(_ download: WKDownload, decideDestinationUsing response: URLResponse, suggestedFilename: String, completionHandler: @escaping (URL?) -> Void) {
     
        let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        let fileURL = documentsDirectory.appendingPathComponent(suggestedFilename)
        print("File URL: \(fileURL)")
        
        let documentInteractionController = UIDocumentInteractionController(url: fileURL)
        documentInteractionController.delegate = self
        documentInteractionController.presentPreview(animated: true)
        
        completionHandler(fileURL)
    }
    
    @available(iOS 14.5, *)
    func downloadDidFinish(_ download: WKDownload) {
        print("File Download Success")
        
    }
    
    @available(iOS 14.5, *)
    func download(_ download: WKDownload, didFailWithError error: Error, resumeData: Data?) {
        print(error)
    }
}

그리고 이 부분도 함께 추가해준다.

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

        if navigationAction.request.url?.scheme == "blob" {
            return decisionHandler(.download)
        }
        return decisionHandler(.allow)    
    }

현재 다운로드 버튼에 걸려있는 링크가 blob:http~ 로 시작하는데

blob은 “JavaScript에서 Blob(Binary Large Object, 블랍)은 이미지, 사운드, 비디오와 같은 멀티미디어 데이터를 다룰 때 사용할 수 있습니다.” 라고합니다. 궁금하면 https://heropy.blog/2019/02/28/blob/ ← 고고

그래서 현재 내가 취한 액션(navigationAction) 이 누른 ulr의 scheme이 blob 이다?? 다운로드 실시! 라는 의미

제일 중요한 부분은 이 부분인데

@available(iOS 14.5, *)
    func download(_ download: WKDownload, decideDestinationUsing response: URLResponse, suggestedFilename: String, completionHandler: @escaping (URL?) -> Void) {
     
        let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        let fileURL = documentsDirectory.appendingPathComponent(suggestedFilename)
        print("File URL: \(fileURL)")
        
        let documentInteractionController = UIDocumentInteractionController(url: fileURL)
        documentInteractionController.delegate = self
        documentInteractionController.presentPreview(animated: true)
        
        completionHandler(fileURL)
    }

정확히 100프로 맞는지는 모르겠다. 근데 FileManger를 이용해서, documentDirectory에 저장을 해주고, 방금 저장한 그 파일을 미리보기로 띄워주면서 다운로드 여부를 결정할 수 있게 해준다.

documentInteractionControllerViewControllerForPreview 함수는 따로 정의해준 함수이다.

밑의 코드 참고 ㄱㄱ

extension MainWebViewController: UIDocumentInteractionControllerDelegate {
    func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
        return self
    }
}

이런식으로하게 되면

요런식으로 잘 작동하는거를 볼 수 있다..!

profile
일단 배우는거만 정리해보자 차근차근,,

0개의 댓글