SwiftUI를 사용하는 프로젝트에서
SDWebImage 라이브러리는 SDWebImageSwiftUI 를 사용해야한다.
(SDWebImageSwiftUI를 설치하면 자동으로 SDWebImage도 설치됨)
https://github.com/SDWebImage/SDWebImageSwiftUI
SDWebImageSwiftUI에서 제공해주는 WebImage를 통해 서버 이미지를 가져오게 되어있는데
채팅에서 사용자가 직접 업로드 해준 이미지에대해서만 다운로드를 못받아오는 현상이 있었는데
(사실 직접 업로드 여부는 관련 없었음)
사파리나 크롬에서는 해당 이미지가 정상적으로 보임.
WebImage(url: self.url, options: options, context: context)
.onProgress { receivedSize, totalSize in
}
.onFailure { error in
loadError = error
}
.onSuccess { image, data, cacheType in
}
.placeholder {
ZStack {
placeholder()
}
}
.resizable()
일단, onProgress에서 receivedSize가 0 -> totalSize 까지 사이즈는 정상적으로 내려왔다.
처음엔 onFailure 에서 나오는 에러가 "Downloaded image decode failed" 였기때문에
데이터 다운로드는 정상적으로 되었는데 이미지로 전환하면서 문제가 있나 싶어서
WebCoder를 설정해주는 방식으로 진행 해봤다.
1. AppDelegate에 앱 시작시, Coder 적용 > 동일 에러 발생
SDImageCodersManager.shared.addCoder(SDImageAWebPCoder.shared)
2. WebImage 생성할 때, context 설정 > 동일 에러 발생
WebImage(url: getImageURL(), options: .retryFailed, context: [.imageCoder: SDImageAWebPCoder.shared])
여기서 별개로 .retryFailed 를 options으로 설정해줬는데,
계속 실패하는 요청을 여러번 하다보니
WebImage 내부에서 해당 URL를 SDWebImage 블랙리스트로 추가하여 요청을 막는 현상이 발생되었다.
retryFailed 설정은 블랙리스트를 비활성화하는 설정이라 해당 현상은 방지할 수 있어서 추가했다.
SDWebImageRetryFailed : By default, when a URL fail to be downloaded, the URL is blacklisted so the library won’t keep trying. This flag disable this blacklisting.
다시 돌아와서 이미지 자체를 어디서 못받아오는지 확인하려고 라이브러리 내부 코드를 확인하니
애초에 requestImageWithURL로 이미지를 받아오는 부분에서 이미지 자체를 못받아 오고 있었다.
에러 코드는 SDWebImageErrorDomain - code: 1001
downloadedImage = nil, downloadedData = nil
흠,, 애초에 이미지를 못받아오는 거였네 🥲
SDWebImageErrorDomain - code: 1001 을 검색하니 해당 내용 발견!
https://github.com/SDWebImage/SDWebImage/issues/2824#issuecomment-527724645
생각해보니,, web으로 접속할 때 항상 로그인하고 시도했고, 쿠키 연동이 되었을터,,,
SDWebImage 공식 문서를 찾아보니 SDWebImageDownloaderRequestModifier 를 통해서 요청을 변경할 수 있다.
https://github.com/SDWebImage/SDWebImage/wiki/How-to-use#use-request-modifier-50
친절하게 샘플 코드도 존재함.
(위에 링크 접속하면 Objective-C 코드도 존재)
let requestModifier = SDWebImageDownloaderRequestModifier { (request) -> URLRequest? in
if (request.url?.host == "foo") {
var mutableRequest = request
mutableRequest.setValue("foo=bar", forHTTPHeaderField: "Cookie")
return mutableRequest
}
return request
};
SDWebImageDownloader.shared.requestModifier = requestModifier
3. 로그인할 때 인증 토큰을 세팅해주고,
로그아웃할 때 requestModifier를 초기화 해주었다. > 이미지 정상 다운로드
참고로, requestModifier 디폴트 값도 nil.
// 로그인
func login(_ info: MeResponse) {
me = info
let requestModifier = SDWebImageDownloaderRequestModifier { (request) -> URLRequest? in
if let accessToken = UserData.shared.accessToken {
var mutableRequest = request
mutableRequest.setValue(accessToken, forHTTPHeaderField: "Authorization")
return mutableRequest
}
return request
}
SDWebImageDownloader.shared.requestModifier = requestModifier
}
// 로그아웃
func logout() {
me = nil
SDWebImageDownloader.shared.requestModifier = nil
}
'iOS' 카테고리의 다른 글
[iOS-SwiftUI] ScrollView Paging 처리 (0) | 2024.03.06 |
---|---|
[iOS-SwiftUI] TabBar > NavigationLink 닫히는 이슈 (0) | 2023.07.20 |
[iOS] Firebase 호스팅 설정 (0) | 2020.09.23 |
[Xcode] git ignore 설정 (0) | 2020.07.02 |
[iOS] AVCaptureSession를 이용한 Barcode Scanner (0) | 2020.01.06 |