본문 바로가기
WWDC

WWDC 17 - What's New in Core Data

by vapor3965 2021. 7. 4.

목차


    • 세션보면서 정리한 내용입니다. 해석이 잘못된 경우가 있을수있으니 발견하시면 댓글로 남겨주시면 감사하겠습니다🙏🏻

    https://developer.apple.com/wwdc17/210

     

    What's New in Core Data - WWDC17 - Videos - Apple Developer

    Join the Core Data engineering team and learn about the new features in Core Data. See how you can easily and automatically include your...

    developer.apple.com

     


     

    요약

    • Core Spotlight를 도입했고, 이를통해 앱에서 손쉽게 디바이스의 데이터를 찾게해준다. ( 어려워서 패스 ) 
    • 다양환 환경에서 데이터베이스의 변경사항들을 놓칠수있는데, 이런 놓친 변경사항들을 찾아주는 Persistent History 가 등장했다!
      • 이제 놓친 사항들을 찾기위해 모든 데이터를 읽을필요없고, Persistent History change Reuqest를 이용하여 변경사항들을 손쉽게 merge할수있다. 
      • 특정 otken, transaction, date를 통해서 change reuqest를 가져올수있다. 

     

     


    이번에 새로운 Core Spotlight 를 도입했다.

     

    우선 Core spotlight를 설명하기전에, spotlight를 설명해보자. 

     

    Spotlight는 original search API이다. 

    Mac OS10부터 기술이며, 

    Command + space 누르면 나오는 검색창!

    사용자들이찾는것을 찾아주지만, 실제로 어디에 저장되어있는지는 알려주지는않는다.

     

    그리고 이는 실제로 database에서는 그다지 이상적이지않다. 엄청많은 레코드가있을수있기때문이다.

     

    Core Spotlight는 iOS에서 original search technology다.

    이는 훨씬더 database에 친화적이며,  심지어 어디에 있는지도 알려준다. 

    그러므로 이제는 Core Data와 결합하는게 좋다라고 생각한다!

    또한 MacOS로도 가능해서, 앱에서 Core Spotlight API를통해, Spotlight search indexes로접근이가능하다. 

     

     

    우선  Core Spotlight 통합에는 세가지 핵심적인 요소가있다. 

     

    첫번째로,  Core Spotlight에 push되어져야하는것을 가리키도록 하기위해 인덱스를 다시만들었다. 

    또한 찾은결과를 spotlight 메뉴에 나타나도록 명시하기위한 방법도 필요하다

    그리고 앱에 저장할때마다 Exporter는 유저가만든변화들을 Core Spotlight index에 push한다.

    ( 도통 무슨말인지 ... ㅎㅎ ) 

     

     

    Core Spotlight display name expression은 약간 이해하기어려운 개념이다. 

    이것은NS Entity Description에 프로퍼티로 세팅한, NSExpression의 인스턴스이다. 

    이것은 Core Sportlight index가 업데이트될때마다 반영받는다

     

     

    NSCore Data Spotlight Delegate도 있는데, 이는 CSSearchableIndexDelegate를 구현했고, 많은 기본적인 구현메소드를 제공해준다. 그리고 백그라운드쓰레드에서 실행된다. 

     

     

    ... 생략  

    (  ㅠㅠ Core Spotlight 개념들이 소개되는데 도무지 봐도 모르겠어서 ㅎㅎ 패스합니다.

    이세션 보는이유가 Persistent History Tracking이기도 해서...

    대충.. Core Spotlight를 통해서 손쉽게 앱에서 디바이스의 데이터를 찾게해준데요

    Core Spotlight를 적용하는것도굉장히 쉽데요...ㅎ 

    )

     

     

     

     

     


     

     

     

    이번에 Persistent History Tracking을 소개한다.

    작년에 소개한 NSPersistent Container를 이용한다면, View Context그리고 Background context를 얻을수있다. 

    background context를통해 외부로부터 다운로딩할수도있다. 

     

    그리고 context로부터 뿐만아니라, 여러 Extension을 이용해서 각 Extension들로부터 persistent store에서 작업이되어질수있다. 

     

    자그럼 각 데이터들은 정확히 어디에서 오고가는걸까? 

    그리고 그런상황에서 어떤 일이 발생할수있을까? 

     

    우선 사용자는 view Context를통해서 데이터를보고있고, 

    background context는 외부서버로부터 데이터를 받아오고있따고 가정해보자.

    그러면 view context는 background context에서 무슨일이 일어나는지를 모른다. 

    하지만 save notification을 통해서 알수잇고, 다만 batch operation들은 save notification을 발생시키지않는다. 

     

    그리고만약 사용자가 사파리로 가서 무선가를 share한다고하자. 

    그러면 데이터베이스에 작성되고, 

    그리고다시 앱으로돌아오면 ? 무엇이 변했는지를 알수는있어도 정확히 무언가가 변했는지를 모른다. 

    그러므로 데이터베이스에서 다시 모두읽어들여 확인해봐야한다. 

     

     

    backrgound context가 서버로부터 열심히다운받고있다가, 

    가끔은..  슬프게도 앱이 크래시날때도있다. 

    예를들어 백그라운드로갔을떄 사용자가 앱을 삭제하거나, 등 

    그리고 다시 앱을키면?  background context는 무엇을놓쳤는지 알수가없다. 그러므로이것도 다시 데이터베이스를 찾고, 무엇이 다시 실행되어야하는지를 찾ㅇ야한다. 

     

     

     

     

    자, 문제들이 어떤변화가발생했을때, 무엇이정확히 변했는지를 모르므로, 모두탐색해야하는 오버헤드가존재한다.

    이를 극복하기위해 Persistent History가 생겨났다!

     

    container와 그 store description에 setOption  - true 만해주면된다.

    • 그러면? 이제 database에 발생하는 모든변화들을 추적하게해준다! ( 박수,박수 ) 

     

     

    위에서 발생할수있는상황들을 토대로, 

    History에는 각 트랜잭션 내역들이남게된다!

    그러므로 다시앱에돌아왔을때는, 이 history table을통해서 각 변화들에대한 세부사항들을 확인할수있다!

     

     

    자, 그러면, history로부터 받아오는  새로운 Store Request를 소개해야겠다.   - NSPersistent History Change Reuqest 

     

    data, token, transaction으로부터 가져올수있다. 

    또는 history들을 제거할수도있다. 

    하지만, 여기서주의할점은 이런경우에는 gatekeeper를 가져야한다 ? 

     

     

    NSPersistent History transaction 

    • 누가 트랜잭션을 했는지 관련정보들을 다룬다.
    • soter ID, bundleID, processID, Token, author, changes 
    • 시스템은 token을 주고, 우리는 이것을 디스크에 인코딩할수있고, 앱이 종료할때, 이를통해 history에서 앱이어디에있는지 추적할수있도록해준다. 
    • author은 누가 manage object context에 접근했는지, batch opertaion을 했는지 알려줄수있다. 
      • 그러므로 context에서 transactionAuthor 에 설정할수있다.  그래서 reuqest들을 excute하기전에 설정해놓으면 history에서 확인할수있다. 

     

    • change에는 각 트랜잭션에서 어떤 변화가발생했는지를 알려준다. 그러므로 하나의 트랜잭션에도 굉장히많은 change가 있을수있다. 
      • model에서도 어떤  attribute, relationship등 가 업데이트됐는지 알수있다. - updatedPrroperties 
      • 그리고 삭제하는경우에는 tombstone으로알려준다.  이것은 attribute의 쌍으로 이루어져있다.  삭제된경우 더이상 데이터베이스에없고, object ID는 더이상관련이없게되지만, 이 tombstone으로는 확인할수있고, 나중에처리도할수이따? 

     

    tombstone을 제대로활용하기위해서는,  model 에디터에서 인스팩터에서 특정 attribute를 Perserve After Deletion 을 체크해준다.  그러면 이는 tombstone에 나타나게된다. 

     

     

     

     

     

     

     

    이제 Demo를 살펴보자.

    post들을 가져오는 앱인데,

    Dounload버튼을통해서 background context를 이용하여 Cloud로부터 post를 가져오고,

    오른쪽탭에는 history탭이있는데, history들을볼수있다. 

    + 버튼을누르면 user로부터 post를 가져온다. 

    또한 각 post에 label을 달았는데, B는 백그라운드, U는 유저, 그리고앞으로나올 S는 사파리 

     

    자, 그럼 사파리로가서 share extension으로 내앱에 보내보자 

     

    다시앱으로돌아와보니? 앵 없어! 

     

    하지만 히스토리에는 있다. 

     

    그리고, 다시 post탭을 눌러보니 옹? 사파리로부터 온 post가 생겼다. 

    실제구현코드에서 모두 다시 fetch했기때문에, 가능하다 

    이것은 굉장히 비효율적이고 사용자한테도 짜증나는 경험이다 

     

     

    대신 Persistent history를 키게된다면?!!

    true로 바꿔주고, 

    우선 코드는 각 viewContext와, bacgroundContext가있다. 

    그리고 각 변경사항에따른 notificaton을 받기위해 observer를 추가해놓았다.

     

    backgroundcontext에서 발생한변화들을 merge하도록한다.

     

    그리고 코드는 미리작성해두었는데, 

    history를 킬경우와안킬경우를 작성했다. 

    안킬경우 모두 fetch하지만, 

     

     

    대신 키게되는 코드는, 

    history를 fetch하고, 

    각 history로부터 viewcontext에 merge한다.  

    이제더이상 모두 Fetch할필요가없다. ( 박수박수 ) 

     

    여튼! 이렇게 다시실행해보면 사파리에서 앱으로share해도 바로 즉각적으로 확인이가능해진다. 

     

     

     

     

     

     

    자, 요약하면, 

    아주간다하게 Persisten history를 가능하게하고,

    놓쳤던 change들을 모두알아내준다!!

     

     

     

    그리고 두가지 주의할점이있는데,

    두가지경우를 제외하고는 최대한 가능한한 history를 보존할것이다.

    하나는 model로부터 entity를 지우면서, 이미 history에 entity가있는경우이다 ( 무슨말이지?  )

    여튼 이경우에는 history에서 삭제한다. 

    • One is if you remove entities from your model and we already have history on these entities, we'll have to remove that history for those entities and that creates a gap.

     

    나머지경우는 tombstone이다.  ( ㅎㅎ 무슨말인지  ) 

    • The other one is for tombstones. For tombstones you don't want to have certain data there after awhile to identify the object. Maybe it's become a security concern for you. So you've called the tombstone.
    •  So we'll do the same and we'll remove that tombstone value out from the model. But if that removes anything that will leave a gap in your history, we'll also then only preserve your history to the last complete transaction. This way you can go and follow the history without falling into a trap where I am missing changes once again because of a gap.

     

     

     

    댓글