iOS로 데이터를 지속적으로 유지하는 방법

23385 단어 iOStech
제작시간:2016-07-01
iOS version: 9
이 발언에서는 iOS의 파일 시스템을 이해하고 데이터(iCloud 포함)를 지속하는 방법을 소개한다.또한 샘플 코드는 이동할 수 없으니 참고해 주십시오.

iOS File System


프로그램이 파일 시스템과 교환할 수 있는 곳은 프로그램의 샌드박스 안의 디렉터리에 의해 거의 제한된다.새 프로그램을 설치할 때, 설치기는 모래상자에 여러 개의 용기를 만들고, 그림1과 같은 구조를 사용합니다.각 컨테이너가 작동하며 Bundle Container는 어플리케이션의 번들을 저장하고 Data Container는 어플리케이션과 사용자 모두의 데이터를 저장합니다.Data Container는 용도에 따라 여러 디렉토리로 추가되었습니다.응용 프로그램은 실행 시 iCloud Contaainer와 같은 추가 컨테이너에 대한 액세스를 요청할 수 있습니다.

그림 1.An iOS app operating within its own sandbox
표1은 각 용기 내의 중요한 하위 디렉터리의 용도와 접근 제한을 총괄하였다.서류의 종류와 이에 대응하는 보존장소는 안내서에 명시돼 있어 위반할 경우 프로젝트의 대상이 될 수 있어 주의가 필요하다.
표 1.Commonly used directories of an iOS app
카탈로그
설명
iTunes, iCloud 백업 객체AppName .app
주요 두건으로 불리다.응용 프로그램과 응용 프로그램이 포함된 자원 파일의 디렉터리입니다.읽기 전용입니다.
NO
Documents/
사용자가 만든 내용 등을 저장하는 위치입니다.
YES
Documents/Inbox/
다른 프로그램에서 파일을 받을 때 사용하는 디렉터리입니다.읽기 전용입니다.
YES
Library/
응용 프로그램이 사용하는 데이터를 저장하는 곳.자주 사용하는 하위 디렉토리에는 애플 지원 및 Caches가 있으며 사용자 정의 디렉토리를 만들 수도 있습니다.
YES
Library/Application Support/
응용 프로그램이 사용하는 데이터를 저장하는 곳.
YES
Library/Caches/
임시 데이터를 저장하거나 복구할 수 있는 곳을 다시 다운로드합니다.애플리케이션에서 데이터의 추가 및 삭제를 관리해야 합니다.그러나 디스크 공간 부족 등으로 인해 시스템이 자동으로 삭제될 수도 있다.
NO
Library/Preferences/
NSUserDefaults의 데이터가 저장된 곳입니다.
YES
tmp/
임시 데이터를 저장하는 위치입니다.사용 후 응용 프로그램에서 삭제해야 합니다.그러나 프로그램이 실행되지 않을 때 시스템이 자동으로 삭제될 수 있습니다.
NO

Path to Directory


다양한 디렉토리 경로를 가져오는 방법
let manager = FileManager.default()

// Documents/
let documentDir = manager.urlsForDirectory(.documentDirectory, inDomains: .userDomainMask)[0]

// Library/
let libraryDir = manager.urlsForDirectory(.libraryDirectory, inDomains: .userDomainMask)[0]

// Library/Application Support/
let applicationSupportDir = manager.urlsForDirectory(.applicationSupportDirectory, inDomains: .userDomainMask)[0]

// Library/Caches/
let cachesDir = manager.urlsForDirectory(.cachesDirectory, inDomains: .userDomainMask)[0]

// tmp/
let tmpDir = manager.temporaryDirectoy

Write/Read Files


