protocol PredicateCodableKeyPathProviding {
    // identifier 문자열 키 및 PartialKeyPath 값 쌍을 딕셔너리에 매핑한 프로퍼티. 
    // identifier 문자열은 allowKeyPath(_:identifier:) API에 제공하던 identifier와 동일하다.
    static var predicateCodableKeyPaths: [String : PartialKeyPath<Self>] { get }
}

<aside> 💡 아카이브될 predicate에서 사용할 것으로 기대하는 keypath의 목록을 제공하는 타입.

PredicateCodableConfiguration 타입의 allowKeyPathsForPropertiesProvided(by:) 또는 disallowKeyPathsForPropertiesProvided(by:) 메소드에서만 사용된다.

</aside>

해당 프로토콜을 준수하는 타입은 내부 프로퍼티 중 predicate에서 아카이빙하는 것이 allow되는 항목들을 딕셔너리로 명시한다. 이는 해당 타입의 keypath 목록이 항상 allow된다는 것을 의미하지는 않는다. 보다 정확한 의미는, PredicateCodableConfiguration 타입의 allowKeyPathsForPropertiesProvided(by:) 또는 disallowKeyPathsForPropertiesProvided(by:) 메소드에 해당 타입을 전달하는 것으로 keypath 목록이 allow/disallow될 수 있음을 의미하는 것이다.

extension Message: **PredicateCodableKeyPathProviding** {
    static var predicateCodableKeyPaths = [
        "MyApp.Message.sender" : \\.sender,
        "MyApp.Message.length" : \\.length,
        "MyApp.Message.content" : \\.content
    ]
}

var configuration = PredicateCodableConfiguration.standardConfiguration
...
// recursive 인자를 활성화하면 해당 타입(Message)의 하위 프로퍼티 타입에서 제공하는 keypath 또한 포함한다.
// 재귀적으로 적용되므로 하위 프로퍼티의 하위 프로퍼티, 그 프로퍼티의 하위 프로퍼티... 전체 계층에 걸쳐 연쇄적으로 포함한다.
**configuration.allowKeyPathsForPropertiesProvided(by: Message.self, recursive: true)**

struct MyRequest: Codable {
    let predicate: Predicate<Message>
    
    func encode(to encoder: Encoder) throws { ... }
    init(from decoder: Decoder) throws { ... }
}

PredicateCodableConfiguration 타입의 전체적인 사용법은 PredicateCodableConfiguration 페이지를 참조하자.

참고자료