앱 출시 데드라인 전에, 데이터 시더를 통해 하드한 테스트를 해보았었습니다.
모든 일기들을 날짜에 따라 section을 나누고, 날짜마다 순서대로 정렬해서 불러오는 게 너무 느리지는 않을까 걱정이 되었기 때문이었는데
역시나....
하루에 10번씩 일기를 쓰는 사람이 이 앱을 3년동안 사용했을 때를 가정하자, 일기 전체를 불러오는 속도가 너무도 현저하게 느려졌습니다.
물론 나중에는 필요한 정보만 긁어오는 방식으로 리팩토링을 할 것이지만,
여러 친구들과 이야기를 나눈 결과, 관계성을 설정해서 마치 인덱싱처럼 DB의 Date를 관리해야겠다는 결론이 나왔습니다.
하지만, 출시가 얼마 남지 않아 다른 오류들을 수정하느라 정신이 없는 상황이어서 일단 출시를 한 후에 수정하기 위해 남겨두었던 부분이었는데....
멘토님께서 사람들이 이 앱을 쓰기 시작하면 DB Table을 건드는 것은 쉽지 않은 작업이라고 하셔서
급하게 DB 수정에 들어갔습니다.
원래 코드는 다음과 같습니다.
먼저 모든 기록들을 Date에 따라 정렬하고... (여기서부터 엄청난.... 문제가 있었죠...)
레코드들을 하나씩 쑥 훑으면서 새로운 날짜가 나올때마다 섹션 목록에 추가하고, 같은 날짜의 기록들을 묶어서 이차원 배열을 생성하는 식으로 TableView를 생성하기 위한 정보들을 정렬했습니다.
private func setDateSections(sortedRecords: [Record]) {
var tempRecords = [Record]()
for r in sortedRecords {
let date = r.createdDate ?? Date()
let dateString = getSectionDateStr(date: date)
if let _ = dateSections.firstIndex(of: dateString) {
tempRecords.append(r)
} else {
dateSections.append(dateString)
onlyDateStr.append(getOnlyDate(date: date))
if tempRecords.count > 0 {
recordsByDate.append(tempRecords)
tempRecords = [Record]()
}
tempRecords.append(r)
}
}
if sortedRecords.count > 0 {
recordsByDate.append(tempRecords)
}
tempRecords.removeAll()
}
사실 For문 하나에 모든 section과 row의 구성을 끝내었다는게 정말 자랑스러웠지만.. 관계성을 고려하여 다시 DB를 리팩토링 했습니다.
관계성은 다음과 같이 설정했습니다.
Attributes명은 .... 눈 감아주세요...ㅜㅜ 수정해야 하는데, 자꾸 Xcode 기능 이용해서 수정하면 오류가 생겨서 아직 못했습니다ㅜㅜ
애초에 관계성을 설정하지 않고 짠 코드라ㅜㅜ 저렇게도 있구나만 봐주시면 감사하겠습니다..
이렇게 하면 장점이 무엇이냐!!
private func setSectionAndRecords() {
recordsByDates = [[Record]]()
onlyDateStr = [String]()
dateSections = [String]()
var superDates = [FinalDate]()
let context = CoreDataStack.shared.managedObjectContext
let request = FinalDate.fetchRequest()
do {
superDates = try context.fetch(request)
} catch { print("context Error") }
superDates.sort(by: {$0.creationDate?.timeIntervalSinceNow ?? Date().timeIntervalSinceNow > $1.creationDate?.timeIntervalSinceNow ?? Date().timeIntervalSinceNow})
for superDate in superDates {
dateSections.append(getSectionDateStr(date: superDate.creationDate ?? Date()))
onlyDateStr.append(getOnlyDate(date: superDate.creationDate ?? Date()))
var recordByOneDate = superDate.records?.allObjects as? [Record] ?? [Record]()
recordByOneDate.sort(by: {$0.createdDate?.timeIntervalSinceNow ?? Date().timeIntervalSinceNow < $1.createdDate?.timeIntervalSinceNow ?? Date().timeIntervalSinceNow})
recordsByDates.append(recordByOneDate)
}
}
이렇게 간단해진다.
더이상 모든 DB를 sorting하는 정말 해서는 안될 짓을 안해도 됩니다...ㅎ
FinalDate (하.. 이름 정말..ㅜㅜ) 을 쭉 불러와서 정렬한 후,
FinalDate의 요소들을 시간별로 sort한 후, 배열을 만들어서, 이차원배열에 순서대로 넣어주기만 하면 그만입니다.
그리고 FinalDate클래스의 theme도 주목해야 할 점 중에 하나입니다.
저는 날짜별로 각각 다른 테마를 가진 그림을 만드려고 했는데, 이렇게 날짜마다 테마를 가지니 관리가 훨씬 수월해졌습니다.
'iOS 개발 > CoreData' 카테고리의 다른 글
[CoreData] Coredata 자체를 sort 할 수 있을까? (0) | 2021.11.17 |
---|---|
[Core Data] Context를 이용해 Entity에 Attributes들을 추가, 삭제 (0) | 2021.09.08 |
[Core Data] Entity의 Name Attribute들을 Cell에 표시하기 (0) | 2021.09.07 |
[Core Data] TableView와 Navgation Cotroller을 임베디드 하기 (0) | 2021.09.07 |
[Core Data] Entity와 Attribute를 생성하는 방법 (0) | 2021.09.07 |
[Core Data] Context란? (0) | 2021.09.06 |
[Core Data] Entity Class 설정 - Codegen option 탐구 (0) | 2021.09.03 |
[애플 Document 번역] Core Data (0) | 2021.08.27 |