Реализовать отображение CodingKey в суперклассе - PullRequest
1 голос
/ 23 апреля 2019

У меня есть структура, которая имеет некоторые свойства, перечисление CodingKey (для соответствия протоколу Codable) и некоторые computed-vars, которые возвращают массив ключей, сопоставленных со строкой.

То, что я пытаюсь сделать, - это извлечь эти вычисленные переменные в протокол (суперкласс, если мне нужно изменить структуру на класс), чтобы избежать повторения реализации в каждой структуре / классе. И мне нужно много из них.

Проблема в том, что я не могу найти способ узнать перечисление CodingKey.

Edit: DBentity

/// Basic protocol for any object directly related with a database table.
public protocol DBEntity: Codable, Equatable {}

код:

///////////////////////////////////////////////////////////////////////

// MARK: - Entity Properties

struct AccountsAddresses: DBEntity {

    let statusMobile: String?
    let codeAccount: Int?
    let codeUnitOrg: String?
    let codeSalesOrg: String?
    let codeAddress: Int?
    let codeType: String?
    let byDefault: String?
    let transfered: String?
}

///////////////////////////////////////////////////////////////////////

// MARK: - Table Columns

extension AccountsAddresses {

    /// Table name.
    static var tableName = "ACCOUNTS_ADDRESSES"

    /// Table columns keys.
    enum CodingKeys: String, CodingKey, CaseIterable {
        case statusMobile   = "status_mobile"
        case codeAccount    = "code_account"
        case codeUnitOrg    = "code_unit_org"
        case codeSalesOrg   = "code_sales_org"
        case codeAddress    = "code_address"
        case codeType       = "code_type"
        case byDefault      = "by_default"
        case transfered
    }

/* This is what I'm trying to extract to a protocol(extension) or super-class. */

    /// All table columns keys.
    static var columns: [String] = CodingKeys.allCases.map { $0.rawValue }
    static var columnsJoined: String = columns.joined(separator: String.commaSpace)
    static var columnsTableName: [String] = columns.map { tableName + String.dot + $0 }
    static var columnsJoinedTableName: String = columnsTableName.joined(separator: String.commaSpace)
}

EDIT

Используя данный код из ответа Sweeper, я пытаюсь реализовать протокол в новой структуре, но компилятор просит установить тип для typealias CodingKeyType (поскольку определенный протокол имеет ассоциированный тип).

public protocol Table {
    associatedtype ColumnKeysType: (CodingKey & CaseIterable & RawRepresentable)
    static var tablename: String { get }
}

Вот структура для тестирования:

struct AccountsTest: Table {

    typealias CodingKeyType = <#type#>
}

Я пытался создать другую структуру, чтобы иметь тип для присваивания typealias, но есть кое-что, что я пропускаю / делаю неправильно (мне пришлось реализовать это vars, constructors & typealias).

struct Keys: (CodingKey & CaseIterable & RawRepresentable) {

    var stringValue: String
    var rawValue: String
    var intValue: Int?

    init?(stringValue: String) {}
    init?(rawValue: String) {}
    init?(intValue: Int) {}

    typealias AllCases = Keys.RawValue
    typealias RawValue = String
}

Компилятор продолжает показывать ошибки, и я не могу найти способ сделать это.

'CaseIterable' requires the types 'Keys' and 'String.Element' (aka 'Character') be equivalent

Любой совет, чтобы сделать это?

Спасибо

Ответы [ 2 ]

0 голосов
/ 23 апреля 2019

Вам не нужно делать преобразование самостоятельно. Вы можете использовать decoder.keyDecodingStrategy = .convertFromSnakeCase, и ваш json будет привязан к свойствам вашего верблюжьего корпуса.

Для получения дополнительной информации:

https://developer.apple.com/documentation/foundation/jsondecoder/keydecodingstrategy/convertfromsnakecase

0 голосов
/ 23 апреля 2019

Обратите внимание, что свойства, которые вы пытаетесь извлечь, не являются вычисляемыми свойствами.

Кажется, что свойства, которые вы хотите извлечь, зависят только от tableName и CodingKeys, поэтому мы можем написать такой протокол:

protocol SomeProtocol {
    associatedtype CodingKeyType : (CodingKey & CaseIterable & RawRepresentable)
    static var tableName: String { get }
}

, а затем расширение, подобное этому (я преобразовал свойства в вычисляемые свойства):

extension SomeProtocol where CodingKeyType.RawValue == String {
    static var columns: [String] { return CodingKeyType.allCases.map { $0.rawValue } }
    static var columnsJoined: String { return columns.joined(separator: " ") }
    static var columnsTableName: [String] { return columns.map { tableName + "." + $0 } }
    static var columnsJoinedTableName: String { return columnsTableName.joined(separator: " ") }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...