Отказ от ответственности: Есть довольно много похожих вопросов, но ни один из них, похоже, не дублирует мой собственный
Предположим, мое приложение получает JSON от довольно плохо спроектированного API, и что JSON, что выглядит примерно так:
{
"matches": {
"page1": [{
"name": "John",
"surname": "Doe",
"interests": [{
"id": 13,
"text": "basketball"
},
{
"id": 37,
"text": "competitive knitting"
},
{
"id": 127,
"text": "romcoms"
}
]
}],
"page2": [{
"name": "Dwayne",
"surname": "Johnson",
"interests": [{
"id": 42,
"text": "sci-fi"
},
{
"id": 255,
"text": "round numbers"
}
]
}]
}
}
Если я хочу получить, скажем, все интересы из всех матчей, в нативной функциональности Swift, мне сначала нужно сделать что-то вроде этого:
struct MatchesData: Codable {
let matches: Matches
}
struct Matches: Codable {
let page1: Page1
let page2: Page2
}
struct Page1: Codable {
let interests: [Interest]
}
struct Page2: Codable {
let interests: [Interest]
}
struct Interest: Codable {
let id: Int
let text: String
}
Затем я должен был бы использовать созданные мной структуры следующим образом:
func handleJSON(_ response: Data) {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode(MatchesData.self, from: response)
// Only here I can start actually working with the data API sent me, it's in decodedData
...
} catch {
// Handle the errors somehow
return
}
}
Хотя этот своего рода работает, у него есть два основных недостатка.
Во-первых, то, что все вместе, - это безумное количество подготовки и кода в целом для такой простой задачи, и оно не соответствует принципу DRY.
Наконец, такой подход просто не работает, если вы не знаете точную структуру JSON заранее. Например, в моем примере, что, если количество страниц не было установлено равным 2, а могло бы быть где-то между, скажем, 1 и 50?
В других языках, которые имеют в своем составе встроенные инструменты для работая с JSON, я бы просто проанализировал JSON и рекурсивно перебрал совпадения, чтобы сделать то, что мне нужно, с содержимым.
Примеры (без мер безопасности для улучшения читабельности) :
JS:
const handleJSON = jsonStr => {
const jsonObj = JSON.parse(jsonStr)
const matches = jsonObj.matches
Object.values(matches).forEach(page => {
// Recursively process every page to find what I need and process it
})
}
Python 3:
import json
def handleJSON(jsonStr):
jsonObj = json.loads(jsonStr)
matches = jsonObj['matches']
for page in matches:
# Recursively process every page to find what I need and process it
PHP:
function handleJSON($jsonStr) {
$jsonObj = json_decode($jsonStr);
$matches = $jsonObj->matches;
foreach ($matches as $page) {
// Recursively process every page to find what I need and process it
}
}
Итак, вопрос в том, как мне добиться того же в Swift в разумной манере, как в примерах выше (что определенно означает примерно одинаковое количество кода)? Если вы знаете стороннюю библиотеку, которая делает именно это, я бы с радостью принял такую библиотеку за ответ.
ОБНОВЛЕНИЕ: Только что узнал о Jsonify , что, по-видимому, является таким же хорошим решением моих проблем, как Swifty JSON, может быть, даже лучше. Вероятно, стоит попробовать какое-то время, чтобы решить, какой из них подходит им по вкусу и нуждается лучше