안녕하세요.
오늘은 WkWebView에서 이미지를 받아 사진첩에 저장하는 방법 그 2번째 이야기입니다.
기존에 스키마를 통해 이미지 서버 URL로 이미지를 저장하는 부분에 대해서 이야기하였습니다.
https://nplayground.tistory.com/57
swift WkWebView 이미지 UIImageWriteToSavedPhotosAlbum 다운로드 및 저장
안녕하세요.오늘은 WkWebView에서 이미지를 받아 사진첩에 저장하는 방법에 관하여 생각해 보겠습니다.일단 해당 부분 웹에 대해 만들어야 하고 이건 과거 글https://nplayground.tistory.com/49 iOS 웹뷰 wit
nplayground.tistory.com
오늘은 그 두 번째 방법인 canvas.toDataURL. 형식으로 만들어져 data:image/png;base64 형식으로 내려오는 이미지를
사진첩에 저장하는 방법과 이 작업을 수행하던 중 발생한 이슈에 대해서 이야기할까 합니다.
일단 간단히 해당 부분 로직 구현에 대해 설명하자면
- 웹뷰 세팅
- 웹뷰에서 이벤트 catch
- catch 한 데이터 필요 부분 축출
- Base64 문자열을 NSData로 변환
- NSData를 UIImage로 변환
- UIImage를 사진첩에 저장
6단계로 진행하면 된다.
1번 단계
먼저 1번 단계는 이전 글인( WkWebView에서 이미지를 받아 사진첩에 저장하는 방법)으로 확인하면 되고
2번 단계
아래 이미지 웹뷰델리게이트 부분을 상속받아 사용하면 된다.
3번 단계
data:image/png;base64 Catch 하여 해당 String을 가져온다
4번 단계
let cleanBase64String = urlString.replacingOccurrences(of: "data:image/png;base64,", with: "")
data:image/png;base64, 뺀 나머지 데이터 String 부분만 가져와서
5번 단계
if let imageData = Data(base64Encoded: cleanBase64String, options: .ignoreUnknownCharacters) {
4번 단계의 데이터 String인 Base64 문자열을 NSData로 변환해 준다.
}
6번 단계
NSData로 변환한 imageData를 UIImage로 변경해 준다.
let image = UIImage(data: imageData)
먼저 1번 단계는 이전 글인( WkWebView에서 이미지를 받아 사진첩에 저장하는 방법)에서와 마찬가지로 사진첩에 저장을 한다.
self.saveImage(tImage: image)
이 와 같이 6단계를 진행하면 웹페이지에서 data:image/png;base64 , data:image/jpg;base64 형식으로 이미지를 다운로드하여 사진첩에 저장할 수 있다.
위에서 보이는 것처럼 간단할걸 같지만 특이한 이슈가 있어서 몇 시간 동안 기능이 작동이 안 돼서 나와 같은 일이 반복되지 않도록
해당 이슈를 상세히 적어 놓겠다.
6단계를 끝내고 개발자 테스트(사진첩 저장확인) 마무리한 뒤 QA를 맡기고 이상 없이 진행되었다.
- 하지만 갑자기 나타난 이슈 (tainted 이슈)
한 1주 후 갑자기 저장이 안 된다는 이슈를 전달받았다.
웹페이지 담당자는 해당 소스를 1주일치를 돌려 원복 했지만 여전히 웹페이지에서 이미지 저장 기능이 되지 않았다.
몇 시간 동안 테스트한 결과는
1. about:blank 이슈
해당 부분에서 url.absoluteString 로그를 찍었을 때 어떠한 데이터도 들어오지 않고 ' about:blank ' 만 계속 나오는 이슈가 발생되었다.
어떠한 데이터가 들어와야지 움직이는데 ' about:blank ' 들어오니 앱에서 정확한 정보를 알수 없었지만
어쨌든 이 이벤트를 진행시키기 위해 원인을 찾기 시작하였다.
2. securityerror the operation not insecure 에러
일단 다시 웹 페이지 개발자 분이 로그를 찍으니 ' securityerror the operation not insecure ' 에러가 떨어 저서 앱에서 ' about:blank '를 전달받는 것이었다.
그런데 왜 갑자기 잘되던 게 ' securityerror the operation not insecure ' 이란 로그가 나타났을까???.....
어느 부분을 건드려서 해당 ' securityerror the operation not insecure ' 이란 로그가 나타났을까???.....
일단 google과 github를 찾기 시작하였다.
몇 시간 동안 원인을 찾다. 의심이 가는 부분은.
Canvas image crossplatform insecure error
I have this code for create canvas image from different server urls function getBase64Image(imageUri) { var canvas = document.createElement("canvas"); ctx = canvas.getContext("2d"); ...
stackoverflow.com
문제의 원인 발견 "tainted"
Drawing cross-domain content on html5 canvas will cause it to be "tainted" 이 부분이었다.
한글로 해석하자면
" 크로스 도메인 콘텐츠를 포함한 Html5 Canvas에 대한 최신 정보입니다.
다음은 크로스 도메인 콘텐츠가 html5 캔버스에 어떤 영향을 미치는지, 크로스 도메인 콘텐츠에 적용되는 보안 제한 내에서 작업하는 방법에 대한 최신 정보입니다.
오늘(2016년 1월) 업데이트가 유용한 이유는 캔버스를 손상시키지 않고 크로스 도메인 이미지를 캔버스에 그릴 수 있는 여러 가지 새로운 방법이 있기 때문입니다.
html5 캔버스에 크로스 도메인 콘텐츠를 그리면 "오염"이 발생합니다.
캔버스에 다른 도메인의 이미지를 그리면 캔버스에 표시됩니다. 다른 도메인의 리소스에 액세스 하는 것을 "Cross Origin Resource Sharing"이라고 하며 일반적으로 줄여서 "CORS"라고 합니다.
CORS 콘텐츠(예: 이미지)를 그리면 보안상의 이유로 캔버스가 "오염"됩니다.
캔버스가 오염된 경우 다음 캔버스 및 컨텍스트 메서드를 사용할 수 없습니다.
- context.getImageData캔버스의 픽셀 데이터를 가져오려면
- canvas.toDataURL캔버스를 이미지로 내보내려면
캔버스를 CORS 보안 제한을 위반하도록 "속일" 수는 없습니다. 시도조차 하고 싶지 않을 것입니다! 하지만 CORS 보안 제한을 충족 함으로써 캔버스를 오염시키지 않고 교차 출처 이미지를 그릴 수 있습니다.
캔버스를 오염시키지 않도록 이미지를 처리하는 "일반적인"(그리고 가장 간단한) 방법:
이미지를 웹페이지와 동일한 도메인에 넣으세요. 콘텐츠를 제공하는 여러 개의 물리적 서버가 있을 수 있지만 이미지 도메인은 캔버스를 만드는 html 코드(또는 javascript 코드)와 동일해야 합니다. CORS 제한이 충족되고 캔버스가 오염되지 않습니다. "
또한 한 가지의 힌트는 CSS와 SVG 적용으로 인한 tainted였다
결국 아래 문구를 찾고 원인을 알 수 있었다.
이는 SVG 문서에 요소가 있기 때문일 수 있습니다.
보안상의 이유로, Safari v.9 이상에서는 이 요소를 캔버스에 그리면 캔버스가 오염됩니다.
SVG에서 제거하는 것 외에는 해결 방법이 없습니다 ;-)
Ps: Edge 이전의 IE도 SVG가 그려지면 캔버스를 오염시킵니다.
CSS 담당자에게 CSS에 포함된 SVG 확인을 요청했고 최근 1주일 사이에 CSS에 SVG포함된 걸 알 수 있었다.
그리고 해당 부분 삭제 후 정상 작동 하는 것을 알 수 있었다.
- 마지막 결론
1. about:blank
2. securityerror the operation not insecure
3. tainted
위의 3가지 이슈의 해결책은 CSS에 포함된 SVG 삭제입니다.
CSS에 SVG포함되어있으면 캔버스에 크로스 도메인 콘텐츠를 그리면 "오염"이 발생합니다.라는 항목이 있고
iOS 보안상 data:image/png;base64 형태로 작업을 진행하려면 "tainted" 없어야 가능하다.
다음에 이러한 이슈가 나타나면 저 부분은 확인하면 해결이 가능하다.
끝!
'iOS, Swift 개발' 카테고리의 다른 글
Swift 하드 코딩, 날코딩 관리 (3) | 2024.11.11 |
---|---|
Swift WKWebview 웹뷰 공통 모듈 구현 (0) | 2024.11.05 |
swift WkWebView 이미지 UIImageWriteToSavedPhotosAlbum 다운로드 및 저장 (0) | 2024.08.22 |
Swift 스키마(scheme) 처리 및 웹뷰 처리(WKWebView evaluateJavaScript) (0) | 2024.08.09 |
App store 앱 연령 등급 정보에 대한 업데이트 이슈 (0) | 2024.08.05 |