NSKeyedArchiver

2024. 9. 11. 12:45·iOS/UIKit
반응형

NSKeyedArchiver

 

오브젝트의 데이터를 key로 참조해서 기록하는 encoder다.

 

 

NSKeyedUnarchiver

key로 참조해서 오브젝트의 데이터를  복원하는 decoder다.


UserDefaults와 차이점

나는 지금까지 데이터를 저장할 때 UserDefaults를 이용했지만 이 아카이버의 역할은 무엇일까??

  NSKeyedArchiver UserDefaults
저장 방식 Key - Value
데이터 타입 매핑 여부 O
상위 하위 관계 매핑 여부 O X

 

공통점이 많은 인터페이스 가지만 큰 차이점이 존재한다.

바로 상속과 같은 복잡한 데이터의 관계를 같이 저장하는데 차이가 있다.

 

흠.. 상하 관계가 있다는 것은 상속을 쓴다는 것이고 NSKeyedArchiver는 클래스를 저장할 때 많이 쓰이는군.. 으로 예상된다.

 

한번 예시 코드와 함께 사용법을 익혀보자.

 


전제 조건

루트와 하위 모든 클래스 타입에서 NSCoding과 NSObject 을 채택, 상속해야한다. 

애플에서 NScoding을 직접 채택하는것보다 NSSecureCoding을 채택하는게 좋다고하니 그 방식으로 진행해보자.

 

위 두 내용에 대한 포스팅은 아래를 참고하자

NScoding와 관련된 포스팅

NSObject와 관련된 포스팅

 

 

1.  클래스 정의

a.encode(with:)

말그대로 어떤 key로 어떤 value로 저장할지 명시한다.

위 사진과 같이 타입별로 정말 많은 api들이 제공된다.

 

b.init?(coder:)

반대로 key를 통해 저장할 값을 decode하는 과정을 겪는다.

 

다음 예는 Canvas란 root를 두고 Circle과 Triangle을 갖고 있는 구조이다.

 

다음 과정을 통해 저장과 복원과정을 살펴보자

 

import Foundation

final class Triangle : NSObject, NSSecureCoding {
    static var supportsSecureCoding: Bool {
        return true
    }
    
    
    let width: Double
    let height: Double
    
