Я правильно загружаю информацию своего профиля в приложение iOS Swift, но у JSON есть связанный с ним объект, который сбивает меня с толку, как правильно анализировать его, чтобы получить доступ к данным внутри него. Вот мой метод.
func attemptToLoadProfile(hash: String) {
let url = "https://www.gravatar.com/\(hash).json"
let fileURL = URL(string: url)
do {
let contents = try String(contentsOf: fileURL!)
let data = contents.data(using: String.Encoding.utf8)
let json = try? JSONSerialization.jsonObject(with: data!, options: [])
print(json!)
} catch {
print("error parsing json")
}
}
Это отлично работает, но когда я распечатываю его, JSON форматируется следующим образом.
{
entry = (
{
displayName = edolecki;
hash = <myhash here>;
id = 1333520;
name = {
familyName = Dolecki;
formatted = "Eric Dolecki";
givenName = Eric;
};
photos = (
{
type = thumbnail;
value = "https://secure.gravatar.com/avatar/<myhash here>";
}
);
preferredUsername = edolecki;
profileUrl = "http://gravatar.com/edolecki";
requestHash = <myhash here>;
thumbnailUrl = "https://secure.gravatar.com/avatar/<myhash here>";
urls = (
);
}
);
}
Как мне разобрать JSON, увидев, что этот объект записи находится в корне? Мне нужно displayName, id и т. д. Обычно я анализирую JSON без более упрощенного корня. Я не видел этого раньше.
Вы не печатаете JSON там, вы печатаете NSDictionary результат JSONSerialization.jsonObject. Итак, он уже проанализирован, если вы хотите отобразить его, вы должны создать собственный тип и использовать Codable: swiftbysundell.com/basics/codable

Значение, связанное с ключом entry, — это просто массив с одним элементом. В этом случае вы можете получить доступ к json["entry"], преобразовать его в [[String: Any]] и получить доступ к первому элементу [0]. Затем вы можете получить доступ к тому, что хотите, например displayName и id.
Лучший способ сделать это — использовать Codable. Используя Быстрый тип, я сгенерировал этот код:
struct Root: Codable {
let entry: [Entry]
}
struct Entry: Codable {
let id, hash, requestHash: String
let profileURL: URL
let preferredUsername: String
let thumbnailURL: URL
let photos: [Photo]
let displayName: String
enum CodingKeys: String, CodingKey {
case id, hash, requestHash
case profileURL = "profileUrl"
case preferredUsername
case thumbnailURL = "thumbnailUrl"
case photos, displayName
}
}
struct Photo: Codable {
let value: URL
let type: String
}
Затем вы можете сделать это, чтобы проанализировать json:
let decoder = JSONDecoder()
let root = try decoder.decode(Root.self, from: data)
// e.g.
let displayName = root.entry[0].displayName
Если вам не нужны какие-либо json KVP, просто удалите их из структуры.
Все поля *URL могут быть преобразованы непосредственно в тип URL
Я получаю сообщение об ошибке: Тип «Запись» не соответствует протоколу «Декодируемый».
@RadagasttheBrown Я забыл удалить ключ urls из CodingKeys. Смотрите редактирование.
json— это словарь. Вы не знаете, как получить доступ к значениям из словаря? Уточните пожалуйста, что вас смущает.