У меня есть структура, которая имеет некоторые свойства, перечисление 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
Любой совет, чтобы сделать это?
Спасибо