코드 개선 - 전개편 (3)

코드 개선 - 전개편 (3)

MVVM 써보려다가 Combine, Protocol, static cell, configuration 공부한 이야기.

·

3 min read

시작은 여느 날과 같았다. 아니, 이 날은 조금 달랐다. 사실 원하던 건 앱 설정 화면을 만드는 거였을 뿐인데... 설정 내용을 띄워주려니 설정 내용을 가진 개체가 필요하겠네? 저장도 해야하니 UserDefaults를 써볼까? 아 근데 이거 어차피 MVVM 식으로 다시 해야하는 김에 얘부터 MVVM에 걸맞게 만드는게 맞는 거 같다? 그럼 어떻게 해야하지?


그렇게 시작된 MVVM을 위한 여정의 시작이자 전개편의 마지막 이야기다. (static cell, configuration은 감초 역할이다.) 아이폰의 앱 설정 화면 같은 걸 만들고 싶은데 잘못 들어온 것 같다면 UITableViewController의 contentConfiguration 알아보기를 확인해보기를 권한다. 설정 화면같은 경우 기본 테이블 뷰에서 제공하는 것으로도 충분히 만들 수 있는데, 이걸 iOS 16에 대응하여 기본 테이블 뷰를 활용하는 방법을 소개한다.


우선 내가 원하는 것을 확인하는 것 부터 시작했다. 나는 설정값이 변경될 경우 알아서 뷰에 갱신되어 보이기를 원했다. 그러니까 값을 탐지해서 변경되면 뷰에 적용하도록 코드를 짜야했다. 쉽게 Combine과 rxSwift라는 선택지를 두고 고민했는데, 현재 진행하는 다른 프로젝트에서 rxSwift를 사용하는데다 Monthly Piece는 유지보수성을 고려해 Apple 제공 외 라이브러리는 최소화 하기 때문에 Combine을 사용해보게 되었다. (그것도... UIKit에서...)

MVVM 형태를 사용하기 위해 Combine을 사용하기로 결정했고 설정 정보를 어디에 저장할지도 고민했는데, Realm에 Combine을 사용 가능한 형태로 데이터 처리 객체를 만들어야 했다.내가 표기할 정보들을 고려하여 구조체를 만들었다.

import Foundation
import UIKit
import Combine

// 코드 중략
struct AppSetting: Identifiable {
    var id: UUID = UUID()
    var titleText: String
    var type: SettingType
    var valueText: CurrentValueSubject<String, Never>
}
// 코드 하략

실제로 변화하고 확인해야 값은 각 설정 항목의 항목 이름이 아니라 항목이 가진 값이다. 그러므로 valueText라는 값을 가진 변수를 CurrentValueSubject로 설정한다. 그 외에도 PassthroughSubject 등을 사용해 설정 뷰와 객체를 연결시켰다. 검색어 'Swift UIKit Combine'으로 검색하면 자료가 다양하게 나오는데, 그 글들을 참고해서 작성했다.

문제가 있었다면, 원래 SwiftUI에서 사용하던대로 @Published 등을 사용해서 작성하던 방식으로는 작동하지 않았다. 그래서 찾아본 글들의 방식대로 작성했다.


그런데 이해를 하며 코드를 짜겠다고 결심하고 시작한 이 코드 개선에서 알지도 못한 채 복사 붙여넣기 할 수는 없었다. 그래서 Combine과 MVVM에 대해 먼저 공부했다. 그런데 Combine 활용에 있어서 프로토콜의 개념을 이해해야겠다느 생각이 들었다. 그도 그럴게 Combine에 등장하는 Publisher와 Subscriber라는 게 프로토콜인데 이걸 채택해야 한다. 그런데 내가 프로토콜을 제대로 이해하고 있는가...? 장담은 못했다.

그래서 Protocol도 알아봤다. 기본적인 건 내가 사용하던 대로 알던대로였지만, Protocol의 extension을 이용하는 방법 등은 새롭게 알았다. 원론적인 MVVM 개념을 Combine에서 적용시키는 게 어려웠다. 아직도 잘 이해한 것인지 확신이 잘 안선다. 그래서 더 공부해 볼 부분이라고 느끼고 있다.

이렇게 나름 공부도 하고 뷰에 보여지는 값을 바꿀 수 있게 되었다. 그리고 또 하나의 언덕을 마주하게 되는데, 난 지금까지 static cell 방식의 테이블 뷰를 만들어본 적이 없었다.

그래서 'static cell'과 'swift 설정화면 만들기' 등으로 검색해서 알아봤다. 딱히 나에게 유용한 정보는 없었다. 아쉬운 일이었지만, static cell이 별 거 있으랴. 말 그대로 셀의 크기나 갯수가 고정적인 테이블 뷰면 되리라.

그러니 일단 갯수도 크기도 형태도 관련 함수는 이미 다 알고 있으니 만들던 방법대로 다만, 값을 내가 의지한 고정값으로 주었다. 셀의 세부적인 형태는 기본적으로 애플에서 제공하는 형태를 사용하고 싶었다. 그런데 다들 table view에서 설정화면 같은 걸 만들 때 아예 새로운 셀 클래스를 만드는 경우나 contentView에 무언가 추가해서 만드는 경우가 많았다.

'기본적으로 쓸 수 있는 요소가 있는데다 설정화면은 완전히 그 기본 테이블 뷰를 빼다 닮았는데 내가 꼭 새로 만들어야할까?'라는 의문이 들어 더 찾아보니 기본 값을 쓰는 영어 문서를 발견했고 관련 요소 이름을 알아내 검색하여 사용법을 알아냈다.

바로 Xcode로 넘어와 사용하려고 보니... deprecated... 되었다고 한다. 그래서 또 관련 요소들의 deprecated로 검색하고 공식 문서도 당연히 살펴봤다. 그래서 알아낸 현대적인 방법이 UIListConfiguration이었다. 그 뒤로는 공식문서 참고하면서 적절하게 설정 화면을 만들었다.

(static cell로 테이블 뷰를 만드는 것에 대한 자세한 내용은 위에 언급한 UITableViewController의 contentConfiguration 알아보기 에서 다룬다.)


꽤나 돌고 돌아 만드는 데 성공했기 때문에 좀 지쳤었다. 하지만, UIKit와 Combine을 사용한 MVVM 형태는 처음 시도한 것이기에 꽤나 재밌는 경험이었다. 그렇게 만든 설정 뷰는 만족스러웠다.