Итак, у меня есть базовый класс DataViewController<T>
, который наследуется от UITableViewController
следующим образом:
class DataTableViewController<T : BMPage<BMData>> : UITableViewController, UISearchBarDelegate {
// implementations...
}
У меня также есть TournamentsViewController
, который наследуется от DataViewController
с переданными обобщениями:
class TournamentsViewController: DataTableViewController<TournamentPage> {
// overrides, etc.
}
Для справки: BMPage<T>
:
open class BMPage<T : Codable> : Decodable {
public enum CodingKeys: String, CodingKey {
case data
}
var data : [T]
required public init(from decoder:Decoder) throws {
let vals = try decoder.container(keyedBy: CodingKeys.self)
data = try vals.decode([T].self, forKey: .data)
}
}
extension BMPage: Encodable {
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(data, forKey: .data)
}
}
... и BMData
:
open class BMData : Codable {
public enum CodingKeys: CodingKey {
case id
case name
}
var id: Int
var name: String
required public init(from decoder:Decoder) throws {
let vals = try decoder.container(keyedBy: CodingKeys.self)
id = try vals.decode(Int.self, forKey: .id)
name = try vals.decode(String.self, forKey: .name)
}
}
То, чего я пытаюсь достичь: различные UITableViewController
подклассы, которым просто нужно указать универсальные шаблоны, чтобы указать их конкретные данные. Вот мои реализации Tournament и TournamentPage, которые должны лучше объяснить эту концепцию:
open class Tournament : BMData {
let game_id: Int = 0
let game_iteration_id: Int = 0
let state: Int = 0
let starts_at: String = ""
let creator_id: Int = 0
let stream_url: String? = nil
let entrant_count: Int = 0
let prereg_count: Int = 0
let path: String = ""
}
open class TournamentPage : BMPage<BMData> {
public enum CodingKeys: String, CodingKey {
case data = "tournaments"
}
let page: String? = nil
let results_per_page: String = ""
let tournament_count: Int = 0
}
Проблема: компилятору не нравится, что я делаю это, поскольку он выдает несколько, но очень похожие ошибки, такие как:
Cannot convert return expression of type 'TournamentsViewController'
to return type 'UIViewController'
Cannot convert return expression of type
'TournamentsViewController?' to return type 'UIViewController?'
Вот пример такого выражения (взято из значения по умолчанию ModelController
, которое XCode добавил туда, где все эти ошибки происходят:
let dataViewController = storyboard.instantiateViewController(withIdentifier: "DataViewController") as! TournamentsViewController
Есть ли способ достичь того, что я пытаюсь сделать? Признаюсь, я новичок в Swift (только начал изучать его на этой неделе), так что, возможно, я совершенно не понимаю типичные практики Swift и просто то, для чего он предназначен, но достигаю этого на языке, таком как C # (и, возможно, даже Objective-C, хотя я немного заржавел, так как я давно его использовал), это почти то, что я делаю здесь.