    init(width: Double, height: Double){
        self.width = width
        self.height = height
        print(#file, #function)
    }
    
    func encode(with coder: NSCoder) {
        // encode(value:, forKey:) value 값을 해당 key로 인코딩
        coder.encode(width, forKey: "width")
        coder.encode(height, forKey: "height")
        print(#file, #function)
    }
    
    init?(coder: NSCoder) {
        // 디코딩
        width = coder.decodeDouble(forKey: "width")
        height = coder.decodeDouble(forKey: "height")
        print(#file, #function)
    }

}


====================================================================================

import Foundation

final class Circle : NSObject, NSSecureCoding {
    
    static var supportsSecureCoding: Bool {
        return true
    }
    
    let radius : Double
    
    init(radius: Double){
        self.radius = radius
        print(#file, #function)
    }
    
    func encode(with coder: NSCoder) {
        // encode(value:, forKey:) value 값을 해당 key로 인코딩
        coder.encode(radius, forKey: "radius")
        print(#file, #function)
    }
    
    init?(coder: NSCoder) {
        // 디코딩
        radius = coder.decodeDouble(forKey: "radius")
        print(#file, #function)
    }
    
}


====================================================================================

import Foundation

final class Canvas: NSObject, NSSecureCoding {
    static var supportsSecureCoding: Bool {
        return true
    }
    
    let circle: Circle
    let triangle: Triangle
    
    init(circle: Circle, triangle: Triangle, owner: String) {
        self.circle = circle
        self.triangle = triangle
        print(#file, #function)
    }
    
    required init?(coder: NSCoder) {
        print(#file, #function)
        guard let circle = coder.decodeObject(of: Circle.self, forKey: "circle"),
              let triangle = coder.decodeObject(of: Triangle.self, forKey: "triangle")
              else { assert(false) }
              self.circle = circle
              self.triangle = triangle
    }
    
    func encode(with coder: NSCoder) {
        print(#file, #function)
        coder.encode(circle, forKey: "circle")
        coder.encode(triangle, forKey: "triangle")
    }
    
}

 


2. archiver and unarchiver interface 이용

    func archvie(rootObject: Canvas) -> Data {
        do {
            let data = try NSKeyedArchiver.archivedData(withRootObject: rootObject, requiringSecureCoding: true)
            return data
        } catch {
            fatalError("Encoing Error")
        }
    }
    
    func unArchive(data: Data) -> Canvas {
        do {
            let unArchiver = try NSKeyedUnarchiver(forReadingFrom: data)
            unArchiver.requiresSecureCoding = true
            guard let object = unArchiver.decodeObject(of: Canvas.self , forKey: NSKeyedArchiveRootObjectKey) else { fatalError("Decode Error")}
            return object
        } catch {
            fatalError("Decoding Eror")
        }
    }

결과

let data = archvie(rootObject: canvas)
let object = unArchive(data: data)


print("Data: \(data)")
print("object: \(object)")

 

참고

 

NSKeyedArchiver | Apple Developer Documentation

An encoder that stores an object’s data to an archive referenced by keys.

developer.apple.com

 

 

NSKeyedUnarchiver | Apple Developer Documentation

A decoder that restores data from an archive referenced by keys.

developer.apple.com

 

반응형

'iOS > UIKit' 카테고리의 다른 글

UIEditMenuInteraction  (3) 2024.10.12
UISearchController  (1) 2024.10.06
NSCoding , NSSecureCoding  (0) 2024.09.10
NSObject  (2) 2024.09.10
UIGraphics  (0) 2024.09.06
'iOS/UIKit' 카테고리의 다른 글
  • UIEditMenuInteraction
  • UISearchController
  • NSCoding , NSSecureCoding
  • NSObject
Hamp
Hamp
남들에게 보여주기 부끄러운 잡다한 글을 적어 나가는 자칭 기술 블로그입니다.
  • Hamp
    Hamp의 분리수거함
    Hamp
  • 전체
    오늘
    어제
    • 분류 전체보기 (312) N
      • CS (30)
        • 객체지향 (2)
        • Network (7)
        • OS (6)
        • 자료구조 (1)
        • LiveStreaming (3)
        • 이미지 (1)
        • 잡다한 질문 정리 (0)
        • Hardware (2)
        • 이론 (6)
        • 컴퓨터 그래픽스 (0)
      • Firebase (3)
      • Programing Langauge (40) N
        • swift (33) N
        • python (6) N
        • Kotlin (1)
      • iOS (132)
        • UIKit (37)
        • Combine (1)
        • SwiftUI (32)
        • Framework (7)
        • Swift Concurrency (22)
        • Tuist (6)
        • Setting (11)
        • Modularization (1)
        • Instruments (6)
      • PS (59)
        • 프로그래머스 (24)
        • 백준 (13)
        • LeetCode (19)
        • 알고리즘 (3)
      • Git (18)
        • 명령어 (4)
        • 이론 (2)
        • hooks (1)
        • config (2)
        • action (7)
      • Shell Script (2)
      • Linux (6)
        • 명령어 (5)
      • Spring (15)
        • 어노테이션 (3)
        • 튜토리얼 (11)
      • CI-CD (4)
      • Android (0)
        • Jetpack Compose (0)
      • AI (3) N
        • 이론 (3) N
  • 블로그 메뉴

    • 홈
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    concurrency
    프로그래머스
    boostcamp
    IOS
    property
    dp
    GIT
    SwiftUI
    dispatch
    Swift
    CS
    UIKit
    protocol
    AVFoundation
    백준
    투포인터
    dfs
    Spring
    lifecycle
    Tuist
  • 최근 댓글

  • 최근 글

  • 반응형
  • hELLO· Designed By정상우.v4.10.0
Hamp
NSKeyedArchiver
상단으로

티스토리툴바