Zatch 프로젝트에서 고객센터(FAQ) 부분이 있다.
FAQ 내용은 고정이고, 나중에 추가가 될 가능성이 있긴 하지만, 매번 변하는 데이터는 아니다 보니 서버 통신 없이 프론트에서 직접 데이터를 보여주기로 하였다.
프론트에서 데이터를 보여주기 위해 내가 생각한 방식은 아래와 같다.
JSON 형태로 관리해야겠다고 생각한 이유는,
직접 UI를 구현하는 ViewController나 View에 데이터를 넣어 놓기에는 글자 수가 너무 많으며,
데이터만 따로 관리 가능한 파일을 생성하는 것이 더 효율적이라 판단했기 때문이다.
JSON 파일에 데이터를 설정할 때 주의해야 할 점은 파일 내에 주석을 작성하면 안된다는 것이다!
처음 파일 생성할 때 주석으로 파일에 대한 정보가 기본으로 추가가 되는데,
이를 신경 쓰지 않고 파싱 작업을 했다가 계속 오류가 나서 꽤 많은 시간 동안 헤맸다.
{
"zatch": [
{
"title" : "재치 게시글 내용을 수정하고 싶어요.",
"content" : "하단의 두 번째 재치 탭에서 수정하고 싶은 재치 게시글을 선택해 주세요. [수정하기] 버튼을 클릭하여 등록하신 재치에 대한 내용 및 설명을 수정하실 수 있어요. 단, 음식에 대한 재치인 경우 유통기한, 구매일자 변경이 불가합니다."
}
],
"search": [
],
"town": [
],
"account": [
]
}
JSON으로 decode를 시켜줘야 하므로 Decodable 프로토콜(또는 Codable) 채택도 필수.
struct FAQ: Decodable{
struct Data: Decodable{
let title: String
let content: String
}
let zatch: [FAQ.Data]
let search: [FAQ.Data]
let town: [FAQ.Data]
let account: [FAQ.Data]
}
파일 경로를 가져오고, 파싱을 진행할 때 2가지 방식으로 구현을 해보았다.
1) 데이터 전체를 String 타입으로 변경한 이후 파싱하는 방식
private func getFAQ(){
guard let path = Bundle.main.path(forResource: "FAQ", ofType: "json"),
let jsonString = try? String(contentsOfFile: path),
let data = jsonString.data(using: .utf8),
let faqData = try? JSONDecoder().decode(FAQ.self, from: data) else { fatalError() }
faq = faqData
}
2) Data를 불러온 후 파싱하는 방식
private func getFAQ(){
guard let path = Bundle.main.url(forResource: "FAQ", withExtension: "json"),
let data = try? Data(contentsOf: path),
let faqData = try? JSONDecoder().decode(FAQ.self, from: data) else { fatalError() }
faq = faqData
}
첫 번째 방식은 path를 통해 String 타입의 파일 경로를 가져오고,
두 번째 방식은 url을 통해 URL 타입의 파일 경로를 가져온다는 차이점이 있다.
나는 두 방식이 큰 차이는 없지만, 두 번째 방식이 조금 더 로직이 단순하다고 생각해 두 번째 방식으로 프로젝트에 적용시켰다.
최종 결과물은 아래와 같다.
protocol 상속과 메서드의 매개변수를 사용하여 코드 재사용성 높이기 (0) | 2023.12.09 |
---|---|
Animation 활용해 TabBar 구현하기 (0) | 2023.04.27 |
Tag DesignSystem 리팩토링 과정 (0) | 2023.03.19 |
Protocol과 상속 관계를 활용해 HeaderView 구성하기 (0) | 2023.02.05 |
UITextField에 값 할당한 경우 이벤트 감지시키기 (0) | 2023.01.08 |