이번 코드 개선을 시작하게 된 가장 큰 계기인 데이터 관리 코드가 너무 별로였다는 점이다. 말이 좋아서 별로지 이 코드를 봤다면 모두가 한숨을 내쉬었을 정도다.
그런데 여기까지 오기가 꽤 많은 일들을 해치워야했고, 드디어 최종 보스전이다. (마지막 전개편이다.) 이번에는 커밋한 내용이 꽤 많았는데, 그럴만 했다. 준비편에서 계획한 데이터 구조를 기억하는가? 일단 큰 변경 지점이 있었고, 이걸 이전 데이터에도 올바르게 적용했어야했다. 일단은 새로운 테이블 추가, 기존 방식과 다른 모음집 정보 불러오기, 기존 구조의 데이터도 현재에 불러올 수 있도록 코드 추가, 각각의 데이터에 추가 삭제 시 발생 가능한 오류 제거를 해야했다. 그리고 하는 중 문제가 생기면 그것도 해결했다...
우선, 내가 변경한 내용은 다음과 같았다.
부스러기(crumbs)라 부르는 요소가 조각(piece)에 귀속되는데, 이를 조각 파일에 넣어두고 조각의 관리자 클래스인 PieceMO에서 관리했었다. 이를 분리해야 한다.
부스러기를 분리하면서 조각 내에 딕셔너리로 존재하던 값을 구조체로 변경한다.
기존의 객체를 다루는 것과 차이점이 있기에 이전 버전에서 작성된 요소를 불러올 수 있도록 LegacyManager를 구현한다.
카테고리에 대해서 enum으로 작성하고 이에 맞는 string값을 딕셔너리로 구현했었는데, 이를 enum에 String을 상속 받는 것으로 수정한다.
// 변경 전 enum Category: String, Codable, Hashable { case film, game, music, book, show, photo, flag, airplane, piece } let categoryIcon: [Category : String] = [Category.film : "film", /*일부 생략*/] // 변경 후 enum Category: String, Codable, Hashable, CaseIterable { case film = "film" /*일부 생략*/ }
인스턴스를 구분하는 id 항목을 String이 아니라 UUID 객체로 변경한다. Realm에 저장하고 불러올 때만 UUID <-> String 변환을 거치도록 한다.
모음집(Series)와 조각 사이의 관계를 나타내는 Contain이라는 테이블을 신설한다.
데이터 관리 클래스를 별도로 만들어 기존에 뷰 컨트롤러에서 작업하던 데이터 관리 작업을 양도한다. 조각과 모음집 관련으로 생성한다. PieceDataManager와 SeriesDataManager.
Realm과 소통하는 RealmManager를 만들어 데이터 처리 과정 단계를 나눈다. 프로그램 내부 클래스에 생긴 수정 사항을 반영하기 용이하게 만드는 데 초점을 둔다. 앞 서 언급한 두 개의 DataManager하고만 데이터를 주고받는다.
각 DataManager와 RealmManager는 싱글톤 객체로 만들어 사용한다.
class PieceDataManager { private let realm: RealmManager = RealmManager.general public static let general: PieceDataManager = PieceDataManager() // 코드 중략 // 함수 Quick Help Information도 작성 ///신규 조각 하나를 추가합니다. func appendPiece(_ newPiece: Piece) { self.whole.append(newPiece) self.realm.appendNewPieces(newPiece) } //코드 하략 }
대충 이정도의 변경 사항을 목표로 작업했다.
그리고 발생한 오류들 중에 삭제 후 변경 작업 시 index가 제대로 매치되지 않는 오류가 있었는데 이 오류로 생각한다. 그래서 realmManager에서 작업할 때는 인덱스가 아닌 id로 접근하여 수정과 삭제 등이 이루어지도록 변경했다.
기존 문제 중에 UI 오류 메시지가 뜨는데 (보이는 것도 다 잘 보이고 눌리는 것도 다 잘 눌리는) 동작 문제는 없었다. 이유를 모르고 있었는데 놀랍게도 데이터 코드를 싹 정리하고 나니 멀쩡해졌다.
중간에 잠시 그런 문제가 다시 발생했었는데 시뮬레이터 오류였는지 시뮬레이터 껐다 켜니까 그 뒤로는 멀쩡하게 동작했다. 구글에 검색해봤을 때 이 문제는 UI 오류라고 하는 글이 많았는데 일단 고쳐졌지만, 데이터 문제였을 수도 있을 것 같다.
그리고 좀 어이없는 일이긴 하지만 모음집이 삭제 기능이 없었다... 물론 만들어야 한다는 인지도 있었고 이번 업데이트에서 빼놓을 수 없는 부분이었다. 그래서 만들었고 잘 작동했다.
쉽고 재미없는 결말
데이터 변경 작업이 생각보다 쉬웠다. 일단 이전 단계를 거치면서 구조를 명확하게 파악해둔 것이 큰 역할을 했다. 그리고 미리 싱글톤 등 데이터 관리 클래스를 구성할 방법에 대해 고민했기 때문에 실제 작업에서는 시간이 많이 줄었다.
음, 쓰고 나니까 보스전 치고는 굉장히 쉽게 깨진 느낌이다. 실제로도 큰 장벽은 없었다. 하지만 이게 보스전을 치루기 전에 중간 보스들을 잘 처리한 덕분이라고 생각한다. 다음은 결말편인데... 사실 마무리라고 미뤄둔 세세한 부분을 정리하는 단계다.
여담
이 글을 쓰는 지금은 1.1.1 버전을 준비하고 있다. 학교 프로젝트로 바쁘기도 하고... 어쨌든 이 쉽고 재미없는 전개가 이야기로 본다면 그닥 흥미로운 이야기는 아니지만, 괜찮은 이야기라고 생각한다. 왜냐하면 난 개발자고 보스전을 쉽게 깨기 위해 앞의 작업들을 했기 때문에 목표 달성에 성공한 개발자이기 때문이다. ^^