본문 바로가기

개발/Swift

[Swift] CoreData 특정 ID의 데이터만 가져오기 (전달하기)

ObjectID를 받아 편집대상 데이터만 추려서 가져오는 방법입니다.

본 방법은 CoreData에 따로 UUID 프로퍼티를 추가하지않고 진행할 수 있는 방법입니다.

CoreData를 사용해 저장한 데이터는 고유의 objectID가 존재합니다.

특정 데이터의 ObjectID를 받아서 이미 정의된 데이터를 편집할 때 간편하게 사용할 수 있습니다.

아래는 Item이라는 Entity로 저장된 배열 중 선택된 셀의 데이터만 편집용 ViewController를 띄워 편집 할 수 있도록 하는 예시입니다.

코드 흐름

RootViewController에서 선택된 특정 Cell의 ObjectID 를 넘김. (fetchUpdateData 메소드 이용)

EditViewController 에서 ObjectID를 받아 Context에서 해당하는 ID의 데이터 받아오기.

→ 데이터를 가져왔으니 편집 후 context를 저장해주기만 하면 간단히 업데이트 됩니다.

 

구현코드

// RootViewController.swift

let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let itemArray = [Item]()

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    // 선택한 셀의 데이터를를 가져옵니다.
  let item = itemArray[indexPath.row]

    // EditViewController를 생성하고 모달로 띄웁니다.
  let editVC = EditViewController()
  editVC.fetchUpdateData(id: item.objectID) // objectID를 EditVC에 전달하는 부분입니다.
  present(editVC, animated: true) 

}

코드 흐름

// EditViewController.swift

// CoreData의 Context입니다.
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

var item: Item? // RootVC에서 전달한 ObjectID에 해당하는 데이터가 저장될 변수입니다.

var textField = UITextField() // 텍스트필드 구성은 생략합니다.

override func viewDidLoad() {
  super.viewDidLoad()

    // ... 

}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    setupData()
    }

// MARK: RootViewController에서 호출한 메소드 (ObjectID 받아 DB에서 데이터를 가져옵니다)
public func fetchUpdateData(id: NSManagedObjectID) {
  do {
      // ObjectID 받아서 일치하는 Object 반환.
      item = try context.existingObject(with: id) as? Item // 데이터 가져오기
      print("업데이트 대상 데이터 로딩성공")
            self.viewWillAppear(true) // 데이터 로딩 후 기존 Data를 적재적소에 로드합니다.
  } catch {
      print("데이터 가져오기 에러 : \(error.localizedDescription)")
  }
}

// MARK: 가져온 데이터를 적재적소에 셋업합니다. item이 nil이 아닐 때 로드됩니다. 
// (아래는 미리 구성한 텍스트필드의 텍스트에 넣는 예시)
private func setupData() {

    if self.item != nil {
        self.textField.text = item.title // 텍스트필드에 기존 데이터의 텍스트 반영
    }

}

// MARK: 변경한 데이터를 DB에 저장합니다.
private func saveData() {
    // 아래처럼 반영하면 Context가 데이터가 변경됨을 자동으로 감지합니다.
    self.item.title = self.textField.text 

    // 대기중인 context를 DB에 업데이트 합니다.
  do {            
      try context.save()
            print("데이터 업데이트 완료!")
            self.dismiss(animated: true) // 모달을 닫습니다.
  } catch {
      print("context 저장중 에러 발생 : \(error.localizedDescription)")
  }
}

 

`만약 코드가 제대로 작동하지 않거나, 틀린 부분이 있다면 댓글 남겨주시면 수정하도록 하겠습니다!
반응형