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