사내 어플 기능중 이루미(현재 업무를 도와주시는분..! 피고용자라고 생각하면 편함)와의 채팅 페이지에서 이루미 혹은 고객이 보낸 파일이 안열리는 이슈가 발생했음.
크롬 혹은 사파리를 통한 웹 브라우저에서는 정상적으로 작동하는데, 네이티브앱(안드로이드 포함)에서 작동이 안된다는건 앱에서 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
}
}
이런식으로하게 되면
요런식으로 잘 작동하는거를 볼 수 있다..!