Simulator Screen Recording - iPhone SE (3rd generation) - 2024-11-29 at 04.26.46.mov
위와 같이 플레이리스트 선택 화면이 나타날 때마다 균일하지 않게 왔다갔다 하는 문제가 있었다.
불러오는 데이터를 print로 찍어보면
⇒ 즉, Core Data에서 불러오는 쪽에 문제가 있다.
CoreDataPlaylistStorage
가 있고, readAll()
메서드에서 Core Data에 저장된 플레이리스트 데이터들을 불러온다.func readAll() async throws -> [Entity] {
try await context.perform {
let playlists = try self.context.fetch(self.fetchRequest)
return playlists.map { playlist in
let filter = MusicFilter(genres: playlist.filters.compactMap { MusicGenre(rawValue: $0) })
return MolioPlaylist(id: playlist.id,
name: playlist.name,
createdAt: playlist.createdAt,
musicISRCs: playlist.musicISRCs,
filter: filter
)
}
}
}
CoreDataPlaylistStorage 객체 내부에서는 NSFetchRequest
인스턴스 1개를 두고 각 메서드를 호출할 때마다 predicate
에 적절하게 필요한 쿼리를 할당해준다.
fetchRequest
는 같은 인스턴스⇒ 하지만 update()
메서드가 먼저 호출되고 난 후 readAll()
메서드를 호출하면 id == %@
조건의 쿼리가 그대로 남게 된다.
readAll()
메서드에서는 따로 기존 쿼리를 정리하는 로직 없이 그대로 사용하기 때문
final class CoreDataPlaylistStorage: PlaylistLocalStorage {
private let context: NSManagedObjectContext
**private let fetchRequest: NSFetchRequest<Playlist> = Playlist.fetchRequest()**
...
func readAll() async throws -> [Entity] {
try await context.perform {
let playlists = try self.context.fetch(self.fetchRequest)
return playlists.map { playlist in
let filter = MusicFilter(genres: playlist.filters.compactMap { MusicGenre(rawValue: $0) })
return MolioPlaylist(id: playlist.id,
name: playlist.name,
createdAt: playlist.createdAt,
musicISRCs: playlist.musicISRCs,
filter: filter
)
}
}
}
// Update
func update(_ entity: MolioPlaylist) async throws {
try await context.perform {
**// ❌ 여기서 설정된 쿼리가 그대로 남아 있는 채로 readAll() 메서드가 호출되면 해당 쿼리 조건에 맞는 엔티티들만 불러온다.**
**self.fetchRequest.predicate = NSPredicate(format: "id == %@", entity.id as CVarArg)**
do {
guard let playlist = try self.context.fetch(self.fetchRequest).first else {
throw CoreDataError.notFound
}
playlist.name = entity.name
playlist.musicISRCs = entity.musicISRCs
playlist.filters = entity.filter.genres.map(\\.rawValue)
try self.saveContext()
} catch {
throw CoreDataError.saveFailed
}
}
}
...
}
fetchRequest.predicate
의 쿼리 조건을 비워주고 데이터를 불러오도록 수정해주었다.
predicate는 옵셔널 값이기 때문에 nil을 넣을 수 있다.
func readAll() async throws -> [Entity] {
**fetchRequest.predicate = nil**
return try await context.perform {
let playlists = try self.context.fetch(self.fetchRequest)
return playlists.map { playlist in
let filter = MusicFilter(genres: playlist.filters.compactMap { MusicGenre(rawValue: $0) })
return MolioPlaylist(id: playlist.id,
name: playlist.name,
createdAt: playlist.createdAt,
musicISRCs: playlist.musicISRCs,
filter: filter
)
}
}
}