-
Notifications
You must be signed in to change notification settings - Fork 0
[#585] 프로필 사진 수정이 반영되지 않는 문제를 해결한다 #586
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 5 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
5f78a4a
feat: 프로필 이미지 데이터 유스케이스 추가
opficdev d5c3dcc
feat: 프로필 이미지 메모리 캐시 저장소 추가
opficdev a1a3785
feat: Nexa로 프로필 이미지 데이터 요청
opficdev 41e90f3
refactor: 프로필 아바타에서 CacheableImage 제거
opficdev 285fe06
chore: 버전 1.2.5로 업
opficdev 8cd6dc4
feat: Nexa 1.1.1 적용
opficdev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
Application/DevLogData/Sources/Protocol/ProfileImageDataService.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| // | ||
| // ProfileImageDataService.swift | ||
| // DevLogData | ||
| // | ||
| // Created by opfic on 6/11/26. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| public protocol ProfileImageDataService { | ||
| func fetchImageData(from url: URL) async throws -> Data | ||
| } |
39 changes: 39 additions & 0 deletions
39
Application/DevLogData/Sources/Repository/ProfileImageDataRepositoryImpl.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| // | ||
| // ProfileImageDataRepositoryImpl.swift | ||
| // DevLogData | ||
| // | ||
| // Created by opfic on 6/11/26. | ||
| // | ||
|
|
||
| import Foundation | ||
| import DevLogDomain | ||
|
|
||
| public final class ProfileImageDataRepositoryImpl: ProfileImageDataRepository { | ||
| private let service: ProfileImageDataService | ||
| private let store: MemoryCacheStore | ||
|
|
||
| public init( | ||
| service: ProfileImageDataService, | ||
| store: MemoryCacheStore | ||
| ) { | ||
| self.service = service | ||
| self.store = store | ||
| } | ||
|
|
||
| public func fetchImageData(from url: URL) async throws -> Data { | ||
| do { | ||
| let data = try await service.fetchImageData(from: url) | ||
| store.setValue(data, forKey: Self.cacheKey(for: url)) | ||
| return data | ||
| } catch { | ||
| if let data: Data = store.value(forKey: Self.cacheKey(for: url)) { | ||
| return data | ||
| } | ||
| throw error | ||
| } | ||
| } | ||
|
|
||
| private static func cacheKey(for url: URL) -> String { | ||
| "profileImageData:\(url.absoluteString)" | ||
| } | ||
| } |
89 changes: 89 additions & 0 deletions
89
Application/DevLogData/Tests/Repository/ProfileImageDataRepositoryImplTests.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| // | ||
| // ProfileImageDataRepositoryImplTests.swift | ||
| // DevLogDataTests | ||
| // | ||
| // Created by opfic on 6/11/26. | ||
| // | ||
|
|
||
| import Foundation | ||
| import Testing | ||
| @testable import DevLogData | ||
|
|
||
| struct ProfileImageDataRepositoryImplTests { | ||
| @Test("캐시가 있어도 원격 이미지 데이터를 다시 요청하고 성공 데이터를 저장한다") | ||
| func 캐시가_있어도_원격_이미지_데이터를_다시_요청하고_성공_데이터를_저장한다() async throws { | ||
| let cachedData = Data([1, 2, 3]) | ||
| let remoteData = Data([4, 5, 6]) | ||
| let service = ProfileImageDataServiceSpy(data: cachedData) | ||
| let store = ProfileImageMemoryCacheStoreSpy() | ||
| let repository = ProfileImageDataRepositoryImpl(service: service, store: store) | ||
| let url = URL(string: "https://example.com/avatar.png")! | ||
|
|
||
| _ = try await repository.fetchImageData(from: url) | ||
| service.data = remoteData | ||
| let data = try await repository.fetchImageData(from: url) | ||
|
|
||
| #expect(data == remoteData) | ||
| #expect(service.calledURLs == [url, url]) | ||
| #expect(store.storedData == remoteData) | ||
| } | ||
|
|
||
| @Test("원격 이미지 요청 실패 시 메모리 캐시 데이터를 반환한다") | ||
| func 원격_이미지_요청_실패_시_메모리_캐시_데이터를_반환한다() async throws { | ||
| let cachedData = Data([1, 2, 3]) | ||
| let service = ProfileImageDataServiceSpy(data: cachedData) | ||
| let store = ProfileImageMemoryCacheStoreSpy() | ||
| let repository = ProfileImageDataRepositoryImpl(service: service, store: store) | ||
| let url = URL(string: "https://example.com/avatar.png")! | ||
|
|
||
| _ = try await repository.fetchImageData(from: url) | ||
| service.error = ProfileImageDataRepositoryImplTestsError.serviceFailed | ||
| let data = try await repository.fetchImageData(from: url) | ||
|
|
||
| #expect(data == cachedData) | ||
| #expect(service.calledURLs == [url, url]) | ||
| } | ||
| } | ||
|
|
||
| private final class ProfileImageDataServiceSpy: ProfileImageDataService { | ||
| var data: Data | ||
| var error: Error? | ||
| private(set) var calledURLs: [URL] = [] | ||
|
|
||
| init(data: Data) { | ||
| self.data = data | ||
| } | ||
|
|
||
| func fetchImageData(from url: URL) async throws -> Data { | ||
| calledURLs.append(url) | ||
|
|
||
| if let error { | ||
| throw error | ||
| } | ||
|
|
||
| return data | ||
| } | ||
| } | ||
|
|
||
| private final class ProfileImageMemoryCacheStoreSpy: MemoryCacheStore { | ||
| private var values = [String: Any]() | ||
| private(set) var storedData: Data? | ||
|
|
||
| func value<T: Codable>(forKey key: String) -> T? { | ||
| values[key] as? T | ||
| } | ||
|
|
||
| func setValue<T: Codable>(_ value: T?, forKey key: String) { | ||
| guard let value else { | ||
| values.removeValue(forKey: key) | ||
| return | ||
| } | ||
|
|
||
| values[key] = value | ||
| storedData = value as? Data | ||
| } | ||
| } | ||
|
|
||
| private enum ProfileImageDataRepositoryImplTestsError: Error { | ||
| case serviceFailed | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
Application/DevLogDomain/Sources/Protocol/ProfileImageDataRepository.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| // | ||
| // ProfileImageDataRepository.swift | ||
| // DevLogDomain | ||
| // | ||
| // Created by opfic on 6/11/26. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| public protocol ProfileImageDataRepository { | ||
| func fetchImageData(from url: URL) async throws -> Data | ||
| } |
12 changes: 12 additions & 0 deletions
12
...Domain/Sources/UseCase/UserData/Fetch/ProfileImageData/FetchProfileImageDataUseCase.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| // | ||
| // FetchProfileImageDataUseCase.swift | ||
| // DevLogDomain | ||
| // | ||
| // Created by opfic on 6/11/26. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| public protocol FetchProfileImageDataUseCase { | ||
| func execute(from url: URL) async throws -> Data | ||
| } |
20 changes: 20 additions & 0 deletions
20
...in/Sources/UseCase/UserData/Fetch/ProfileImageData/FetchProfileImageDataUseCaseImpl.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| // | ||
| // FetchProfileImageDataUseCaseImpl.swift | ||
| // DevLogDomain | ||
| // | ||
| // Created by opfic on 6/11/26. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| public final class FetchProfileImageDataUseCaseImpl: FetchProfileImageDataUseCase { | ||
| private let repository: ProfileImageDataRepository | ||
|
|
||
| public init(_ repository: ProfileImageDataRepository) { | ||
| self.repository = repository | ||
| } | ||
|
|
||
| public func execute(from url: URL) async throws -> Data { | ||
| try await repository.fetchImageData(from: url) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
Application/DevLogInfra/Sources/Service/ProfileImageDataServiceImpl.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| // | ||
| // ProfileImageDataServiceImpl.swift | ||
| // DevLogInfra | ||
| // | ||
| // Created by opfic on 6/11/26. | ||
| // | ||
|
|
||
| import Foundation | ||
| import Nexa | ||
| import DevLogData | ||
|
|
||
| final class ProfileImageDataServiceImpl: ProfileImageDataService { | ||
| func fetchImageData(from url: URL) async throws -> Data { | ||
| try await NXAPIClient( | ||
| configuration: NXClientConfiguration(baseURL: url) | ||
| ) | ||
| .get(url.absoluteString) | ||
| .timeout(10) | ||
| .intercept(ProfileImageDataCachePolicyInterceptor()) | ||
| .validate(.successStatusCode) | ||
| .raw() | ||
| .data | ||
| } | ||
| } | ||
|
|
||
| private struct ProfileImageDataCachePolicyInterceptor: NXHTTPInterceptor { | ||
| func intercept( | ||
| context: NXRequestExecutionContext, | ||
| next: @escaping @Sendable (NXRequestExecutionContext) async throws -> NXRawResponse | ||
| ) async throws -> NXRawResponse { | ||
| var request = context.request | ||
| request.cachePolicy = .reloadIgnoringLocalCacheData | ||
| return try await next(context.replacingRequest(request)) | ||
| } | ||
| } | ||
115 changes: 0 additions & 115 deletions
115
Application/DevLogPresentation/Sources/Common/Component/CacheableImage.swift
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.