2017-11-29 2 views
2

기본 클래스는 Action이며 Operation입니다. 그것은 그것 (KVO와 그 모든 것)의 crufty Operation 재료의 묶음을 가지고있다. 기본 클래스 자체는 실제로 아무 것도 인코딩/디코딩 할 필요가 없습니다.클래스 상속과 함께 형식을 모르는 경우 어떻게 디코딩 할 수 있습니까?

class Action : Operation, Codable { 
    var _executing = false 
    ... 
} 

내가 직접 Input 구조체로 인스턴스화 DropboxUploadAction 같은 Action 서브 클래스의 무리를 가지고 그들은 정의

class DropboxUploadAction : Action { 
    struct Input : Codable { 
     var guid: String 
     var eventName: String 
     var fileURL: URL? 
     var filenameOnDropbox: String 
     var share: Bool 
    } 

    struct Output : Codable { 
     var sharedFileLink: String? 
     var dropboxPath: String? 
    } 

    var input: Input 
    var output: Output 

    ... 

    required init(from decoder: Decoder) throws { 
     let values = try decoder.container(keyedBy: CodingKeys.self) 
     input = try values.decode(Input.self, forKey: .input) 
     output = try values.decode(Output.self, forKey: .output) 
     let superDecoder = try values.superDecoder() 
     try super.init(from: superDecoder) 
    } 

    fileprivate enum CodingKeys: String, CodingKey { 
     case input 
     case output 
    } 

    override func encode(to encoder: Encoder) throws { 
     var container = encoder.container(keyedBy: CodingKeys.self) 
     try container.encode(input, forKey: .input) 
     try container.encode(output, forKey: .output) 
     try super.encode(to: container.superEncoder()) 
    } 
} 
:

여기
let actionInput = DropboxUploadAction.Input.init(...) 
ActionManager.shared.run(DropboxUploadAction.init(actionInput, data: binaryData), completionBlock: nil) 

는 서브 클래스가 어떻게 생겼는지입니다

인터넷 연결이 끊기는 등의 상황이 발생할 경우 나중에 이러한 클래스를 디스크에 직렬화해야합니다. 그건 괜찮아요. 왜냐하면 내가 그들에 대한 참조를 가지고 있고 JSONEncoder().encode(action)으로 인코딩 할 수 있기 때문이죠.

나중에 이들을 deserialize하려는 경우 클래스의 유형을 지정해야하며 그 클래스가 무엇인지 알 필요가 없습니다. 일부 데이터가 있고 그것을 Action, 상속하는 클래스로 디코딩 할 수 있지만 그것은 어떤 하위 클래스인지 알 수 없습니다. 나는 파일 이름에 그것을 인코딩하는 것이 싫다. 거기에 기본 클래스 Action로 디코드하는 방법이 있나요 decode() 방법의 Action, 어떻게 든 적절한 클래스를 감지하고 리디렉션?

과거에는 이것을 처리하기 위해 NSKeyedUnarchiver.setClass()을 사용했습니다. 도움이된다면하지만 ...

을 나는 스위프트 4의 Codable으로 그렇게하는 방법을 모른다, 나는 NSCoding 지금은 내가 더 이상 NSKeyedUnarchiver를 사용해서는 안되지 않습니다 이해 : 나는 struct Types : OptionSet, Codable하는 각 서브 클래스 반환을 , 그래서 나는 그 클래스의 이름을 그 정체성으로 사용할 필요가 없다.

도움 주셔서 감사합니다.

+0

작동 방식은 다음과 같습니다. 그러나보기 흉한 점 때문에 마음에 들지 않습니다. https://gist.github.com/xaphod/3fda8e584dd840e3a3564da8a5b25846 – xaphod

답변

1

Uhhh NSCoding은 (는) 더 이상 사용되지 않습니다. 스토리 보드에서 UIViewController를 init(coder:)을 통해 인스턴스화 할 때 여전히 사용합니다.

는 여전히 NSCoding을 사용하지 않으려는 경우 또한, 당신은 단지 Input, OutputTypes 구조체에 저장하고 디스크 대신에 그 직렬화. 필요하면

struct SerializedAction { 
    let input: Input 
    let output: Output 
    let type: Type 
} 

, 당신은을 디코딩하고 type 속성을 통해 사용자의 입력/출력을 초기화 할 수있는 올바른 Action를 결정할 수 있습니다.

class DropboxAction: Action { 
    ... 
    init(input: Input, output: Output) { 
    ... 
    } 
} 

당신은 반드시 전체 Action 객체를 인코딩 할 필요가 없습니다.

+0

고마워요. 그 동안 나는 이미 동일한 결론에 도달 했으므로 (입력 만 인코딩 됨) 답변으로 받아 들일 것입니다. – xaphod

관련 문제