[swift] IGListKit에서 데이터 모델 간 분리하는 방법

IGListKit은 iOS 앱에서 복잡하고 유연한 데이터-driven 컬렉션 뷰를 구축할 수 있는 강력한 도구입니다. IGListKit을 사용하면 데이터 모델을 효과적으로 관리할 수 있으며, 모델 간의 분리를 통해 코드의 유연성과 재사용성을 높일 수 있습니다.

1. 데이터 모델 클래스 분리

데이터 모델 간의 분리를 위해 먼저 각 데이터 모델에 대한 클래스를 만들어야 합니다. IGListKit에서는 데이터 모델 클래스는 NSObject를 상속해야 하며, IGListDiffable 프로토콜을 준수해야 합니다. IGListDiffable 프로토콜은 데이터 모델이 어떻게 비교되고 유일하게 식별되는지에 대한 정보를 제공합니다.

class User: NSObject, IGListDiffable {
    let id: String
    let name: String
    
    init(id: String, name: String) {
        self.id = id
        self.name = name
    }
    
    func diffIdentifier() -> NSObjectProtocol {
        return id as NSObjectProtocol
    }
    
    func isEqual(toDiffableObject object: IGListDiffable?) -> Bool {
        guard let object = object as? User else {
            return false
        }
        return id == object.id
    }
}

위의 예제에서는 User 클래스가 데이터 모델을 나타내며 idname 프로퍼티를 가지고 있습니다. diffIdentifier 메서드를 통해 데이터 모델의 식별자를 반환하고, isEqual 메서드를 통해 데이터 모델 객체를 비교합니다.

2. 데이터 소스 클래스 구현

다음으로, IGListKit의 IGListDiffable 프로토콜을 구현한 데이터 모델 클래스들을 사용하는 데이터 소스 클래스를 구현해야 합니다. 이 클래스는 IGListDiffableDataSource 프로토콜을 준수해야 하며, objects(for:) 메서드를 사용하여 섹션에 대한 데이터 모델 배열을 반환해야 합니다.

class UserListDataSource: NSObject, IGListDiffableDataSource {
    var users: [User]
    
    init(users: [User]) {
        self.users = users
    }
    
    // MARK: - IGListDiffableDataSource
    
    func objects(for listAdapter: IGListAdapter) -> [IGListDiffable] {
        return users
    }
    
    func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController {
        return UserSectionController()
    }
    
    func emptyView(for listAdapter: IGListAdapter) -> UIView? {
        return nil
    }
}

위의 예제에서는 UserListDataSource 클래스가 데이터 소스를 나타내며 users 프로퍼티에 사용자 데이터를 저장합니다. objects(for:) 메서드를 통해 데이터 모델 배열을 반환하고, listAdapter(_:sectionControllerFor:) 메서드를 통해 섹션 컨트롤러를 반환합니다. emptyView(for:) 메서드는 비어 있는 경우에 대한 뷰를 반환합니다.

3. 섹션 컨트롤러 클래스 구현

마지막으로, 데이터 모델을 표시하는 뷰를 관리하기 위한 섹션 컨트롤러 클래스를 구현해야 합니다. IGListSectionController 프로토콜을 가지고 있으며, sizeForItem(at:) 메서드에서 데이터 모델의 크기를 반환하고, cellForItem(at:) 메서드에서 데이터 모델에 해당하는 셀을 반환합니다.

class UserSectionController: IGListSectionController {
    var user: User?
    
    // MARK: - IGListSectionController
    
    override func numberOfItems() -> Int {
        return 1
    }
    
    override func sizeForItem(at index: Int) -> CGSize {
        return CGSize(width: collectionContext.containerSize.width, height: 50)
    }
    
    override func cellForItem(at index: Int) -> UICollectionViewCell {
        let cell = collectionContext.dequeueReusableCell(of: UserCell.self, for: self, at: index) as! UserCell
        cell.user = user
        return cell
    }
    
    override func didUpdate(to object: Any) {
        user = object as? User
    }
}

위의 예제에서 UserSectionController 클래스는 IGListSectionController를 상속하며 user 프로퍼티를 가지고 있습니다. numberOfItems() 메서드는 해당 섹션의 아이템 수를 반환하고, sizeForItem(at:) 메서드는 아이템의 크기를 반환합니다. cellForItem(at:) 메서드는 해당 아이템에 대한 셀을 반환합니다. didUpdate(to:) 메서드는 데이터 모델이 업데이트될 때 호출되며, 해당 데이터 모델을 다시 할당합니다.

결론

IGListKit에서 데이터 모델 간의 분리는 앱의 유연성과 재사용성을 높이는 중요한 요소입니다. 복잡한 컬렉션 뷰 레이아웃을 구축하기 위해 IGListKit을 사용하는 경우 데이터 모델 클래스를 분리하고, 데이터 소스 및 섹션 컨트롤러 클래스를 구현하여 코드를 관리하고 유지보수하기 쉽게 만들 수 있습니다.

참고 자료: