지난 WWDC15 What's New in CoreData에 이어 Core Data Best Practices 에 대해 살펴봅니다.
코어데이터를 저장하는 방법입니다. 흔한 게시글 같이 사진과 글이 있는
경우 이런 식의 모델링을 할 수 있습니다.
여기서 post 와 comment의 relations 가 필요합니다. 시간이 지날수록 디스크 내의 많은 양의 데이터가 쌓일텐데, 관리하기 위해 NSPersistentstoreCoordinator를 사용할 수 있습니다.
coordinator 는 앱의 모델을 store의 버전과 비교할 수 있고, 앱이 진화함에 따라 자동으로 migration을 합니다.
NSManagedObjectContext 는 안전하고 빠르고 예측가능하게 데이터에 접근할 수 있도록 합니다.
심지어 query generation, connection pooling, history tracking 와 같은 기능들에서도 사용 가능합니다. (?)
원래는 위와 같이 복잡한 코드를 작성해야 했다면,
코어데이터를 이용하면 boilerplate 코드를 줄여줄 수 있습니다.
persistantContainer은 Main Bundle 외부에서 데이터를 load 할 것입니다.
코어데이터는 앱이 성장함에 따라 사용하기에 좋도록 설계 되었습니다.
Container가 모델을 찾는 방법입니다.
Container가 모델을 찾는 향상된 방법입니다.
저장소가 저장되는 공간을 커스터마이징 합니다.
향상된 방법입니다. 코어데이터는 생성될 때 기본 경로가 생성됩니다.
Core Data를 사용하는 Controller에게 필요한 것!
위에서 fetchRequest와 context를 잘 주입해 주었습니다. 이 두 객체를 이용하여 결과값을 얻으려면, fetch request 를 조금 더 구성해주어야 합니다. 왜냐하면 훌륭한 성능을 보장하기 위해서 입니다.
만약 하루에 게시글을 올리는 수를 파악하기 위한 차트를 만들고 싶다면?
여전히 SQLite는 그래프의 수를 계산할 때 메모리를 통해 모든 게시글을 읽습니다. 데이터가 너무 많아지면 어떻게 해결해야 할까요?
앱이 성장함에 따라 데이터는 더욱 복잡해지고, 카오스를 불러일으킵니다. CoreData를 이용하면 이 카오스를 막을 수 있습니다.
사용자 입장의 metrics
엔지니어 metrics
사용자와 상호작용하는 위 세개의 버튼이 동시적으로 일어날 때, 카오스가 일어납니다.
적은 양의 상호작용 임에도 불구하고, 동시적으로 일어났을 때 수많은 다른 상태변화를 일으킵니다.
나쁜 사용자 경험을 선사할 수 있습니다..
이는 query generations에게 도움을 받을 수 있습니다.
What's new in coredata 에서 소개된 녀석입니다. (어려워서 잘 못봤던거..)
오직 SQLite 에서 작동합니다.
queryGeneration을 설정하는 방법입니다.
기존의 방법대로 mergeChanges를 통해 업데이트 합니다.
위 방법을 이용하여 앱 데이터의 명백한 변화를 UI에 즉각 나타낼 수 있습니다.
만약 우리가 쓰는 데이터가 코멘트를 다운받는 것처럼 UI와 연관이 없다면 어떨까요?
이때는 데이터가 UI에 보여지지 않길 원합니다.(변경 사항이 사용자에게 표시되지 않기 때문)
그래서 이런 업데이트는 history tracking으로 필터링 합니다. (wwdc17 what's new in core data에서 소개되었다.)
- 위같은 **POST** 데이터가 들어왔을 때, 우리는 UI를 새로고침 해주고 싶을 것이다.
- NSPersistentHistoryTransaction을 사용할 수 있다.
- 하지만 **Comment** 데이터가 들어온다면 UI 새로고침 하고싶지 않을 것이다.
- POST 작업만 뽑도록 필터링 해줄 수 있다.
생각해보면 POST Entity에 프로퍼티가 title 과 image 밖에 없습니다.
entity로 필터링 하는 방법 말고 history changes 를 이용하여 업데이트된 프로퍼티를 기준으로 필터링도 해줄 수 있습니다.
[20:15]
데이터가 복잡해지고 커질 수 있습니다. 이때 몇몇 editing 작업이 어려워 질 수 있습니다.
CoreData는 위와 같은 multi-selection의 경우 Batch Operation을 통해 지원 가능합니다.
▼ BatchUpdateRequest
▼ BatchDeleteRequest
메모리에 객체 faulting 하는 것과는 다른 방법으로 커집니다. 예를들어 delete(NSManagedObejct.delete를 이용하는) 를 하는 동안에 database의 record 사이즈를 늘릴 것입니다. 객체를 delete 함에 따라 메모리는 fault 될 것입니다. 이는 database가 커짐에 따라 비용도 비싸질 것입니다. 그러나 BatchOperation을 이용하면 메모리의 일부만으로 동일한 mutation을 수행할 수 있습니다. 이는 데이터가 증가함에 따라 메모리 사용량이 줄어드는 곡선을 가지게 합니다.
이것은 사용자의 기기에 자원을 저장하는데에 아주 파워풀한 방법입니다. 하지만 전통적인 문제중 하나는 batch operation을 이용하여 작업하기 어렵다는 것입니다. 이유는 save notification을 생성하지 않기 때문입니다. 그래서 history tracking이 다시 시작됩니다.
objectIDNotification()
이 save notification의 역할을 해줄 수 있습니다. 이러한 방식으로 가져온 result controller 또는 애플리케이션의 다른 컨텍스트는 이러한 알림을 점진적으로 업데이트할 수 있습니다.
여기까지 CoreData를 이용해 커지는 데이터를 관리하는 방법이었습니다. 하지만 workflow는 어떨까요?
NSKeyedArchiver API is changing
Default value transformer
Transparent for plist types
▼ 추후 이렇게 기본값으로 정해질 것이다.
▼코드로 적용해주는 방법이다.
▼ 확인해보니 이렇게 되어있다. value transformer 라는게 없다..
core data 관련 wwdc 는 항상 데이터베이스 관련 내용이 같이 나와 이해하기가 어려운 것 같습니다. 이번에도 마찬가지로 후반부의 내용은 db관련 심화 내용(Help Us Help You [23:00] 이후내용)이 포함되어있어 정리하지 못했지만, 추후 코어데이터를 헤비하게 사용하게 된다면 찾아봐도 좋을 것 같습니다.
이번 wwdc 를 한마디로 요약해보자면, "앱이 버전업 함에 따라 데이터가 복잡해지고, 이를 관리해주기 힘들텐데 CoreData 를 이용하면 쉽게 관리해줄 수 있다!" 입니다.