Я пытаюсь создать общий класс Plugin
, а затем подклассы, такие как PluginOne
и PluginTwo
, которые расширили бы класс, добавив свойство run()
и output
, чтобы каждый плагин мог выполнитьПользовательская команда и сохранить вывод.
Примерно так:
class Plugin: Decodable {
var name: String
init(name: String) {
self.name = name
}
}
class PluginOne: Plugin {
var output: String?
init(name: String, output: String) {
self.output = output
super.init(name: name)
}
func run() {
// do something
self.output = "Some output"
}
}
class PluginTwo: Plugin {
var output: String?
init(name: String, output: String) {
self.output = output
super.init(name: name)
}
func run() {
// do something
self.output = "Some other output"
}
}
Теперь я получаю список доступных плагинов из json:
let json = """
[
{ "type": "PluginOne", "name": "First plugin of type one" },
{ "type": "PluginOne", "name": "Second plugin of type one" },
{ "type": "PluginTwo", "name": "abcd" }
]
"""
ИЯ декодирую файл в [Plugin]
:
let decoder = JSONDecoder()
let jsonData = Data(json.utf8)
let plugins = try decoder.decode([Plugin].self, from: jsonData)
Теперь вопрос заключается в том, как правильно создать подклассы PluginOne
и PluginTwo
из каждого Plugin
, чтобы run()
каждый из них?
Также я понимаю, что я делаю что-то не так и, может быть, должен сразу декодировать в подкласс (как?) И / или использовать протоколы вместо подклассов.
Пожалуйста, сообщите
Результат выполнения первого ответа:
import Foundation
let json = """
[
{ "type": "PluginOne", "name": "First plugin of type one" },
{ "type": "PluginOne", "name": "Second plugin of type one" },
{ "type": "PluginTwo", "name": "abcd" }
]
"""
class Plugin: Decodable {
var name: String
init(name: String) {
self.name = name
}
}
class PluginOne: Plugin {
var output: String?
init(name: String, output: String) {
self.output = output
super.init(name: name)
}
required init(from decoder: Decoder) throws {
fatalError("init(from:) has not been implemented")
}
func run() {
// do something
self.output = "Some output"
}
}
class PluginTwo: Plugin {
var output: String?
init(name: String, output: String) {
self.output = output
super.init(name: name)
}
required init(from decoder: Decoder) throws {
fatalError("init(from:) has not been implemented")
}
func run() {
// do something
self.output = "Some other output"
}
}
let decoder = JSONDecoder()
let jsonData = Data(json.utf8)
let plugins = try decoder.decode([Plugin].self, from: jsonData)
for plugin in plugins {
if let pluginOne = plugin as? PluginOne {
pluginOne.run()
print(pluginOne.output ?? "empty one")
}
else if let pluginTwo = plugin as? PluginTwo {
pluginTwo.run()
print(pluginTwo.output ?? "empty two")
} else {
print("error")
}
}
// Result: error error error