iCloud Data Back Up

kuruma-42·2022년 2월 21일
0

swift

목록 보기
17/19
post-thumbnail

Motivate?

  • iOS는 SandBox구조라 fileManager를 사용해서 앱내 디렉토리에만 filePath를 생성할 수 있고,
    앱을 삭제하면 백업 파일이 지워진다고 공식문서에도 있다고 몇 번을 얘기했지만, 받아들여지지 않았다.
  • iCloud Sand Box Description
  • 결국, 내부에서 DB 데이터를 백업해서 에어드랍으로 보내라는 지시를 받았다.
    하지만 이 또한 매우 위험한 결정이다.

Risk?

  • info.plist에서 상기의 두 가지 항목을 선택해 YES로 바꿔야지만 나의 iPhone 카테고리에서
    백업 파일에 접근 하는 것이 가능해진다. 하지만, 이렇게 접근하게 되면 앱 내부의 파일에 접근할 수 있기 때문에 보안 이슈가 생긴다.
  • 위의 위험성 까지 말했지만 일단 해보자는 말에 구현을 하면서 이슈를 잡아보자고 생각했다.
  • 물론, 공식문서를 안 믿는 것은 어떤 이유인지 모르겠지만.

Any Alternative?

  • 일단, iPhone 앱 기획을 하면서 기기 간 데이터 백업에 대해 걱정하는 게 약간 어불성설 같았다.
  • 우선 구현을 진행하면서 앱 기획팀에게 Migration이라는 기능을 검토해봤냐고 물어봤다.
  • 앱 기획팀 대부분이 iPhone을 사용하지만 Migration에 대해서는 잘 모르는 것 같았다.
  • 핸드폰을 사면 대리점에서 해주는 경우가 많으니 그럴 수 있다고 긍정적으로 생각해보기로 했다.
  • iPhone Migration 왼쪽 링크인 마이그레이션 공식 문서를 보면 앱의 모든 게 옮겨지기 때문에 유저들도 쉽게 언제든지 기기를 교체할 수 있다. 카톡의 경우 대화내용을 따로 다운받을 필요도 없고, 은행 앱도 로그인을 해야하는 것도 있고 없는 것도 정말 마법 같은 기능이다.
  • 에어드랍으로 옮기는 기능을 다 완성한 뒤에 마이그레이션을 기획팀에 보여줬더니, 기기 간 데이터 백업은 마이그레이션으로 진행되는 것으로 합의를 봤다.

Why iCloud?

  • 그렇게 끝날 줄 알았던 백업 일정은 유저가 같은 기기에서 지웠다가 설치하는 경우를 상정해서
  • (자사 서비스는 마이데이터 기반 서비스이기 때문에 서버에 데이터를 저장하지 않는다.)
  • 개인 클라우드에 올릴 것인지, 유저들이 Google Drive를 연동해 데이터를 옮길 것인지 선택하라고 했다.
  • 나는 개인적으로 Native 기능들을 매우 좋아한다. 자연스러운 애니메이션, 유저의 안전까지 생각하기 때문이다.
  • iCloud를 사용해 백업을 하기로 최종 결정했다.

What Is Important?

  • iCloud를 사용하는 방법은 굉장히 많았다.
  • 첫 번째, CoreData를 iCloud에 연동하는 방법
  • 두 번째, Object형태의 저장을 포기하고 Key-Value 형식으로 최대 1024개의 데이터를 저장하는 방법
  • 세 번째, FileManager를 사용해서 iCloud에 데이터를 올리는 방법이다.
  • 자사 서비스는 대규모 데이터를 저장하고 사용하기 위해 RealmDB를 사용하고 있기 때문에 CoreData를 사용하는 방법은 사용하지 않기로 했다.
  • Key - Value값으로 저장하자고 하니, Zip으로 압축된 데이터를 올리는 시나리오가 있기 때문에 사용하지 않기로 했다.
  • 결국 세 번째, RealmDB데이터를 ZipFile로 압축하고, 압축 할 당시에 보안을 위해 데이터 암호화, ZipFile 암호화 등을 통해 보안을 챙기기로 했다.

