본문 바로가기

iOS

[트러블 슈팅] CoreData의 Entity Attribute의 타입을 변경한 경우

배경

JSON으로 받아온 데이터 항목중 하나를 다른걸로 변경하고자 했습니다.

위 사진은 JSON 항목중 일부를 나타낸 사진입니다

기존에 CoreData에  time_last_update_utc인 String 타입 문자열을 저장하다가, time_next_update_unix로 항목을 변경해야 했습니다.

 

그래서 Int타입을 받기 위해 Attribute의 updateTime 타입을 String -> Integer 64로 변경했습니다.

CoreData를 불러오는 메서드도 모두 Int형식으로 받도록 수정하였습니다.

 

 

⚠️ 문제발생

 

CoreData에 저장된 updateTime 속성을 Int타입으로 값 갱신하는 과정에서 치명적인 오류가 발생했습니다.

 

Persistent store migration failed, missing mapping model

- 마이그레이션을 실패했고, 모델 매핑을 실패했다!

 

사실 타입을 변경하는 것은 매우 위험한 일이라고 생각했지만, 혹시나 바꿔도 자동으로 추론을 해줄까? 하는 생각에 진행했지만 역시나 오류가 발생했습니다.

이는 기존에 updateTime 속성이 String이고 새롭게 값을 갱신하는 과정에서 새로운 값이 Int타입이여서 원인이 되었던걸로 보입니다.

 

🤔 어떻게 해결할까?

 

업데이트 과정에서 기존에 저장된 코어데이터 모델과 새로운 값의 모델이 달라서 그런거니까 그냥 기존 데이터를 밀어버리면 되지 않을까?

- 가장 간단하고 쉬운 방법이 될 수 있겠습니다.

- 하지만 이미 배포되었고 앱 사용자들이 개인의 CoreData를 갖고 있다면... 모든 사용자한테 "앱 한번 삭제하고 재설치해주세요!" 라고 부탁할 수는 없을 것입니다.

 

 

1. 기존의 코어데이터 모델을 유지하고, 호출 및 사용부분에서 따로 타입변환을 하자

CoreData에 저장된 값을 새로운 값으로 업데이트 하려면 데이터 모델을 그대로 유지해야 합니다.

타입 변환과정을 통해 호출부분에서 타입을 변환하여 사용하는 방법이 있습니다.

 

 

2. 매핑모델을 구현하여 새로운 모델로 마이그레이션 하자.

실제 서비스중인 앱이라면, 저장된 코어데이터를 새로운 데이터모델로 마이그레이션 하는 방법이 있습니다.

Xcode에서 Mapping Model이 존재합니다.

Mapping Model의 source에 기존에 사용하던 데이터 모델을 넣고, destination에 새롭게 구현한 데이터 모델을 넣어 매핑하도록 구현했습니다.