[swift] Swift DeepDiff를 사용하여 컬렉션 데이터 변경 시 셀 특정부분만 업데이트하기

iOS 앱을 개발할 때, 테이블 뷰나 컬렉션 뷰에서 데이터 변경이 발생하면 많은 양의 셀을 다시 그리는 것은 효율적이지 않습니다. 이러한 문제를 해결하기 위해 DeepDiff라는 Swift 라이브러리를 사용할 수 있습니다. DeepDiff는 두 개의 컬렉션을 비교하고 변경 내용을 찾아주는 기능을 제공합니다.

DeepDiff 설치하기

DeepDiff를 사용하기 위해 먼저 Swift Package Manager를 통해 프로젝트에 라이브러리를 추가해야 합니다. Package.swift 파일을 열고 dependencies 항목에 다음과 같이 추가합니다.

dependencies: [
    .package(url: "https://github.com/onmyway133/DeepDiff.git", from: "2.4.0"),
],

그리고 Xcode에서 File -> Swift Packages -> Update to Latest Package Versions를 선택하여 패키지를 업데이트 해줍니다.

DeepDiff를 사용하여 셀 업데이트하기

DeepDiff를 사용하면 컬렉션 내의 변경된 요소를 찾아낼 수 있습니다. 이를 활용하여 변경된 요소만 업데이트하고, 나머지 요소들은 그대로 유지할 수 있습니다.

import DeepDiff

// 이전과 새로운 컬렉션 생성
let oldData = ["apple", "banana", "cherry"]
let newData = ["apple", "kiwi", "cherry"]

// DeepDiff를 사용하여 컬렉션 비교
let changes = diff(old: oldData, new: newData)

// 변경된 요소만 업데이트
changes.forEach { change in
    switch change {
    case .insert(let newIndex):
        // 새로운 요소가 추가된 경우
        let indexPath = IndexPath(item: newIndex, section: 0)
        // 해당 indexPath에 대한 UI 업데이트 로직 추가
        break

    case .delete(let oldIndex):
        // 기존 요소가 삭제된 경우
        let indexPath = IndexPath(item: oldIndex, section: 0)
        // 해당 indexPath에 대한 UI 업데이트 로직 추가
        break

    case .move(let oldIndex, let newIndex):
        // 요소가 이동한 경우
        let oldIndexPath = IndexPath(item: oldIndex, section: 0)
        let newIndexPath = IndexPath(item: newIndex, section: 0)
        // 해당 indexPath에 대한 UI 업데이트 로직 추가
        break

    case .replace(let newIndex, _, _):
        // 요소가 변경된 경우
        let indexPath = IndexPath(item: newIndex, section: 0)
        // 해당 indexPath에 대한 UI 업데이트 로직 추가
        break
    }
}

위 코드에서는 diff 함수를 사용하여 이전 컬렉션과 새로운 컬렉션을 비교하고, changes에 변경 내역을 저장합니다. 그리고 changes를 순회하면서 변경된 요소를 확인하고, 해당 변경에 대한 UI 업데이트 로직을 작성합니다.

참고 자료