Difficult

  • 자료가 없다. 제대로 된 자료를 구하기가 굉장히 힘들었다.
  • 공식 문서에서도 찾기 힘들었고 iCloud에 올리는 Code들은 많았으나 대부분 iCloud Drive에 데이터가 업로드 되지 않았다. 그리고 대부분 데이터 업로드의 확인을 하기의 사진처럼 하라고 했다.

  • iCloud도 결국 SandBox의 형태로 iCloud 외부로 데이터를 쓸 수 없다고 했다.
  • 따라서 상기의 상태로 밖에는 업로드 할 수 없다고 했다.
  • 어디까지나 블로그에 그렇게 쓰여있었을 뿐, 아직 공식문서에는 그런 언급을 찾을 수 없어 좀 더 찾아봤다.
  • iCloud Programming Guide Apple Document
  • iOS 명언이 있다. "급하면 급할 수록 공식문서를 봐라."
  • 상기의 문서를 밑으로 쭉 내리면 빛나는 자료를 얻을 수 있다.

Process

  • 상기의 사진에서 보이는 코드를 우리 앱 이름에 맞춰 plist에 넣으면 된다.
  • plist 파일에서 Key Value 값으로 Property 이름이 NSUbiq...로 시작하는 것은 없으니
  • plist를 우클릭 해서 Open As Source로 열고 가장 바깥 "dict /dict" 안 쪽에 넣어주면 된다.

  • 상기의 이미지 처럼 앱의 Build & Capabilities에 가서 iCloud를 추가해주고
  • iColud Documents 체크박스를 체크해준다.
  • 이렇게 하고 iOS Developer에 가서 Certificates & Identifier를 조작해줘야 한다.

  • 개발자 계정에 접속해서 상기의 카테고리로 간다.
  • 화면을 내리다 보면 iCloud가 활성화가 안 되어있을텐데 활성하 시켜준다.
  • 상기의 사진처럼 우측에 돋보기를 누르면 iCloud Container라는 것이 나오는데
  • 거기서 Container를 추가해 주면 된다.
  • 반드시 이름을 많이 생각하고 예쁘게 짓기를 바라겠다. 바꾸는 작업은 생각보다 귀찮을 수 있다.
  • 이렇게 설정하고 나면 하기의 사진에서
  • Containers 부분에 선택을 할 수 있는 부분이 생길 것이다.
  • 거기서 Container를 체크하면 우리는 FileManager를 통해서 접근할 수 있는 세팅을 마쳤다.
  • 만약 여기까지 했는데 Filemanager를 통해서 UbiqContainer쪽에 접근이 안 되거나, nil이 계속 나온다면. App.entitlement를 확인해보자.

  • 상기의 이미지와 같은 Key Value 값들이 entitlement에 생기지 않았다면.
	<key>com.apple.developer.icloud-container-identifiers</key>
	<array>
		<string>Your App Container Name</string>
	</array>
	<key>com.apple.developer.icloud-services</key>
	<array>
		<string>CloudDocuments</string>
	</array>
	<key>com.apple.developer.ubiquity-container-identifiers</key>
	<array>
		<string>Your App Container Name</string>
	</array>
  • Open As Source로 열고 상기의 코드를 자신의 앱에 맞게 수정한 뒤 저장해주면 올바르게 동작할 것이다.
  • 이렇게 하면 우리의 앱이 FileManager를 통해 iCloud Driver에 FileManager를 통해 읽고 쓰기가 가능해진다.
  • 여기까지가 자료조사와 세팅의 과정이다.
  • 로직을 짜는 것은 어렵지 않다, 하지만 자료가 숨어있다 끈기를 가지고 찾고
  • 판단 기준을 공식문서로 두고, 된다 안 된다의 근거를 찾아 움직여야 한다.

Code & Logic

  • 대략적인 테스트 코드는 github의 뷰모델 쪽에 가보면, 구현이 되어있다.
  • iOS Developer ChaCha Github
  • 회사에서 요구했던 기능은 유저가 데이터를 백업할 때 백업 비밀번호를 설정하고
  • 다시 데이터를 복원할 때 예전에 만들었던 비밀번호를 입력하면 데이터가 복원되는 시나리오를 요구했다.
  • 현재는 이 시나리오도 모두 구현된 상태이며 지속적으로 테스터들이 테스트 하며, 새로운 예외를 찾아 대응하는 중이다.

Development Tip 🎾

// Set iCloudDocsURL Here & Do Nil Check
if let iCloudDocsURL = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents") {
 // Set Logic Here
} else {
// Handling Exception Here When You Developing
print("TEST BACK UP :: iCLOUD URL IS NIL CHECK XCODE SETTING")
}
  • 상기의 코드는 유저가 iCloud Drive를 사용설정을 했는지 안 했는지 우회적으로 알 수 있는 방법이다.
  • 상기의 변수 iCloudDocsURL이 nil이 나오면 User가 iCloud Drive 연결을 안 한 것이니
  • else 부분에서 Alert를 띄워주거나, 아예 데이터 백업 화면으로 진입을 못하게 하면 된다.

