#ios #swift #xcode #swift-playground
Вопрос:
Я пытаюсь расшифровать приведенный ниже JSON на игровой площадке и сталкиваюсь с ошибкой EXC_BAD_ACCESS. В идеале я хотел бы декодировать все свойства в структуре Person, но я могу декодировать их только после того, как они будут раскомментированы прямо сейчас. Как только я раскомментирую любой из комментариев один раз, он выдает ошибку, выполнение было прервано, причина: EXC_BAD_ACCESS (код=1, адрес=0x5e48).. Что я здесь делаю не так? Я долго искал в Google, но не смог найти никакого ответа.
Заранее спасибо за вашу помощь!
struct Address: Decodable {
var line1: String
var city: String
var region: String
var postalCode: String
var countryCode: String
}
struct CityCoordinate : Decodable {
var latitude: Double
var longitude: Double
}
struct Thumbnail: Decodable {
var url: String
var width: Int
var height: Int
}
struct Headshot: Decodable {
var url: String
var width: Int
var height: Int
var sourceUrl: String
var thumbnails: [Thumbnail]?
}
struct Meta : Decodable {
var id: String
}
struct Person : Decodable {
//var newPatients: Bool?
var address: Address
var description: String?
var name: String
var cityCoordinate: CityCoordinate
//var baseURL: String?
// var c_baseURL: String?
// var headhshot: Headshot?
// var insuranceAccepted: [String]?
//var expertises: [String]?
// var meta: Meta
enum CodingKeys : String, CodingKey {
//case newPatients = "acceptingNewPatients"
case address
case description
case name
case cityCoordinate
// case headhshot
// case insuranceAccepted
//case baseURL = "c_baseURL"
//case expertises = "c_expertises"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
//self.newPatients = try container.decodeIfPresent(Bool.self, forKey: .newPatients) ?? false
self.address = try container.decode(Address.self, forKey: .address)
self.description = try container.decode(String.self, forKey: .description)
self.name = try container.decode(String.self, forKey: .name)
self.cityCoordinate = try container.decode(CityCoordinate.self, forKey: .cityCoordinate)
// self.insuranceAccepted = try? container.decodeIfPresent([String].self, forKey: .insuranceAccepted) ?? []
//self.baseURL = try? container.decodeIfPresent(String.self, forKey: .baseURL) ?? ""
// self.headhshot = try? container.decodeIfPresent(Headshot.self, forKey: .headhshot)
// self.expertises = try? container.decodeIfPresent([String].self, forKey: .expertises) ?? []
}
}
let json2 = """
{
"acceptingNewPatients": true,
"address": {
"line1": "111 7th Ave",
"city": "New York",
"region": "NY",
"postalCode": "10005",
"countryCode": "US"
},
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"name": "John Doe",
"cityCoordinate": {
"latitude": 41.78200149536133,
"longitude": -72.83170318603516
},
"c_baseURL": "https://some-url.dummy.com/my-profile/current",
"headshot": {
"url": "https://some-url.dummy.com/my-profile/current/p/ooREDemnhmfahTVexnEyXRC4GTfeKdCDWgUr-GRL11Y/199x199.png",
"width": 199,
"height": 199,
"sourceUrl": "https://some-url.dummy.com/my-profile/current/p/ooREDemnhmfahTVexnEyXRC4GTfeKdCDWgUr-GRL11Y/199x199.png",
"thumbnails": [{
"url": "https://some-url.dummy.com/my-profile/current/p/ooREDemnhmfahTVexnEyXRC4GTfeKdCDWgUr-GRL11Y/196x196.png",
"width": 196,
"height": 196
}]
},
"insuranceAccepted": ["Finibus", "anything", "hidden", "consectetur" ],
"meta": {
"accountId": "967081498762345229",
"uid": "Nd28v0",
"id": "5119-13270",
"timestamp": "2021-03-24T12:10:36",
"labels": ["61280", "61288", "84273", "117907", "122937", "126160"],
"folderId": "351068",
"schemaTypes": ["therefore", "popular", "commodo", "voluptatem"],
"language": "en",
"countryCode": "US",
"entityType": "informationProfessional"
}
}
""".data(using: .utf8)!
let person = try JSONDecoder().decode(Person.self, from:json2)
print(person)
Комментарии:
1. Оберните
try
линию вdo - catch
блок иerror
2. Не воспроизводимо для меня, когда все раскомментировано (и недостающие строки для
meta
)
Ответ №1:
Я думаю, что есть две-три проблемы, которые приводят к сбою, я думаю, что номер один отсутствует мета, номер два отсутствует c_expertise
, и, наконец, когда Headshot?
это необязательно в init
том, что вам нужно использовать try
вместо try?
того, чтобы декодировать необязательный ключ, после этих изменений:
struct Address: Decodable {
var line1: String
var city: String
var region: String
var postalCode: String
var countryCode: String
}
struct CityCoordinate : Decodable {
var latitude: Double
var longitude: Double
}
struct Thumbnail: Decodable {
var url: String
var width: Int
var height: Int
}
struct Headshot: Decodable {
var url: String
var width: Int
var height: Int
var sourceUrl: String
var thumbnails: [Thumbnail]?
}
struct Meta : Decodable {
var id: String
}
struct Person : Decodable {
var newPatients: Bool?
var address: Address
var description: String?
var name: String
var cityCoordinate: CityCoordinate
var baseURL: String?
var c_baseURL: String?
var headhshot: Headshot?
var insuranceAccepted: [String]?
var expertises: [String]?
var meta: Meta?
enum CodingKeys : String, CodingKey {
case newPatients = "acceptingNewPatients"
case address
case description
case name
case cityCoordinate
case headhshot
case insuranceAccepted
case baseURL = "c_baseURL"
// case expertises = "c_expertises"
case meta
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.newPatients = try container.decodeIfPresent(Bool.self, forKey: .newPatients) ?? false
self.address = try container.decode(Address.self, forKey: .address)
self.description = try container.decode(String.self, forKey: .description)
self.name = try container.decode(String.self, forKey: .name)
self.cityCoordinate = try container.decode(CityCoordinate.self, forKey: .cityCoordinate)
self.insuranceAccepted = try? container.decodeIfPresent([String].self, forKey: .insuranceAccepted) ?? []
self.baseURL = try? container.decodeIfPresent(String.self, forKey: .baseURL) ?? ""
self.headhshot = try container.decodeIfPresent(Headshot.self, forKey: .headhshot)
//self.expertises = try? container.decodeIfPresent([String].self, forKey: .expertises) ?? []
self.meta = try container.decodeIfPresent(Meta.self, forKey: .meta)
}
}
let json2 = """
{
"acceptingNewPatients": true,
"address": {
"line1": "111 7th Ave",
"city": "New York",
"region": "NY",
"postalCode": "10005",
"countryCode": "US"
},
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"name": "John Doe",
"cityCoordinate": {
"latitude": 41.78200149536133,
"longitude": -72.83170318603516
},
"c_baseURL": "https://some-url.dummy.com/my-profile/current",
"headshot": {
"url": "https://some-url.dummy.com/my-profile/current/p/ooREDemnhmfahTVexnEyXRC4GTfeKdCDWgUr-GRL11Y/199x199.png",
"width": 199,
"height": 199,
"sourceUrl": "https://some-url.dummy.com/my-profile/current/p/ooREDemnhmfahTVexnEyXRC4GTfeKdCDWgUr-GRL11Y/199x199.png",
"thumbnails": [{
"url": "https://some-url.dummy.com/my-profile/current/p/ooREDemnhmfahTVexnEyXRC4GTfeKdCDWgUr-GRL11Y/196x196.png",
"width": 196,
"height": 196
}]
},
"insuranceAccepted": ["Finibus", "anything", "hidden", "consectetur" ],
"meta": {
"accountId": "967081498762345229",
"uid": "Nd28v0",
"id": "5119-13270",
"timestamp": "2021-03-24T12:10:36",
"labels": ["61280", "61288", "84273", "117907", "122937", "126160"],
"folderId": "351068",
"schemaTypes": ["therefore", "popular", "commodo", "voluptatem"],
"language": "en",
"countryCode": "US",
"entityType": "informationProfessional"
}
}
""".data(using: .utf8)!
do {
let person = try JSONDecoder().decode(Person.self, from:json2)
print(person)
} catch let error {
print(error)
}
Он печатается Person
, пожалуйста, попробуйте, и если возникнет какая-либо ошибка, попробуйте в проекте вместо Playground
онлайн-компилятора или онлайн-компилятора.
Комментарии:
1. Спасибо за ответ! Я запустил ваш код на игровой площадке, и, получив это сообщение, valueNotFound(__lldb_expr_39.Человек, Свифт. Ошибка декодирования. Контекст(Путь к кодированию: [], Описание отладки: «Данные не содержали значения верхнего уровня.», ошибка в основе: ноль)).
2. Хорошо, я попробовал то же самое здесь : tutorialspoint.com/compile_swift_online.php и для меня это прекрасно работает. Я как-нибудь загляну на игровую площадку.
3. в реальном проекте это работает. Конечно, это работает в tutorialpoints.com и еще. Я собираюсь принять ваш ответ. Спасибо!