<h1><center> Advances in diffable data sources </center></h1> ###### tags: `๐Ÿ’ป WWDC ์Šคํ„ฐ๋””` > [color=#724cd1][name=๋ฐ๋ฆญ] > [Advances in diffable data sources - wwdc](https://developer.apple.com/videos/play/wwdc2020/10045/) > WWDC 2020 Session ์ค‘ ํ•˜๋‚˜์ธ `Advances in diffable data sources`์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž # ๊ฐœ์š” > Diffable Data Source์— ๋Œ€ํ•œ ๊นŠ์€ ํ•™์Šต์ด ํ•„์š”ํ•˜๋‹ค. ![แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-12-20 21.03.05](https://hackmd.io/_uploads/B1HWdUlva.png) - ์ฒซ ๋ฒˆ์งธ ์„น์…˜์€ Horizontally scrolling grid์ด๋‹ค. - ์ค‘๊ฐ„์˜ ์„น์…˜์€ iOS 14๋ถ€ํ„ฐ ์ƒˆ๋กญ๊ฒŒ ์ถ”๊ฐ€๋œ ๊ธฐ๋Šฅ์ธ๋ฐ, ํ™•์žฅ ๋ฐ ์ถ•์†Œ๊ฐ€ ๊ฐ€๋Šฅํ•œ outline-styled UI๋ผ๊ณ  ํ•œ๋‹ค. - ๋งˆ์ง€๋ง‰ ์„น์…˜์€ UITableView์ฒ˜๋Ÿผ ๋ณด์ด๋Š” UICollectionView์ด๋‹ค. iOS 13์— ๋„์ž…๋œ Diffable Data Source๋Š” ์ƒˆ๋กœ์šด snapshot ๋ฐ์ดํ„ฐ ํƒ€์ž…์œผ๋กœ UI ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ๋‹จ์ˆœํ•˜๊ฒŒ ๋งŒ๋“ค์—ˆ๋‹ค. ### Snapshot ์Šค๋ƒ…์ƒท์€ ๊ณ ์œ ํ•œ ์„น์…˜์„ ๊ฐ€์ง€๊ณ  item์˜ identifier๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ UI State๋ฅผ ์บก์Аํ™”ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ, UICollectionView๋ฅผ ์—…๋ฐ์ดํŠธํ•  ๋•Œ ๋จผ์ € ์ƒˆ๋กœ์šด ์Šค๋ƒ…์ƒท์„ ๋งŒ๋“ค๊ณ  ํ˜„์žฌ ๋ณด์—ฌ์ง€๋Š” UI์˜ State๋ฅผ ์ฑ„์šด ๋‹ค์Œ Data Source์— ์ ์šฉํ•œ๋‹ค. Diffable Data Source๋Š” ์ถ”๊ฐ€ ์ž‘์—… ์—†์ด ์ž๋™์œผ๋กœ ๋ฐ์ดํ„ฐ์˜ ์ฐจ์ด๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ  ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ ์šฉํ•œ๋‹ค. **WWDC 2019 Advances in UI Data Source**์—์„œ ์ด API๋ฅผ ์ž์„ธํžˆ ๋‹ค๋ฃจ๊ณ  ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ๋‹ค์Œ ์ฃผ์— ๊ณต๋ถ€ํ•ด๋ณด๊ฒ ๋‹ค. ๊ทธ๋ž˜์„œ iOS 14๋ถ€ํ„ฐ ์ ์šฉ๋œ๊ฒŒ ๋ฌด์—‡์ด๋ƒ๋ฉด, ์„น์…˜ ์Šค๋ƒ…์ƒท๊ณผ first class Reordering(์ตœ๊ณ  ์ˆ˜์ค€์˜ ์žฌ์ •๋ ฌ..?) ์ง€์›์ด๋ผ๋Š” ๋‘ ๊ฐ€์ง€ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ๊ตฌ์ถ•๋˜์—ˆ๋‹ค๊ณ  ํ•œ๋‹ค. ## Section Snapshot ์œ„์—์„œ iOS 14์˜ ๊ฒฝ์šฐ, Section Snapshot์ด๋ผ๊ณ  ํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜์—ˆ๋‹ค๊ณ  ์–ธ๊ธ‰ํ–ˆ๋Š”๋ฐ.. Section Snapshot์€ ๊ธฐ์กด ์Šค๋ƒ…์ƒท ๋ฐ”๋กœ ์˜†์— ์ƒˆ๋กœ์šด ์„น์…˜ ์Šค๋ƒ…์ƒท์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ํ•œ๋‹ค. UICollectionView์˜ single snapshot์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์บก์Аํ™”ํ•œ๋‹ค. (์ด๋ฆ„์—์„œ ์•Œ ์ˆ˜ ์žˆ๋‹ค๋Š” ํ‘œํ˜„์ด ์žˆ๋Š”๋ฐ.. ๋‚˜๋Š” ํ•œ๊ตญ์ธ์ด๋ผ ์•Œ๊ธฐ ํž˜๋“ค๋‹ค.) ์ด๋ ‡๊ฒŒ ํ–ฅ์ƒ ๋œ ์ด์œ ๋Š” ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค. 1. Data Source๋ฅผ section-sized chunk๋กœ ๋” ์‰ฝ๊ฒŒ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. 2. iOS 14์˜ UI ๋ Œ๋”๋ง์„ ์ง€์›ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๊ณ„์ธต์  ๋ฐ์ดํ„ฐ ๋ชจ๋ธ๋ง์„ ํ—ˆ์šฉํ•˜๊ฒŒ ๋œ๋‹ค. - ๋ฌด์Šจ๋ง์ผ๊นŒ? - ๊ณ„์ธต์  ๋ฐ์ดํ„ฐ ๋ชจ๋ธ๋ง์€ ์ฃผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณ„์ธต์ ์œผ๋กœ ๊ตฌ์กฐํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ํ•œ๋‹ค. ![แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-12-20 21.19.19](https://hackmd.io/_uploads/HkbRoIgD6.png) ์ฒซ ๋ฒˆ์งธ Horizontally scrolling Section์„ ๋ณด๋ฉด single section snapshot์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋ธ๋ง์„ ํ•œ๋‹ค. ๋‘ ๋ฒˆ์งธ๋Š” ํ™•์žฅ ๋ฌ๋‹ค๊ฐ€ ์ถ•์†Œ๋  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด ์žˆ๋Š” ์„น์…˜์ธ๋ฐ ๋‘ ๋ฒˆ์งธ ์„น์…˜ ์Šค๋ƒ…์ƒท์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๊ณ„์ธต์  ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋ธ๋ง ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ์ด ๋ง์€ extendable ์ผ€์ด์Šค๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๋Š” ์˜๋ฏธ์ด์ง€ ์•Š์„๊นŒ? ```swift enum Section { case horizontal case extendable case list } ``` ์š”์•ฝํ•˜์ž๋ฉด ๊ฐ๊ฐ์˜ ๋‹จ์ผ ์„น์…˜์„ ๋‚˜ํƒ€๋‚ด๋Š” ์ด ์„ธ ๊ฐœ์˜ ์„น์…˜ ์Šค๋ƒ…์ƒท์œผ๋กœ Diffable Data Source๋ฅผ ๊ตฌ์„ฑํ•œ๋‹ค. ![แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-12-20 21.24.01](https://hackmd.io/_uploads/B1iyp8gP6.png) > Section Snapshot API ์„น์…˜ ์Šค๋ƒ…์ƒท์˜ ํƒ€์ž…์„ ์‚ดํŽด๋ณด๋ฉด item ํƒ€์ž…์ด Generic์ธ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. Section์˜ Identifier ํƒ€์ž…์€ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ž. Section Snapshot์€ ๋ณธ์งˆ์ ์œผ๋กœ ์ž์‹ ์ด ์–ด๋–ค ์„น์…˜์„ ๋‚˜ํƒ€๋‚ด๋Š”์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค๊ณ  ํ•œ๋‹ค. Section snapshot์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด์„œ `append`๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ๋งค๊ฐœ๋ณ€์ˆ˜ **parent**๋ฅผ ์œ ์‹ฌํžˆ ๋ด์•ผํ•œ๋‹ค. parent๋ฅผ ํ†ตํ•ด ์„น์…˜ ์Šค๋ƒ…์ƒท์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์œ„-ํ•˜์œ„ ๊ด€๊ณ„๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ parent ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ํ•ด๋‹น Item์„ Root๋กœ ์ ์šฉํ•œ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค. ![แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-12-20 21.29.09](https://hackmd.io/_uploads/HkymCUew6.png) ๋˜, ์ƒˆ๋กœ์šด ์„น์…˜ ์Šค๋ƒ…์ƒท์„ ์œ„ํ•ด ๋‘ ๊ฐœ์˜ ์ƒˆ๋กœ์šด API๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋Š”๋ฐ apply ๋ฉ”์„œ๋“œ๋Š” ์„น์…˜ ์Šค๋ƒ…์ƒท๊ณผ identifier๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ํ•จ์ˆ˜์ด๋‹ค. snapshot ๋ฉ”์„œ๋“œ๋Š” ํŠน์ • ์„น์…˜์˜ ์ฝ˜ํ…์ธ ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์„น์…˜ ์Šค๋ƒ…์ƒท์„ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ![แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-12-20 21.31.56](https://hackmd.io/_uploads/H1DTCIeDp.png) > ์Šค๋ƒ…์ƒท ๊ตฌํ˜„ ![แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-12-20 21.33.30](https://hackmd.io/_uploads/HJL71Plv6.png) ์ฝ”๋“œ์—์„œ parent๋ฅผ ์„ค์ •ํ•˜์—ฌ ์ƒ์œ„-ํ•˜์œ„ ๊ด€๊ณ„๋ฅผ ๊ตฌ์„ฑํ•œ ๊ฒƒ๊ณผ ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ### Child snapshot ![แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-12-20 21.35.17](https://hackmd.io/_uploads/Skk9kvxwa.png) ์ด ์ฝ”๋“œ๋Š” Optional๋กœ ์ƒ์œ„ Item์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์ƒ์œ„ Item๊ณผ ๊ด€๋ จ๋œ ๋ชจ๋“  ํ•˜์œ„ Item์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ### Expanding and collapsing items ![แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-12-20 21.37.29](https://hackmd.io/_uploads/rJ7GgPeP6.png) Expansion State๋Š” ์„น์…˜ ์Šค๋ƒ…์ƒท State์˜ ์ผ๋ถ€๋กœ ๊ด€๋ฆฌ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ‘œ์‹œํ•  ์Šค๋ƒ…์ƒท์„ ์ƒ์„ฑํ•  ๋•Œ ํ•ด๋‹น Item์˜ ์ƒ์œ„ Expansion State๋ฅผ ์„ค์ •ํ•˜์—ฌ ํ•˜์œ„ ์ฝ˜ํ…์ธ ๊ฐ€ ์ฒ˜์Œ์— ๋ณด์—ฌ์งˆ์ง€๋ฅผ ์‰ฝ๊ฒŒ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ, ์Šค๋ƒ…์ƒท์„ queryํ•˜์—ฌ ํ™•์žฅ, ์ถ•์†Œ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ• ์ˆ˜๋„ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์„น์…˜ ์Šค๋ƒ…์ƒท์˜ Expansion State๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒฝ์šฐ, ์‹ค์ œ Diffable Data Source์— ์ ์šฉํ•  ๋•Œ๊นŒ์ง€ ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ•œ๋‹ค. ๋งŒ์•ฝ ์‚ฌ์šฉ์ž๊ฐ€ outline disclosure ์•…์„ธ์„œ๋ฆฌ ๊ฐ™์€ outline-styled UI์™€ ์ƒํ˜ธ ์ž‘์šฉํ•  ๋•Œ ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์ž๋™์œผ๋กœ ์Šค๋ƒ…์ƒท์„ ์ƒˆ๋กœ์šด Expansion State๋กœ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ํ•ด๋‹น ์„น์…˜ ์Šค๋ƒ…์ƒท์„ Data Source์— ์ ์šฉํ•œ๋‹ค. ์ด๋Ÿฐ ํ™•์žฅ ์ƒํƒœ ๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ์•Œ๋ฆผ์„ ๋ฐ›๋Š” ๊ฒƒ์ด ์œ ์šฉ(?)ํ•œ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค๊ณ  ํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํŠน์ • ์ƒ์œ„ Item์ด ์ ˆ๋Œ€ ์ถ•์†Œ๋˜์ง€ ์•Š๋„๋ก ์š”๊ตฌํ•˜๋Š” ๋””์ž์ธ์ด ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ๋ฅผ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ๋˜ ์ƒˆ๋กœ์šด API๋ฅผ ํ†ตํ•ด code ๋ฐฉ์‹์œผ๋กœ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ![แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-12-20 21.45.10](https://hackmd.io/_uploads/BJf1MvevT.png) ์˜ด๋งˆ.. ์ด๊ฒŒ ๊ทธ API์ด๋‹ค. ์œ„์—์„œ ๋งํ•œ ์˜ˆ์ œ ์ƒํ™ฉ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ `shouldCollapseItem`์„ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • ์ƒ์œ„ Item์— ๋Œ€ํ•ด false๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Lazy Loading๋„ ์ง€์›ํ•˜๋Š”๋ฐ snapshotForExpandingParent๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. ## Reordering Support ๊ณ ์œ ํ•œ Item identifier๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์‚ฌ์šฉ์ž ์ƒํ˜ธ ์ž‘์šฉ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์žฌ์ •๋ ฌํ•  ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋“ค์„ ์ž๋™์œผ๋กœ ์ปค๋ฐ‹ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทผ๋ฐ ๋˜ ๋” ๋‚˜์•„๊ฐ„ ๊ธฐ์ˆ ..? ### Optional closures ![แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-12-20 21.50.04](https://hackmd.io/_uploads/r1Ib7wgwT.png) `canReorderItem` ํด๋กœ์ €๋ฅผ ์‚ฌ์šฉํ•ด์„œ Reordering์„ ํ™œ์„ฑํ™” ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. ํด๋กœ์ € ๋‚ด๋ถ€์—์„œ true๊ฐ€ ๋ฐ˜ํ™˜๋˜๋ฉด Reordering ์ƒํ˜ธ์ž‘์šฉ์ด ์‹œ์ž‘๋  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ Reordering ์ƒํ˜ธ์ž‘์šฉ์„ ๋งˆ์น˜๋ฉด didReorder ํด๋กœ์ €๊ฐ€ ํ˜ธ์ถœ๋˜์–ด ์ƒˆ๋กœ์šด ์ •๋ ฌ State๋ฅผ ์•ฑ์˜ source of truth์— ์ปค๋ฐ‹ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ์œ„์— ์–ธ๊ธ‰ํ•œ canReorderItem์™€ didReorder ํด๋กœ์ €๋ฅผ ๋ชจ๋‘ ์ œ๊ณตํ•ด์•ผ Reordering ๊ธฐ๋Šฅ์„ ํ™œ์„ฑํ™” ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.(๋ฏธ๋ฆฌ ๋งํ•ด์ฃผ์ง€..) Transaction์€ Diffable Data Source๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ๋ชจ๋“  ์ •๋ณด๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ![แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-12-20 21.55.06](https://hackmd.io/_uploads/ryIE4Dgvp.png) ใ…Žใ…Ž.. **initailSnapshot**์€ ์—…๋ฐ์ดํŠธ๊ฐ€ ์ ์šฉ๋˜๊ธฐ ์ „์˜ Diffable DataSource์˜ State๋ผ๊ณ  ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  **finalSnapshot**์€ ์—…๋ฐ์ดํŠธ๊ฐ€ ์ ์šฉ๋œ ํ›„์˜ State์ด๋‹ค. ์Šค๋ƒ…์ƒท์˜ identifier๋กœ App์˜ source of truth์— ์ปค๋ฐ‹ํ•ด์•ผํ•˜๋Š” ์ƒˆ๋กœ์šด ordering์„ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ![แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-12-20 21.58.22](https://hackmd.io/_uploads/r1_eSPeDp.png)