
코어데이터를 사용하는 방법을 연습하다가 생긴 일이다. 먼저 entity로는 UserMO와 JokeMO 두개가 있다.


User와 Joke는 Model도 있다.


여기서 보면 알 수 있듯이 User는 Joke 배열을 가지고 있다. 때문에 특정한 User의 특정 카테고리를 갖는 Joke만 선별하고 싶은 과정에서 문제가 있었다.
func fetchWithPredicate(currentUser: User, currentCategory: Category) -> [Joke] {
var jokes = [Joke]()
let fetchRequest: NSFetchRequest<UserMO> = UserMO.fetchRequest()
let idPredicate = NSPredicate(format: "id = %@", currentUser.id as CVarArg)
fetchRequest.predicate = idPredicate
if let result = try? appDelegate.container.viewContext.fetch(fetchRequest) {
let jokesData = object.jokes as! Set<JokeMO>
result.forEach { jokeData in
let data = Joke(id: jokeData.id!, content: jokeData.content!, category: Category(rawValue: Int(jokeData.category))!)
jokes.append(data)
if data.category == currentCategory {
jokes.append(data)
}
}
}
return jokes
}
처음에는 이러한 코드를 작성했다. 일단 NSPredicate를 사용해 user의 id로 특정한 userMO를 가져오고 그렇게 가져온 userMO를 fetch해서 user의 모든 데이터를 가져온다. 그 후 안의 내용은 모두 fetch 되어 있는 상태니 NSSet로 가져와진 jokes 데이터를 타입캐스팅하고 그 안에서 currentCategory와 맞는 Joke만 배열에 추가해서 return 한다.
근데 이렇게 하면 일단 모든 정보를 가져와서 if문으로 걸러주기에 굳이 알 필요 없는 데이터까지 전부 가져온다는 생각이 들었다. 그래서 찾은 방법이 이것이다.
func fetchWithPredicate(currentUser: User, currentCategory: Category) -> [Joke] {
var jokes = [Joke]()
let fetchRequest: NSFetchRequest<JokeMO> = JokeMO.fetchRequest()
let idPredicate = NSPredicate(format: "user.id = %@ AND category = %x", currentUser.id as CVarArg, Int16(currentCategory.rawValue))
fetchRequest.predicate = idPredicate
if let result = try? appDelegate.container.viewContext.fetch(fetchRequest) {
result.forEach { jokeData in
let data = Joke(id: jokeData.id!, content: jokeData.content!, category: Category(rawValue: Int(jokeData.category))!)
jokes.append(data)
}
}
return jokes
}
relation을 통해 Joke역시 User에 대한 정보를 가지고 있다. 본인을 들고 있는 User에 대해서! 그래서 처음부터 JokeMO에서 NSPredicate로 거름망처럼 조건을 주었다. user.id를 통해 User의 id로 거르고, 그 안에서 category로 거른다. 그 후 fetch한 데이터를 새로운 Joke타입으로 만들어서 배열에 추가해 반환하면 끝!
코어데이터의 개념에 대해서 더 파봐야겠다는 생각을 했다. predicate를 잘 쓰면 아주 적은 비용으로 원하는 데이터만 가져올 수 있다!
'🍎 iOS & 🔹 Flutter > 🔥 트러블 슈팅' 카테고리의 다른 글
[iOS] Image url 통해 가져와서 view에 띄우거나 갤러리 다운로드하는 방법 2가지 비교 (0) | 2024.02.14 |
---|---|
[iOS] UICollectionViewFlowLayout으로 Pinterest Layout 구현하기 (0) | 2024.01.31 |
[iOS] Test 파일을 넣을 Asset 생성시 오류_ Bundle 사용 (1) | 2024.01.28 |
[iOS] TableViewCell에서 layoutMarginsGuide 사용 (0) | 2024.01.06 |
[iOS] storyboard에서 custom init을 한 경우 required init이 필요한 이유 (0) | 2023.11.09 |