JSON은 JavaScript 객체 표기법(JavaScript Object Notation)의 약자입니다. API나 기타 외부 서비스를 다룰 때 대부분의 경우 데이터가 JSON 형식으로 반환되며, 이를 앱에서 실제로 사용할 수 있는 언어 형식으로 변환하는 과정이 필요합니다.
JSONSerialization 클래스란?
iOS의 Foundation 프레임워크는 JSON을 딕셔너리(Dictionary), 문자열(String), 불리언(Bool) 등 Swift에서 지원하는 형식으로 손쉽게 변환할 수 있도록 JSONSerialization 클래스를 제공합니다.
이 클래스의 핵심 메서드인 jsonObject(with:options:)는 JSON 데이터를 파싱하여 결과를 Any 타입으로 반환하며, 데이터를 파싱할 수 없는 경우에는 에러를 발생시킵니다.
// 예시 JSON:
/*
{
"age": 42.0,
"name": {
"firstName": "tut"
}
}
*/API 응답 데이터 파싱하기
실제 예제를 통해 살펴보겠습니다. API 호출을 통해 데이터를 받았다고 가정하고, 이 데이터를 JSONSerialization.jsonObject(with:options:) 메서드로 파싱해 보겠습니다.
if let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] { }// 위 코드에서 json 객체는 수신한 데이터를 [String: Any] 타입의 딕셔너리로 담고 있습니다. 만약 파싱에 실패하면 if let 블록을 벗어나 else 구문으로 이동합니다.
// json에 "Student"라는 키가 있고, 그 값이 딕셔너리라고 가정해 봅시다.
guard let student = json["Student"] as? [String: Any] else { return }이처럼 JSON을 파싱하고 원하는 값을 추출할 수 있습니다. 여기에 모델(Model)과 이니셜라이저(Initializer)를 활용하면 더욱 체계적으로 코드를 개선할 수 있습니다.
로컬 JSON 파일 파싱하기
이번에는 로컬 JSON 파일을 생성한 후 이를 직접 파싱하는 예제를 살펴보겠습니다. 아래와 같은 내용으로 JSON 파일을 만들고 exercises.json이라는 이름으로 저장합니다.
{
"Warmup": {
"Exercises": [
{
"Name": "Neck Strech",
"images": [
"http:sdf.com",
"sdf",
"sdf",
"sdf"
],
"time": 30
}
]
}
}이제 아래 코드를 사용해 로컬 JSON 파일을 파싱하고 결과를 출력해 보겠습니다.
if let filePath = Bundle.main.path(forResource: "exerciseData", ofType: "json") {
do {
let data = try Data(contentsOf: URL(fileURLWithPath: filePath), options: .mappedIfSafe)
let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves)
if let exercises = jsonResult as? [String:AnyObject] {
if let warmups = exercises["Warmup"] as? [String:AnyObject] {
print(warmups)
}
}
} catch {
print(error.localizedDescription)
}
}위 코드를 실행하면 번들(Bundle)에 포함된 JSON 파일을 읽어 "Warmup" 키에 해당하는 운동 데이터를 성공적으로 출력할 수 있습니다. 파일 경로를 찾지 못하거나 JSON 형식이 올바르지 않은 경우에는 catch 블록에서 에러 메시지가 출력됩니다.