크게 두가지 일을 하시는 NSFetchedResultsController
Core Data만 단독으로 사용할 땐 데이터를 추가 또는 삭제를 한 뒤 데이터가 사용되는 TableView 등에 직접 reloadData()를 호출해서 수동으로 UI 업데이트를 해줘야 하지만, NSFetchedResultsController를 사용하면 Core Data의 context를 본인이 모니터링해서 saveContext()가 호출될 때마다 대신 업데이트를 합니다.
NSFetchedResultsController 라는 아이가 이런 일들을 대신 뒤처리를 해주니까 Delegate를 채용해야 하는데, 본문에 Optionally~ 라고 되어있듯이 delegate를 채용하지 않으면 해당 기능을 수행하지 않아요.
두번째 내용은 캐싱에 관한 내용입니다.
NSFetchedResultsController의 Cache 기능은 잘 사용하지 않아서 😅 내용을 더 공부한다면 후에 Cache에 관한 코드도 추가해보겠습니다.
제발 까먹지 말라고 적어두는 Core Data Singleton 구현 순서
// 1. class 만들기
class CoreDataManager {
// 2. Type Property, initializer 생성
static let shared = CoreDataManger()
private init() {}
// 3. context 생성
var context: NSManagedObjectContext { return persistentContainer.viewContext }
// 4. fetchedResultsController Property 생성
var fetchedResultsController: NSFetchedResultsController<MemoEntity>?
// 5. fetchMethod 만들기 (5-X는 method안에서 해야하는 내용)
// 5-1. context 생성
// 5-2. fetchRequest.sortDescriptors로 정렬 방법 설정
// 5-3. NSFetchedResultsController 초기화
// 5-4. do_catch문에서 delegate 채용
// 5-5. method 안에서 초기화한 NSFetchedResultsController를 위에 선언한 fetchedResultsController에 저장
// 5-6. controller.performFetch() 호출
// -------------------------------------------------------------------------------------
// https://developer.apple.com/documentation/coredata/nsfetchedresultscontroller#1661441
// -------------------------------------------------------------------------------------
// 먼훗날 까먹을 나 자신에게 - 애플 개발자 문서 들어가면 다 나와
func fetch(with viewController: NSFetchedResultsControllerDelegate) {
// 5-1
let fetchRequest: NSFetchRequest<<#CoreDataEntityType#>> = <#CoreDataEntityType#>.fetchRequest() // 2. fetchRequest() 호출
// 5-2
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "YourKey", ascending: false)]
// 5-3
let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
do {
controller.delegate = viewController // 5-4
fetchedResultsController = controller // 5-5
try controller.performFetch() // 5-6
} catch {
fatalError("Failed to fetch entities: \(error)")
}
}
}
// 6. predicateMethod 만들기 (6-X는 method안에서 해야하는 내용)
// 6-1. <#CoreDataEntityType#>.fetchRequest() 생성
// 6-2. predicate 생성
// 6-3. request.predicate에 만들어둔 predicate 저장
// 6-4. do_catch문에서 저장된 데이터의 배열을 가져오기
// 6-5. 첫번째 요소값 return
func predicate(id: Int) -> <#CoreDataEntityType#>? {
let request: NSFetchRequest<<#CoreDataEntityType#>> = <#CoreDataEntityType#>.fetchRequest() // 6-1
let predicate = NSPredicate(format: "data's Id == %i", id) // 6-2
request.predicate = predicate // 6-3
do {
let objects = try context.fetch(request) // 6-4
return objects.first // 6-5
} catch {
print(error)
}
return nil
}
관련 링크