FileManager Tip

  • FileManager Copy, Move, Remove는 동기로 동작하는 기능이다.
  • 공식문서에는 명시적으로 Return Value가 없으며 do-try-catch를 사용해서 개발을 해야하고
  • Error를 Throw 하는 형태이다. 따라서 로직을 개발할 때 조금 괴롭다.
  • FileManager Apple Docs
  • 안드로이드 개발자가 PM으로 있거나 안드로이드 개발자가 회사에서 iOS를 개발하고 있는 상황의 사람들이라면 FileManager가 비동기가 아니고 Return Value가 없이 do-catch-throw로 개발을 진행해야 하는 것을 문서를 통해 알려줘야 한다.
  • iCloud는 용량이 꽉차도 error를 throw 안 한다.
  • iCloud Drive에 가서 확인해 보면 파일 이름이 올라가 있고 대기중이라는 메세지가 있다.
  • 미리 용량을 체크하지 왜 체크하지 않냐고 반문한다면 하기의 두 개의 자료를 체크해보자.
  • iCloud Storage Check is Impossible Apple Docs
  • Code Lab From Stack Over Flow
  • 상기의 두 자료를 요약하자면, 우리는 개발을 하면서 유저의 특정 ubiquitycontaineridentifie를 식별할 수 없다.
  • 식별하려고 하면 Local Container의 위치를 보내며, 용량체크를 하면 ubiquitycontainer의 용량이 리턴되는 게 아니라 Local Container의 용량을 보낸다. 라는 내용이 있다.

FileManager Delegate

  • FileManager Delegate Apple Docs
  • 상기의 링크는 FileManagerDelegate에 대한 문서인데
  • SwiftUI로 개발을 진행하는 입장에서 Delegate로 Task의 결과를 받는 것은 구조상 그렇게 좋지 않다.
  • Coordinator Pattern을 구현해야 하며, MVVM 구조도 깨진다고 생각한다.
  • 현재 상기의 문서에서 Coordinator Pattern을 써서라도 테스트 해보려고 생각하는 것은
  • 상기의 두 가지 기능인데 다음 기능 개발 일정이 빠듯해서 테스트 할 수 있을지 의문이다.
  • 상기의 두 가지 기능을 구현한 블로그나 테스트 코드를 찾으려고 노력했으나 구현 되어있는 곳은 없었다.
  • 후에, 추가적으로 이 기능에 대해서 연재하겠다. 아니면 따로 FileManager 편을 만들어서 포스팅하겠다.

Review✨

  • 신입에서 이제 막 1년차에 접어 들었는데 우선, iCloud 관련 일을 하게 되서 굉장히 재밌었다.
  • 문서를 끈기있고 깊게 찾아봐야겠다고 다시 한 번 생각하게 되었다.
  • iCloud 업로드 로직은 마음에 들게 만들었지만, 팀원이 만들어준 RealmDB BackUp기능은 조금 더 기능 개선과 그에 따른 예외 처리를 늘려야겠다고 생각했다.
  • 추후에는 CoreData 와 iCloud Kit의 연동 실습과 Key Value 형태로 iCloud를 저장하는 실습도 해보고싶다.
  • FileManager에 대해서 조금 더 공부해봐야 겠다.
  • FileManager의 기능들을 여러번 쓰게되면 do-try-catch가 계속 깊어지는데 분명히 다른 해결책이 있을 것이라고 생각된다.
  • 안드로이드를 기준으로 기획이 나오면 강하게 어필을 해야하며 공식 문서와 정책을 기획팀에게 보내줘야한다.
  • 그리고 안드로이드와 다르게 생각하도록 계속 소통해야한다.
  • 안드로이드 기준으로 나온 기획들을 뒤집으려면 AHIG에 대한 스스로의 이해가 필요하다
  • 이번 iCloud 개발을 통해서 Programming Guide는 물론 AHIG까지 깊게 숙지하려고 공부를 해야겠다.
  • iCloud에 대해서 Apple이 방어적인 이유는 iCloud는 유료이고, 소비자의 사적인 데이터들이 담겨있기 때문이라고 생각한다.

0개의 댓글