iOS에서 객체를 파일에 저장할 경우
  • 아카이빙(직렬화)
  • 속성 목록(*.plist)
  • 두 가지 용법이 있다.아카이빙은 객체를 아카이빙이라고 하는 NSData 형식으로 간단하게 변환한 후 파일에 저장하는 방법입니다.또한 NSAray와 NSDictionary 클래스는 각각 속성 목록으로 저장되는 메커니즘을 제공합니다.
    아카이브 저장 예
    // UIImageの保存
    let imagePath = documentDir.appendingPathComponent("sample.png")
    let image = UIImage(named: "bundle_image.png")
    // 書き込み
    UIImagePNGRepresentation(image)?.write(to: imagePath, atomically: true)
    // 読み込み
    UIImage(data: NSData(contentsOf: imagePath))
    
    // Stringの保存
    let strPath = documentDir.appendingPathComponent("sample.txt")
    let str = "Sample text"
    let data = str.data(using: .utf8)
    // 書き込み
    data?.write(to: strPath)
    // 読み込み
    String(data: Data(contentsOf: strPath), encoding: .utf8)
    
    속성 목록으로 저장된 예
    let path = documentDir.appendingPathComponent("sample.plist")
    var user = NSDictionary(dictionary: ["Name":"Tim Cook"])
    
    // 書き込み
    user.write(to: path, atomically: true)
    
    // 読み込み
    var user = NSDictionary(contentsOf: path)
    

    Data Managing Services


    SDK는 용도에 따라 NSUserDefaults 또는 Core Data를 사용하여 관리할 수 있는 기본 데이터 관리 메커니즘을 갖추고 있습니다.또 코어데이터 대신 리얼엠이라는 모바일용 데이터베이스를 사용하는 경우도 늘고 있지만 여기서 생략한다.
    표 2.Commonly used services for managing data in iOS app
    타입
    설명
    NSUserDefaults
    모든 객체를 Key/Value 방식으로 저장하거나 읽을 수 있습니다.plist로 저장됩니다.
    Core Data
    SQLite용 ORMDB 파일은 Docoments/아래에 작성됩니다.
    Keychain
    암호화 저장소.암호, 기밀 키, 인증서 등을 안전하게 저장하는 데 사용됩니다.

    iCloud Storage


    iCloud에 데이터를 저장하여 여러 터미널에서 같은 데이터를 액세스할 수 있습니다.iCloud에는 표 3과 같은 3가지 저장 유형이 있는데 용도에 따라 분리해서 사용한다.각 서비스를 이용하려면 Xcode 프로젝트의 Capabilities 탭에서 iCloud를 ON으로 설정하고 미리 설정해야 합니다.
    표 3.Types of storage service in iCloud
    타입
    설명
    Key-value storage
    프로그램의 설정과 상태 등을 저장하기 위한 KVS.최대 용량은 애플리케이션당 1MB입니다.
    iCloud Documents
    파일 기반 스토리지(Core Data 포함).문서, 드로잉 파일 또는 복잡한 응용 프로그램의 상태 등을 저장하는 데 사용할 수 있습니다.최대 저장 용량은 사용자의 iCloud 계정에 따라 달라집니다.
    CloudKit storage
    애플이 제공하는 BaaS 내 저장 기능.구조화된 데이터를 관리하거나 사용자 간에 공유하고자 하는 파일이나 데이터를 저장할 수 있습니다.데이터베이스는 데이터를 관리하는 데 사용되며 각 레코드는 KVS로 간주됩니다.

    Key-value storage


    NSUbiquitousKeyValueStore 클래스를 사용하여 iCloud Key-value stoge에 액세스합니다.기록된 데이터는 먼저 메모리에서 유지된 다음에 시스템이 적당한 시간에 디스크에 기록합니다.iCloud 계정에 로그인하지 않은 상태에서 쓰기를 진행하면 데이터는 다음 동기화까지 로컬로 저장됩니다.사용자가 iCloud 계정에 로그인하면 시스템은 자동으로 로컬 KVS 및 iCloud 서버의 계정 끝을 확인합니다.
    코드 예
    // AppDelegate.swift
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        let kvs = NSUbiquitousKeyValueStore.default()
    
        // register to observe notifications from the store
        NSNotificationCenter.defaultCenter()
                            .addObserver(self,
                                         selector: #selector(storeDidChange:),
                                         name: NSUbiquitousKeyValueStoreDidChangeExternallyNotification,
                                         object: kvs)
    
        // get changes that might have happened while this
        // instance of your app wasn't running
        kvs.synchronize()
    
        // Get/Set value
        kvs.set("Value", forKey: "Key")
        kvs.string(forKey: "Key")
    
        return true
    }
    

    iCloud Documents


    응용 프로그램이 처리한 문서 UIDocument 의 클래스 대상을 계승함) 를 iCloud에 저장하는 서비스입니다.여기서 설명한 문서는 디스크에 단일 파일 또는 패키지로 쓸 수 있는 데이터의 집합체입니다.로컬에서는 iCloud Contaainer에 파일이 배치되고 Doocuments/이하 파일이 사용자에게 공개됩니다.이외에 배치된 파일, 디렉터리는 사용자에게 공개되지 않습니다.
    문서는 기본적으로 iCloud api를 지원하며 iCloud의 파일 변경과 로컬 파일 변경을 잘 조정합니다.이것은 NSFileCoordinator류 대상과 NSFilePresenter 협의를 통해 실현된다.파일을 열고 저장하고 이름을 바꾸는 UI를 응용 프로그램에 설치해야 합니다.
    코드 예
    let manager = FileManager.default()
    let containerPath = manager.urlForUbiquityContainerIdentifier(nil)
    let documentPath = containerPath.appendingPathComponent("Documents")
    let filePath = documentPath.appendingPathComponent("document.key")
    
    // Create document file to iCloud Container
    let document = UIDocument(fileURL: filePath)
    document.save(to: document.fileURL, for: .forCreating)
    
    // Download is automatically done by the OS
    
    와 코어데이터도 UIManagedDocument 클래스(UIDocument의 하위 클래스)를 이용하여 같은 방식으로 iCloud와 동기화할 수 있다.

    CloudKit


    기본적으로 다른 사용자와 공유한 데이터를 저장하는 서비스다.각 기록은 KVS로 간주되며 단순 유형(문자열, 숫자, 날짜 등)에서 복잡한 유형(위치 정보, 참고, 자산 등)의 대상에 대응한다.
    다른 iCloud 서비스와 마찬가지로 데이터는 로컬 컨테이너에 생성되고 시스템에서 동기화됩니다.CKContainer 대상은 용기 내의 데이터베이스CKDatabase 대상에 접근할 수 있다.
    코드 예
    let container = CKContainer.default()
    let database = container.publicCloudDatabase
    
    // Create record
    let record = CKRecord(recordType: "employee")
    record.setObject("Jacob", forKey: "firstName")
    record.setObject("Nielsen", forKey: "lastName")
    database.save(record, completionHandler: { (record: CKRecord?, error: NSError?) -> Void in })
    
    // Fetch record
    let recordID = record.recordID
    database.fetch(withRecordID: recordID, completionHandler: { (record: CKRecord?, error: NSError?) -> Void in
    })
    

    Reference

  • File System Programming Guide
  • iCloud Design Guide
  • 좋은 웹페이지 즐겨찾기