Существует существующий протокол Swift, Codable
(или вы можете сделать просто Encodable
, если хотите, так как Codable
это просто Encodable
и Decodable
), который предназначен для представления объекта в JSON (или других форматах).
Затем вы используете JSONEncoder
(вместо JSONSerialization
,например) для кодирования объекта в JSON. См. Кодирование и декодирование пользовательских типов :
Рассмотрим структуру Landmark
, в которой хранится название и год основания ориентира:
struct Landmark {
var name: String
var foundingYear: Int
}
Добавление Codable
в список наследования для Landmark
запускает автоматическое соответствие, которое удовлетворяет всем требованиям протокола от Encodable
и Decodable
:
struct Landmark: Codable {
var name: String
var foundingYear: Int
}
Затем можно выполнить:
let landmark = Landmark(name: "Big Ben", foundingYear: 1859)
do {
let data = try JSONEncoder().encode(landmark)
print(String(data: data, encoding: .utf8)!)
} catch {
print(error)
}
Это будет продукт JSON следующим образом:
{
"name": "Big Ben",
"foundingYear": 1859
}
См. Кодирование и декодирование пользовательских типов для получения дополнительной информации.
Но, если вы сделаетеваши типы Codable
/ Encodable
, затем вы можете полностью удалить свой метод toJSON
. Больше нет необходимости писать код для кодирования JSON.
Если вы ищете более тактичное редактирование вашего проекта при преобразовании его из Objective-C в Swift, вы можете определить свой собственный протокол. скажем, JsonRepresentable
, у которого есть одно требование к методу, ваше toJSON
(или то, что вы переименовали в этот метод во время процесса конвертации).
protocol JsonRepresentable {
func toJSON() -> Data
}
И затем, для всех типов, которые реализовали этот метод, просто добавьте это соответствие.
В идеале вернитесь к этим отдельным файлам и переместите метод в расширение для этого протокола, например, для вашего первого типа объекта:
extension RequestObject1: JsonRepresentable {
func toJSON() -> Data {
...
}
}
И для вашего второго:
extension RequestObject2: JsonRepresentable {
func toJSON() -> Data {
...
}
}
И т.д.
нет более простого способа, чем его изменение во всем проекте
Я бы предположил, что вышеприведенное лучше, но,если вы не хотите возвращаться ко всем этим отдельным объявлениям типов, вы можете просто добавить соответствие с пустым расширением прямо там, где вы определили JsonRepresentable
:
extension RequestObject1: JsonRepresentable { }
extension RequestObject2: JsonRepresentable { }
Пока эти типы реализованыэтот метод, эти расширения сообщат компилятору об их соответствии вашему протоколу.
В любом случае, этот метод может затем использовать этот протокол:
func save(_ request: JsonRepresentable, requestId: Int) {
let requestData = ...
requestData.data = request.toJSON()
requestData.requestId = requestId
requestData.timestamp = Date()
save()
}