CoreData

CoreData ) NSSecureCoding (정말정말정말 간단하게 알아봄)

JoonSwift 2022. 5. 4. 14:36

CoreData의 Transformable 타입을 알아보다가 NSSecureCoding이라는 녀석을 만나고 한번 살펴보다가 엄청난 Objective-C 개념들을 만나고 우선은 공식문서의 내용에 대해서만 정리하도록 마음먹었습니다. 😅 😅 😅 

 

NSSecureCoding?

A protocol that enables encoding and decoding in a manner that is robust against object substitution attacks.
- Apple Developer Document -

Object Substitution 공격에 맞서기 위한 강력한 Encoding, Decoding 방식을 가능하게하는 프로토콜입니다. 

 

음.... 직접 코드로 작성하며 이 NSSecureCoding이라는 프로토콜을 채택해보았습니다. 

 

class MyClass: NSSecureCoding {
  static var supportsSecureCoding: Bool
  
  var someClass: SomeClass
  
  // ... 

  func encode(with coder: NSCoder) {
  	// coder.encode(someClass, forKey: "someClass")
  }

  required init?(coder: NSCoder) {
    // Decode here...
  }
}

 

NSSecureCoding 프로토콜을 채택하자 supportsSecureCoding, encode(with coder: ), required init?(coder: ) 이렇게 3가지를 필수적으로 구현해야하는 것들로 주어집니다. (encode(with coder: )와 required init?(coder: )는 NSCoding의 메서드입니다.)

  • supportsSecureCoding : 이 static 프로퍼티는 이름에서도 알 수 있듯, 이 클래스가 SecureCoding을 지원하느냐 에 대한 Boolean 값을 나타내는 프로퍼티입니다. 공식문서의 Discussion을 보면 Seucre Coding을 지원하는 Class를 작성할 때, 이 클래스 프로퍼티의 getter 반환 값이 true임을 보장해야한다고 합니다. 
  • encode(with coder: ) : 파라미터로 받아온 coder를 활용하여 인스턴스 변수들을 Encoding 과정을 작성해야하는 메서드입니다. 
  • required init?(coder : ) : 인코딩한 object들(enclosed objects)을 decodeObjectOfClass: forKey: 메서드를 사용하여 반드시 디코딩 해주어야 합니다. 

그래서 이 NSSecureCoding을 활용하면 아래와 같이 Object를 디코드 할 수 있습니다. 

class MyClass: NSObject, NSSecureCoding { 
 // ...
}

class SomeOtherClass {
  var myClass: MyClass?
  
  init(coder: NSCoder) {
    let object = coder.decodeObject(of: MyClass.self, forKey: "myClass")
  }
}

대충 이런 형태로 구현될 수 있는듯합니다. 

NSSecureCoding이 아닌 NSCoding만 활용할 경우에는 

if let obj = coder.decodeObject(forKey: "myClass") as? MyClass {
      
}

이런식으로 as? MyClass를 활용하여 MyClass라는 타입을 타입캐스팅을 통해 가져옵니다. 이런 디코딩의 경우, 공식문서의 설명을 빌리자면, 클래스의 타입을 확인할 때, 이미 object가 생성된 상태이며, 만약 이것이 컬렉션 클래스의 일부라면, 잠재적으로 object graph에 삽입될 수도 있기에 안전하지 않은 방법이라고 합니다. 

결국 Object가 생성되기 전에 클래스의 타입을 확정짓기 못하기 때문에 안전하지 않다는 결론으로 생각됩니다. 

반면에 위의 NSSecureCoding을 채택한다면, Object가 생성되기 전에, 클래스의 타입을 확정지을 수 있기 때문에 더 안전합니다. 

이상으로 NSSecureCoding의 정의가 무엇인지, 왜 안전한지, 채택하면 필수적으로 구현해주어야 하는 메서드나 프로퍼티에 대해서 아~~~주 간단하게 알아보았습니다.

정리

내용이 조금 어려운것 같아 문서를 읽는 듯이 포스팅을 한것 같습니다. CoreData를 계속 공부하면서 더 알게되는 부분, Transformable 타입을 사용하면 NSSecureCoding에 대해서 새롭게 알게되는 부분이 나온다면 다시 정리하여 포스팅을 수정하는 시간을 가져야겠습니다 ㅎㅎ

 

참고 자료

https://developer.apple.com/documentation/foundation/nssecurecoding

 

Apple Developer Documentation

 

developer.apple.com

아래에 Conforming Types를 보면 정말 많은 타입들이 이 프로토콜을 준수하고있다는걸 확인할 수 있습니다 ㄷ ㄷ!!