본문 바로가기
WWDC

WWDC 19 - Advances in UI Data Sources

by vapor3965 2021. 6. 23.

목차

     


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

     

     

    https://developer.apple.com/videos/play/wwdc2019/220/

     

    Advances in UI Data Sources - WWDC 2019 - Videos - Apple Developer

    Use UI Data Sources to simplify updating your table view and collection view items using automatic diffing. High fidelity, quality...

    developer.apple.com

     

     


    관련내용

    • Collection, TableView에 사용하는 UI Data Source를 사용하라.
    • 동기화버그,예외,크래쉬등을 완전히피하게해준다.

     

    요약

    • 👍많은버그들을 없애줄, 새로운 DiffableDataSource (디퍼블 ) !
      • Snapshot + Identifier ! 끝!
      • Snapshot을 만들거나, 기존에서가져오고!
      • Snapshot에 추가및삭제하고,
      • apply
      • Identifier는 Hashable이여야한다.
      • 백그라운드에서도 가능하다.

     


    Current State-of-the-Art

    웹서비스와 이용한다면, 더 복잡해진다.


    복잡하니, 아래같이에러가자주뜬다.
    ( 나도그랬어……..!)

    • 넘짜증나니, 결국 reloadData를하게된다.
      • 그럼 결국 애니매이션을얻지못하지.
      • ( 아니, 나랑어떻게이렇게똑같지? ) - 통신에서 과도하게빠르게데이터가추가될겨웅그러던데


    UI는 sync적으로 되어야하고 ,
    controller는 데이터처리를야하고 …
    우리의 기본적인접근법으로는 종종 틀리게된다 ( 에러가뜬다 )

     

     

     

     

     

    DiffableDataSource

    • 그러므로. 새로운 접근법을 제시한다.
    • performBatchUpdate를 하지않고, apply() 라는 새로운간단한 걸사용한다.

     

    Snapshot


    apply()는 snapshot과함께 작동한다.

    • 새로운 construct이다.
    • IndexPath대신, section,item마다 유니크한 identifier를 갖는다.

    새로운 Snapshot이 생겼다면 ? apply()를 적용한다.


    current state와 new state를 apply시켜, Final state를 만들어낸다.


    iOS, tvOS는 UIColectionView,UItableView DIffableDataSource가 있다.
    mac은 NSCollectionViewDiffableDatasoure가 있다.

    그리고 모든플랫폼에 해당하는 Snapshot class가 존재한다.

    예제도있으니, 다운받아서 한번봐라, 길지않고 간단하다.

     

    알게되겠지만, 반복적인패턴을 발견할것이다.
    그리고 그것은 아주간단한 3단계프로세스이다.

     

    새로운변화의데이터를 넣ㅇ르때마다, Snapshot을 만들어낸다.

    • 그 snpashot은 각 item들의 description이담겨있다.
      그리고, Snaphot을 자동적으로 UI에 commit해주는 apply()를 한다.

     


    1.Demo

    아래와같이 마운틴 리스트들이있고,
    탑에는 입력하여 마운틴을 필터할수있다.


    이렇게 입력하다보면 아주매끄러운 UI애니메이션과함께 자동적으로 필터링된다.


    타이핑하는곳은 performQuery()를 진해앟ㅇㄴ다.


    performQueyr는 아래와같이구현되어있다.
    데이터모델에서 필터링하여, mountains를 얻는다.

     

    그리고다음이 앞서말한 3단계인데,
    👍1.우선 SNapshot을 만들어준다.
    이는 빈empty이고,
    2.그다음, appendSection( main) 으로추가해준다. 즉, 하나의섹션을갖는다.
    2.우리가보여주고하는 item의identifier을 append해준다.

    • 여기서는 단순히 배열로 넣었는데, swift의 native 타입에 hashable만 가능하게해주면 어떤 타입이든 넣을수있다.

    3.그다음 diffableDatasource에 apply를 요청한다.

    • 애니메이팅을해주며서, 이전의데이터와 지금의데이터의 차이를 자동적으로 파악한다.

    이게전부인데, indexpath를 사용하지않는다. 어떻게보여지는지, 이전은어떻고, 등등 걱정할필요없이 자동적으로된다.


    그리고 중요한점이 Snapshot은 generic class이다
    SectionIdentifierType과 ItemIdentifierType으로되어있다.


    👍SectionIdentifier - Secion 타입

    • 약간귀찮은 코드지만, 매우간단하다.
    • enum타입으로, 하나섹션만사용할것이므로, 하나의 case만 작성한다.
    • 그리고 중요한점이 swift에서 enum은 자동적으로 hashable이다.
      이게끝이다! ㅋㅋ

     

    👍ItemIdentifierType - Moutain 타입

     

    struct로, Hashable을채택했다. 그러므로 명시적으로 identifier를 전달하지않고서 DiffableDataSurce과사용되어질수있다.

    • 그리고, 각 Mountain은 Unqiue해야한다 ( 해쉬되어야하니까 )
    • 그래서, identifier 로 자동으로생성되는unqiue한 identifier를주었다 ( UUID() )

    • Hashable되어야하니까, hash를 구현했다.

    그리고, struct 이므로, 값타입으로, 복사만하고, 참조하기위한포인터가없다.
    또한, hashability일부로써, == 구현했따.



    지금까지, DiffableDataSource에게 변화를 전달하는 방법만 배웠는데, 그럼 어떻게 set할까?

     

    configureDataSource()

    UICollectionView를 이용할거니, 그에 맞는 DiffableDataSource를 생성하고, 섹션, item 타입을 정의한다. 그리고 CollectionView 포인터를 넣어준다.

    • 그러므로써, 알아서 wire해주고, collectionView의 datasource를.
    • 그리고 trialing클로저안에는 cellforItem처럼 cell가져오고, 하면된다.
      • 약간의다른점은, item 타입도넣어준다. ( mountain )
        • 그러므로, indexPath하여 아이템을꺼내올필요가읍네 ?


    2.Demo2

    2개이상의 섹션이있는경우,

    위는 와이파이 스위치와, 현재연결된 아이파이.
    아래는 다이나믹으로 감지되는 와이파이리스트.

    updateUI

    마찬가지로 3단계를 거친다.
    타입을 지정한 빈 Snapshot을 만들고,
    Snapshot에 section, item을 추가한다.

    • 처음에는 .config섹션에 (가장윗) 에추가해주고,

    그다음 wifie가 가능하다면, 현재가능한 와이파이리스트들을 찾는다.
    .networks섹션에 item들을 추가해준다!


    그리고, 애니메이팅이 싫다면, animate에 bool값을넣어줄수있따.


     

    Secion 타입

    🔥Item 타입

    • 각 아이템은 스위치도 있을수도있으니, Generic 타입을 사용했다.
    • 그래서 각 init에 따라 타입을 지정했다.

    hashable 채택하여 hash 구현해주고, 


    각 item이 어떤 타입인지, ?


    configure

    tableview를 사용하니 그에 맞는 diffableDataSource만들고,

    그리고, Item타입이 3가지이므로, 3가지에따라 cell을 분기했다.

     

     



    3.그리고 마지막으로 Demo
    이전Demo와는 약간다르다.

    랜덤 색들을 스팩트럼으로 바뀌는..



    앞서말했듯, 항상 3단계사이클을거친다.
    get Snaphot
    populate snapshot
    apply snaphot.

    하지만 이번에는 약간다르게, 기존의 snapshot을 가져온다.

    기존을가져와서, 삭제하고, 추가한다.

    • 그리고 Snapshot API에는 다양한 수정할수있는 기능들이많다. 예를들어, 다른곳으로움직일수있고,뜽등

    그리고 마지막으로, apply해준다.

    configure

     

     


    performBatch, insertItem은 죽었고, 늙었다.ㅎ


    Snapeshot 만드는 방법 2가지

    현재snapshot을 가져올때는, 오직 하나만을 수정하여 액션을취하고자할때 유용하다.


    Snapshot 상태

    • API에많이있다.

    그리고 장담하건데, Snapshot을사용하면 indexpath를 사용할필요가ㅇ전혀없다.

     

    👍그리고, section, items들에 추가,삭제,움직임,삽입 등등 많다!
    또한, 여러개를 한꺼번에삽입도가능하데 ,
    그리고, 어떤 섹션에넣을지모르겠다면, 그냥 section선언없이넣으면 마지막에넣게해준다?


    Identifier
    ( Section과 Item에 해당하는 )

    • 무조건 unique해야한다.
    • enum으로 쉽게 unique하게할수잇고,
    • String,integer, UUID 로도가능하고,

     

     

    그럼! indexPath기반의 API들은?!


    ( 터치딜리게이드 등등 )

    짜잔~ IndexPath로 identifier를 얻는다!
    그리고이는 상수시간이라 매우매우빠르다


    Performance 측면

    • 겁나빠르다. 아주low-level stuff이다.
    • cs배웠다면, 이는 선형시간이다. O of N 으로!
    • 만약 작업할게너무많다면, 백그라운드큐에서도 safe하게 작동가능하다! ( 미췬 박수 )
      • 알아서 백그라운드큐에서 작업을다마치면 메인큐로넘어가서 하는듯
      • 대신, 둘중하나만 하도록해라, 믹스해서 하지말고, 안그럼랙!



    ShareSheet 과의 콜라보

    특히, airdrop extension에서 멋지다.


    추가적으로 보고싶은거
    완전히새로운 layout system - CollectionVIew 가나타났다.

    • 서브클래싱할필요없이!!

    댓글