PlanBee 복귀 유저를 위해서 Firestore에 저장해둔 데이터를 받아와서 CoreData에 저장하는 작업을 하던 중 에러가 나오는 상황
Task {
if let todoList = await FirestoreManager.shared.getTodoList(strDate: formattedDate) {
for todo in todoList {
_ = CoreDataManager.shared.saveTodoData(todo: todo)
}
}
}
func saveTodoData(todo: Todo) -> Bool {
guard let context = context else { return false }
guard let entity = NSEntityDescription.entity(
forEntityName: planEntityName, in: context
) else { return false }
let object = NSManagedObject(entity: entity, insertInto: context)
object.setValue(todo.id, forKey: Todokeys.uuid.key)
object.setValue(todo.content, forKey: Todokeys.content.key)
object.setValue(todo.date, forKey: Todokeys.date.key)
object.setValue(todo.priority, forKey: Todokeys.priority.key)
object.setValue(todo.done, forKey: Todokeys.done.key)
do {
try context.save()
return true
} catch {
print("error: \(error.localizedDescription)")
return false
}
}
CoreData에서 대량의 데이터를 고속 처리하는 것이 문제가 되어 에러가 발생하는 것이라고 추론 가능하다.
NSBatchInsertRequest
를 사용하여 대량의 데이터를 한 번에 삽입할 수 있게 수정한다.
NSBatchInsertRequest
란?Task {
if let todoList = await FirestoreManager.shared.getTodoList(strDate: formattedDate) {
if !todoList.isEmpty {
CoreDataManager.shared.saveTodoDataAtOnce(todos: todoList)
}
}
}
func saveTodoDataAtOnce(todos: [Todo]) {
guard let context = context else { return }
let object = todos.compactMap { data -> [String: Any]? in
let todo: [String: Any] = [
Todokeys.uuid.key: data.id,
Todokeys.content.key: data.content,
Todokeys.date.key: data.date,
Todokeys.priority.key: data.priority,
Todokeys.done.key: data.done
]
return todo
}
// NSBatchInsertRequest를 사용하면 대량의 데이터를 효율적으로 CoreData에 추가할 수 있습니다.
// 단일 요청으로 여러 객체를 추가할 수 있으므로 성능 향상을 기대할 수 있습니다.
let batchInsertRequest = NSBatchInsertRequest(entityName: planEntityName, objects: object)
do {
let result = try context.execute(batchInsertRequest) as? NSBatchInsertResult
if let success = result?.result as? Bool, success {
print("Batch insert successful")
return
}
} catch {
print("error: \(error.localizedDescription)")
return
}
}
NSBatchInsertRequest
를 사용하여 아래와 같이 Firestore로부터 데이터를 받아온 후 CoreData에 대량의 데이터를 한 번에 삽입할 수 있게 만들었습니다. (지난 6개월간 데이터 모두 받아와서 저장하는 예시)
※ 추가적으로 NSBatchDeleteRequest
를 사용하면 한 번에 모든 데이터를 삭제할 수 있습니다.
func removeAllPlanData() {
guard let context = context else { return }
let entityNames: [String] = [planEntityName]
for entity in entityNames {
let fetrequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetrequest)
do {
try context.execute(deleteRequest)
print("\(entity) 데이터 모두 삭제")
} catch {
print("삭제 중 오류 발생: \(error.localizedDescription)")
}
}
return
}
좋은 글 감사합니다. 자주 올게요 :)