스닥
Playground
스닥
전체 방문자
오늘
어제
  • 분류 전체보기 (125)
    • 개발자 기본기 (1)
    • Swift 아키텍처 (6)
    • iOS 개발 (55)
      • Swift (12)
      • UIKit (17)
      • SwiftUI (9)
      • CoreData (9)
      • MusicKit (4)
      • WebKit (2)
      • 개발 환경 (0)
      • WatchOS (2)
    • 애플 개발자 아카데미 (4)
    • 막 쓰는 개발일지 (0)
    • 운영체제 (4)
    • 네트워크, 서버 (16)
      • Network (9)
      • Server (7)
    • 알고리즘 (8)
    • C언어 (7)
      • 함수 (7)
    • 하루 이야기 (23)

블로그 메뉴

  • GitHub계정
  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • ip주소
  • dfs
  • 서버
  • 문자열 복사
  • 트리
  • C 언어
  • 알고리즘
  • Server
  • 도커
  • docker
  • 자료구조
  • ios rendering
  • 너비 우선
  • SWIFT
  • 깊이 우선
  • BFS
  • Core Animation
  • core data
  • swift performance
  • struct class 성능

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
스닥

Playground

[SwiftUI] json parsing 방법
iOS 개발/SwiftUI

[SwiftUI] json parsing 방법

2022. 3. 10. 14:45

 

swift UI에서 json parsing은 정말 간단하고, 똑똑? 위험? 한 것 같다는 생각을 했습니다.

 

 

어떤 json 파일을 struct array에 parsing하려고 한다고 했을 때,

json 파일의 구성은 다음과 같습니다.

 

먼저 파일 이름은 landMarkData.json 입니다.

{
        "name": "Turtle Rock",
        "category": "Rivers",
        "city": "Twentynine Palms",
        "state": "California",
        "id": 1001,
        "isFeatured": true,
        "isFavorite": true,
        "park": "Joshua Tree National Park",
        "coordinates": {
            "longitude": -116.166868,
            "latitude": 34.011286
        },
        "description": "Suscipit inceptos est felis purus aenean aliquet adipiscing diam venenatis, augue nibh duis neque aliquam tellus condimentum sagittis vivamus, cras ante etiam sit conubia elit tempus accumsan libero, mattis per erat habitasse cubilia ligula penatibus curae. Sagittis lorem augue arcu blandit libero molestie non ullamcorper, finibus imperdiet iaculis ad quam per luctus neque, ligula curae mauris parturient diam auctor eleifend laoreet ridiculus, hendrerit adipiscing sociosqu pretium nec velit aliquam. Inceptos egestas maecenas imperdiet eget id donec nisl curae congue, massa tortor vivamus ridiculus integer porta ultrices venenatis aliquet, curabitur et posuere blandit magnis dictum auctor lacinia, eleifend dolor in ornare vulputate ipsum morbi felis. Faucibus cursus malesuada orci ultrices diam nisl taciti torquent, tempor eros suspendisse euismod condimentum dis velit mi tristique, a quis etiam dignissim dictum porttitor lobortis ad fermentum, sapien consectetur dui dolor purus elit pharetra. Interdum mattis sapien ac orci vestibulum vulputate laoreet proin hac, maecenas mollis ridiculus morbi praesent cubilia vitae ligula vel, sem semper volutpat curae mauris justo nisl luctus, non eros primis ultrices nascetur erat varius integer.",
        "imageName": "turtlerock"
}

 

이렇게 name, category 등등의 properties를 가지는데

 

이 json 파일을 parsing하기 위해는, 해당 요소들에 대응되는 struct을 만들어주어야 합니다.

 

import Foundation
import SwiftUI
import CoreLocation

struct Landmark: Hashable, Codable {
    var id: Int
    var name: String
    var park: String
    var state: String
    var description: String
    
    private var imageName: String
    var image: Image {
        Image(imageName)
    }
    
    private var coordinates: Coordinates
    var locationCoordinate: CLLocationCoordinate2D {
        CLLocationCoordinate2D(
            latitude: coordinates.latitude,
            longitude: coordinates.longitude)
    }
    
    struct Coordinates: Hashable, Codable {
        var latitude: Double
        var longitude: Double
    }
}

 

 

여기서 구조체는, 3가지 protocol을 따르는데, Hashable, Decodable, Encodable입니다.

 

 

자 이렇게 json 파일에 대응되는 구조체를 만들어줬습니다!!

이 구조체 배열에 어떻게 json 파일의 값을 parsing 할 수 있을까요?

 

정말 간단합니다.

 

import Foundation

var landmarks: [Landmark] = load("landmarkData.json")

func load<T: Decodable>(_ filename: String) -> T {
    let data: Data
    
    guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
    else {
        fatalError("Couldn't find \(filename) in main bundle.")
    }
    
    do {
        data = try Data(contentsOf: file)
    } catch {
        fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
    }
    
    do {
        let decoder = JSONDecoder()
        return try decoder.decode(T.self, from: data)
    } catch {
        fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
    }
}

Landmarks 라는 방금 만들어준 LandMark 구조체의 배열을 선언해주고, 값을 할당해주면 됩니다.

 

여기서 값을 할당해주는 과정은 다음과 같습니다.

 


 

1. 먼저 filename을 통해 file을 open 해주기

let file = Bundle.main.url(forResource: filename, withExtension: nil)

 

2. 아까 선언했던 Data형의 변수에 file의 Data를 넣어주기. 여기서 Data는 encoding 되어있는 상태

data = Data(contentsOf: file)

 

3. Data를 Decoder을 통해 Decoding 해준 다음, return 해주기

let decoder = JSONDecoder()
return decoder.decode(T.self, from: data)

 


 

이게 끝이에요!ㅎㅎ

 

처음에는 너무 try catch에 의존하는거 아니야? 라는 생각이 들었지만, 애초에 문제 생기면 오류 반환해주는 거 말고 해줄 수 있는게 뭐가 있나 싶어서 수긍이 갔습니다...ㅎㅎ

 

'iOS 개발 > SwiftUI' 카테고리의 다른 글

[SwiftUI] @escaping에 대해서  (2) 2022.04.11
[SwiftUI] inout은 어떻게 작동하는가 (C언어의 Call by Reference와 비교)  (0) 2022.03.21
[SwiftUI] Generics 타입 제약 (Type Constraints) 다루기  (0) 2022.03.20
[SwiftUI] ForEach에서 \.self를 사용하는 이유와 id 중복 문제 해결 방법  (0) 2022.03.13
[SwiftUI] View 가독성을 늘리는 3가지 방법 (View 쪼개기)  (0) 2022.03.10
[SwiftUI] View protocol과 body 변수에 대한 고찰 (some 키워드를 사용하는 이유)  (0) 2022.02.25
[Swift UI] @State에 대한 아주 얕은 고찰  (0) 2021.11.07
[SwiftUI] Swift UI에 대한 첫인상  (2) 2021.11.07
    스닥
    스닥
    https://github.com/feldblume5263

    티스토리툴바