set의 연산을 이용한 Local - Remote DB 연동하기

jane·2022년 5월 2일
0

Swift

목록 보기
7/7
post-thumbnail

네트워크 연결이 끊어진 오프라인 환경에서 데이터 변경사항이 생길 경우

  • 먼저 Local에 저장한 후에,
  • 네트워크가 다시 연결되면 Local의 변경사항을 Remote에 업데이트하는 방식으로 구현하였다.

Remote에서 변경이 일어날 가능성은 없으므로 Remote변경사항을 Local에 업데이트하는 부분은 배제하였다.

Local의 변경사항을 Remote에 업데이트할 때 Set의 메서드들을 활용하여 두 데이터를 연동하였다.


오프라인에서 추가/삭제/수정된 Project를 찾아서 Remote에서도 똑같이 추가/삭제/수정해주는 방식을 사용했다.

각 Project를 identify할 수 있는 ID 프로퍼티를 활용하였다.

let localIDSet = Set(localProjects.map { $0.id })
let remoteIDSet = Set(remoteProjects.map { $0.id })
  • 오프라인에서 Local에만 새로 추가된 ID를 구하려면 Local - Remote 한 결과를
    Remote에도 추가하기
let locallyAppendedIDSet = Set(localIDSet).subtracting(Set(remoteIDSet))
let locallyAppendedProjects = localProjects.filter {
       locallyAppendedIDSet.contains($0.id)
}
  • 오프라인 환경에서 Local에만 삭제된 ID를 구하려면 Remote - Local 한 결과를
    Remote에서도 삭제
let deletedIDSet = remoteIDSet.subtracting(localIDSet)
let locallyDeletedProjects = remoteProjects.filter {
     deletedIDSet.contains($0.id)
}
  • 오프라인에서 Local에만 수정된 ID를 구하려면 둘다 동일하게 가진 ID에서 수정이 일어나지 않은 부분을 제외하면 된다.
    - Remote와 Local의 교집합 부분은 둘다 동일하게 가진 ID들로써 수정이 일어나지 않았거나, 수정이 일어난 ID들이다.
    - 수정이 일어나지 않은 부분은 가만히 놔둠 (어짜피 Local, Remote 똑같으니 굳이 업데이트 안해도됨)
    - 요기서 수정이 일어났는지는 어케 아냐면, 수정시에 Project 객체의 updatedAt 프로퍼티에 Date()를 할당하여, 만약 Local의 updatedAt이 Remote보다 최신일 경우, 오프라인에서 수정이 일어난 것
    Remote에서도 수정
let intersectingIDSet = localIDSet.intersection(remoteIDSet)
let intersectingLocalProjects = localProjects.filter {
   intersectingIDSet.contains($0.id)
}
let intersectingRemoteProjects = remoteProjects.filter {
   intersectingIDSet.contains($0.id)
}

intersectingRemoteProjects.flatMap { remoteProject in
     intersectingLocalProjects.filter { localProject in
     localProject.updatedAt > remoteProject.updatedAt
   }
}
profile
제가 나중에 다시 보려고 기록합니다 ✏️

0개의 댓글