

performBatchUpdates() 를 사용하지 않고 모든 충돌, 번거로움과 같은 것들을 제거apply() 라는 메소드 사용, 이는 자동으로 diffing함
indexPath 를 사용하지 않고, section과 item의 고유한 identifier을 사용
ㄴ BAR, FOO, BAZ로 이루어진 새로운 Snapshot
ㄴ Apply는 현재 상태를 알고 있으며, 새롭게 적용할 New Snapshot에 대해서도 알고 있음

따라서 그냥 Apply 해! 간단간단 ,,, ✨

산 이름을 검색하면 text를 입력할 때마다 자동으로 필터링되는 collectionView

func performQuery(with filter: String?) {
let mountains = mountainsController.filteredMountains(with: filter).sorted { $0.name < $1.name }
var snapshot = NSDiffableDataSourceSnapshot<Section, MountainsController.Mountain>()
snapshot.appendSections([.main])
snapshot.appendItems(mountains)
dataSource.apply(snapshot, animatingDifferences: true)
}
mountains : 필터링된 데이터 목록을 가져옴NSDiffableDataSourceSnapshot 을 생성, 하나의 section을 추가@preconcurrency struct NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>
where SectionIdentifierType : Hashable,
SectionIdentifierType : Sendable,
ItemIdentifierType : Hashable,
ItemIdentifierType : Sendable
SectionIdentifierType 과 ItemIdentifierType 에 의해 매개변수화됨 // 2개의 section - enum 사용
enum Section: CaseIterable {
case config, networks
}
enum ItemType {
case wifiEnabled, currentNetwork, availableNetwork
}
struct Item: Hashable {
let title: String
let type: ItemType
let network: WiFiController.Network?
init(title: String, type: ItemType) {
self.title = title
self.type = type
self.network = nil
self.identifier = UUID()
}
init(network: WiFiController.Network) {
self.title = network.name
self.type = .availableNetwork
self.network = network
self.identifier = network.identifier
}
var isConfig: Bool {
let configItems: [ItemType] = [.currentNetwork, .wifiEnabled]
return configItems.contains(type)
}
var isNetwork: Bool {
return type == .availableNetwork
}
private let identifier: UUID
func hash(into hasher: inout Hasher) {
hasher.combine(self.identifier)
}
}
Item 을 Hashable한 구조체로 선언 
configItems 로 표시할 데이터를 얻고, Snapshot 생성config section에 item의 identifier 추가if controller.wifiEnabled {
let sortedNetworks = controller.availableNetworks.sorted { $0.name < $1.name }
let networkItems = sortedNetworks.map { Item(network: $0) }
currentSnapshot.appendSections([.networks])
urrentSnapshot.appendItems(networkItems, toSection: .networks)
}


var upadatedSnapshot = dataSource.snapShot()


Snapshot을 구성하는 메소드들이고, 더이상 indexPath 에 의존하지 않음을 알 수 있음




이때(iOS13) Airdrop에도 CompositionalLayout&DiffableDataSource를 사용했대용
UUID를 사용하여 발견된 각 디바이스들을 고유하게 식별함
새로운 디바이스가 발견되면 빈 Snapshot을 만들고 section과 item을 추가한 후, diff를 apply