πŸ“± App/πŸŽ‡ Swift

[Swift] load(_:) method (fetching JSON data) λœ―μ–΄λ³΄κΈ°

chamroro 2023. 6. 7. 11:58

import Foundation

//Create an array of landmarks that you initialize from landmarkData.json.
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(contentsOf:) λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 파일의 λ‚΄μš©μ„ Data 객체둜 μ½μ–΄μ˜¨λ‹€. 
        // νŒŒμΌμ„ μ½λŠ” κ³Όμ •μ—μ„œ μ˜ˆμ™Έκ°€ λ°œμƒν•  수 μžˆμœΌλ―€λ‘œ try-catch 문을 μ‚¬μš©ν•˜μ—¬ μ˜ˆμ™Έ 처리λ₯Ό ν•œλ‹€. 
        // μ˜ˆμ™Έκ°€ λ°œμƒν•œ 경우, fatalErrorλ₯Ό 톡해 ν”„λ‘œκ·Έλž¨μ„ μ€‘μ§€ν•˜κ³  였λ₯˜ λ©”μ‹œμ§€λ₯Ό 좜λ ₯ν•œλ‹€.
        data = try Data(contentsOf: file)
    } catch {
        fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
    }

    do {
        // JSONDecoder μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜κ³ , decode(_:from:) λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 데이터λ₯Ό λ””μ½”λ”©ν•œλ‹€. 
        // λ””μ½”λ”©ν•  νƒ€μž…μ€ T.self둜 μ „λ‹¬λ˜λ©°, μ΄λŠ” μ œλ„€λ¦­μœΌλ‘œ 전달받은 νƒ€μž… T의 μ‹€μ œ νƒ€μž…μ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€. 
        // λ””μ½”λ”© κ³Όμ •μ—μ„œ μ˜ˆμ™Έκ°€ λ°œμƒν•  수 μžˆμœΌλ―€λ‘œ try-catch 문을 μ‚¬μš©ν•˜μ—¬ μ˜ˆμ™Έ 처리λ₯Ό ν•œλ‹€. 
        // μ˜ˆμ™Έκ°€ λ°œμƒν•œ 경우, fatalErrorλ₯Ό 톡해 ν”„λ‘œκ·Έλž¨μ„ μ€‘μ§€ν•˜κ³  였λ₯˜ λ©”μ‹œμ§€λ₯Ό 좜λ ₯ν•œλ‹€. 
        // 디코딩이 μ„±κ³΅ν•˜λ©΄ λ””μ½”λ”©λœ 값인 Tλ₯Ό λ°˜ν™˜ν•œλ‹€.
        let decoder = JSONDecoder()
        return try decoder.decode(T.self, from: data)
    } catch {
        fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
    }

}

 

μœ„μ˜ μ½”λ“œλŠ” μ œλ„€λ¦­ ν•¨μˆ˜μΈ loadλ₯Ό μ •μ˜ν•˜κ³  μžˆλ‹€.  νŒŒμΌμ—μ„œ 데이터λ₯Ό λ‘œλ“œν•˜κ³ , ν•΄λ‹Ή 데이터λ₯Ό μ§€μ •λœ νƒ€μž…μœΌλ‘œ λ””μ½”λ”©ν•˜μ—¬ λ°˜ν™˜ν•˜λŠ” μ½”λ“œμ΄λ‹€!  Decodable ν”„λ‘œν† μ½œμ„ μ€€μˆ˜ν•˜λŠ” ꡬ쑰체 λ˜λŠ” 클래슀 νƒ€μž…μ„ μ§€μ •ν•˜μ—¬ load ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄, ν•΄λ‹Ή 파일의 데이터가 λ””μ½”λ”©λ˜μ–΄ ν•΄λ‹Ή νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€λ‘œ λ°˜ν™˜λœλ‹€. 이λ₯Ό 톡해 JSON 데이터λ₯Ό Swift 객체둜 λ³€ν™˜ν•˜μ—¬ μ‚¬μš©ν•  수 μžˆλ‹€.

file λ³€μˆ˜λ₯Ό μ˜΅μ…”λ„ 바인딩 →  λ©”μ„œλ“œμ˜ κ²°κ³Όκ°€ nil이 μ•„λ‹Œ κ²½μš°μ—λ§Œ file에 값이 ν• λ‹Ή → νŒŒμΌμ˜ λ‚΄μš©μ„ Data 객체둜 μ½μ–΄μ˜€κΈ° →  JSONDecoder μΈμŠ€ν„΄μŠ€λ₯Ό 생성 →  decode(_:from:) λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 데이터λ₯Ό λ””μ½”λ”©

 

 


πŸ€” μ œλ„€λ¦­ νƒ€μž… T?

μ œλ„€λ¦­ νƒ€μž… TλŠ” ν•¨μˆ˜λ‚˜ νƒ€μž…μ„ μ •μ˜ν•  λ•Œ μ‹€μ œλ‘œ μ‚¬μš©λ  νƒ€μž…μ„ λ‚˜νƒ€λ‚΄λŠ” μΌμ’…μ˜ ν”Œλ ˆμ΄μŠ€ν™€λ”
TλŠ” νƒ€μž… νŒŒλΌλ―Έν„°λ‘œμ„œ, ν•¨μˆ˜κ°€ 호좜될 λ•Œ μ‹€μ œ νƒ€μž…μœΌλ‘œ λŒ€μ²΄λœλ‹€.

μ œλ„€λ¦­μ„ μ‚¬μš©ν•˜μ—¬ ν•¨μˆ˜λ‚˜ νƒ€μž…μ„ μ •μ˜ν•˜λ©΄, μ—¬λŸ¬ λ‹€λ₯Έ νƒ€μž…μ— λŒ€ν•΄ λ™μž‘ν•˜λŠ” μœ μ—°ν•˜κ³  μž¬μ‚¬μš© κ°€λŠ₯ν•œ μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆλ‹€. ν•¨μˆ˜λ‚˜ νƒ€μž…μ„ μΌλ°˜ν™”ν•  수 있으며, λ‹€μ–‘ν•œ νƒ€μž…μ— λŒ€ν•΄ λ™μΌν•œ λ™μž‘μ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μœ„μ˜ μ½”λ“œμ—μ„œ load ν•¨μˆ˜λŠ” TλΌλŠ” μ œλ„€λ¦­ νƒ€μž…μ„ λ°›λŠ”λ‹€. 이 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ Tμ—λŠ” μ‹€μ œλ‘œ μ‚¬μš©ν•  νƒ€μž…μ΄ μ§€μ •λœλ‹€.
예λ₯Ό λ“€μ–΄, load<Landmark>("landmarks.json")와 같이 ν˜ΈμΆœν•˜λ©΄ TλŠ” Landmark νƒ€μž…μœΌλ‘œ λŒ€μ²΄λœλ‹€.

μ œλ„€λ¦­μ„ μ‚¬μš©ν•˜λ©΄ μ½”λ“œλ₯Ό νƒ€μž…μ— λ…λ¦½μ μœΌλ‘œ μž‘μ„±ν•  수 μžˆμœΌλ―€λ‘œ, ν•¨μˆ˜λ‚˜ νƒ€μž…μ„ μž¬μ‚¬μš©ν•  수 μžˆλŠ” μž₯점이 μžˆλ‹€. λ‹€μ–‘ν•œ νƒ€μž…μ— λŒ€ν•΄ λ™μž‘ν•˜λŠ” 단일 ν•¨μˆ˜λ₯Ό μž‘μ„±ν•˜κ³ , ν•΄λ‹Ή ν•¨μˆ˜λ₯Ό λ‹€μ–‘ν•œ νƒ€μž…μœΌλ‘œ ν˜ΈμΆœν•  수 μžˆλ‹€. 이둜써 μ½”λ“œμ˜ 쀑볡을 쀄이고 μœ μ§€λ³΄μˆ˜μ„±μ„ ν–₯μƒμ‹œν‚¬ 수 μžˆλ‹€.

 

πŸ€” filename μ•žμ— λΆ™λŠ” '_' λŠ” 뭘까? 

`load` ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜ `filename` μ•žμ— 뢙은 `_`λŠ” μ™€μΌλ“œμΉ΄λ“œ μ‹λ³„μžμž…λ‹ˆλ‹€. μ™€μΌλ“œμΉ΄λ“œ μ‹λ³„μžλŠ” λ§€κ°œλ³€μˆ˜ 이름을 μƒλž΅ν•˜κ³ μž ν•  λ•Œ μ‚¬μš©λœλ‹€.

`load` ν•¨μˆ˜λŠ” 호좜될 λ•Œ 파일 이름을 인자둜 전달받아야 ν•œλ‹€. κ·ΈλŸ¬λ‚˜ ν•¨μˆ˜ λ‚΄μ—μ„œλŠ” `filename`을 μ‚¬μš©ν•˜μ§€ μ•Šκ³  μžˆλ‹€. λ”°λΌμ„œ, ν•¨μˆ˜ ν˜ΈμΆœμžμ—κ²Œ 파일 이름을 μ „λ‹¬ν•˜κΈ° μœ„ν•œ λͺ©μ μœΌλ‘œ λ§€κ°œλ³€μˆ˜ 이름을 ν•„μš”λ‘œ ν•˜μ§€ μ•ŠλŠ”λ‹€.

μ™€μΌλ“œμΉ΄λ“œ μ‹λ³„μž `_`λŠ” μ΄λŸ¬ν•œ κ²½μš°μ— μ‚¬μš©λœλ‹€. λ§€κ°œλ³€μˆ˜ 이름을 μƒλž΅ν•¨μœΌλ‘œμ¨ ν˜ΈμΆœμžμ—κ²Œμ„œ 파일 이름을 전달받을 수 있게 λœλ‹€. ν•¨μˆ˜ λ‚΄μ—μ„œλŠ” ν•΄λ‹Ή λ§€κ°œλ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ μƒλž΅ν•΄λ„ λ¬Έμ œκ°€ μ—†λ‹€.

λ”°λΌμ„œ, `func load<T: Decodable>(_ filename: String)`은 λ§€κ°œλ³€μˆ˜ `filename`을 κ°€μ§€μ§€λ§Œ, 호좜 μ‹œμ—λŠ” 파일 μ΄λ¦„λ§Œ μ „λ‹¬ν•˜λ©΄ λœλ‹€. `_`λŠ” ν˜ΈμΆœμžμ—κ²Œ ν•΄λ‹Ή λ§€κ°œλ³€μˆ˜μ˜ 이름을 감좔고 싢을 λ•Œ μ‚¬μš©λ˜λŠ” ν‘œκΈ°λ²•μ΄λ‹€.


+) λ§€κ°œλ³€μˆ˜μ˜ 이름을 감좔지 μ•Šμ„ 경우 μ½”λ“œμ˜ λͺ¨μŠ΅
let result: MyType = load<MyType>(filename: "data.json")​

 

πŸ€” guardλŠ” 뭐지?

guard ꡬ문의 μ£Όμš” λͺ©μ μ€ 쑰건이 μΆ©μ‘±λ˜μ§€ μ•ŠμœΌλ©΄ 쑰기에 ν•¨μˆ˜λ₯Ό μ’…λ£Œν•˜κ±°λ‚˜ μ˜ˆμ™Έ 처리λ₯Ό μˆ˜ν–‰ν•˜μ—¬ μ½”λ“œ 싀행을 κ³„μ†ν•˜κΈ° 전에 μ˜ˆμ™Έ 상황을 μ²˜λ¦¬ν•˜λŠ” 것
: μ½”λ“œμ˜ 가독성을 ν–₯상, 쑰건을 μΆ©μ‘±ν•˜μ§€ μ•Šμ„ λ•Œμ˜ νŠΉμˆ˜ν•œ 상황을 λͺ…μ‹œμ μœΌλ‘œ μ²˜λ¦¬κ°€ κ°€λŠ₯

 

  guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
    else {
        fatalError("Couldn't find \(filename) in main bundle.")
    }
μœ„μ˜ μ½”λ“œλŠ” guard ꡬ문을 μ‚¬μš©ν•˜μ—¬ Bundle.main.url(forResource:withExtension:) λ©”μ„œλ“œμ˜ κ²°κ³Όλ₯Ό λ°”μΈλ”©ν•˜κ³ , 쑰건을 μΆ©μ‘±ν•˜μ§€ μ•Šμ„ 경우 fatalErrorλ₯Ό λ°œμƒμ‹œν‚€λŠ” μ½”λ“œμ΄λ‹€.

Bundle.main.url(forResource:withExtension:) λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜μ—¬ 파일의 URL을 κ°€μ Έμ˜¨λ‹€. μ΄λ•Œ filename을 파일 μ΄λ¦„μœΌλ‘œ μ „λ‹¬ν•˜κ³ , withExtension은 파일의 ν™•μž₯자λ₯Ό λ‚˜νƒ€λ‚΄λŠ”λ°, nil둜 μ „λ‹¬λ˜μ–΄ ν™•μž₯자λ₯Ό μƒλž΅ν•¨μ„ μ˜λ―Έν•œλ‹€.

guard ꡬ문의 μ‘°κ±΄μ—μ„œλŠ” file λ³€μˆ˜λ₯Ό μ˜΅μ…”λ„ λ°”μΈλ”©ν•œλ‹€. Bundle.main.url(forResource:withExtension:) λ©”μ„œλ“œμ˜ κ²°κ³Όκ°€ nil이 μ•„λ‹Œ κ²½μš°μ—λ§Œ file에 값이 ν• λ‹Ήλ˜κ³ , 쑰건을 μΆ©μ‘±ν•˜μ§€ μ•Šμ„ 경우 else 블둝이 μ‹€ν–‰λœλ‹€.

else 블둝 λ‚΄λΆ€μ—μ„œλŠ” fatalErrorλ₯Ό ν˜ΈμΆœν•˜μ—¬ 였λ₯˜ λ©”μ‹œμ§€μ™€ ν•¨κ»˜ ν”„λ‘œκ·Έλž¨μ„ μ€‘μ§€μ‹œν‚¨λ‹€. fatalError ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄ ν”„λ‘œκ·Έλž¨μ΄ μ¦‰μ‹œ μ’…λ£Œλ˜λ©°, μ΄ν›„μ˜ μ½”λ“œλŠ” μ‹€ν–‰λ˜μ§€ μ•ŠλŠ”λ‹€.

즉, μœ„μ˜ μ½”λ“œλŠ” 파일의 URL을 κ°€μ Έμ˜€λŠ” κ³Όμ •μ—μ„œ λ¬Έμ œκ°€ λ°œμƒν•œ 경우, ν”„λ‘œκ·Έλž¨μ„ μ€‘μ§€ν•˜κ³  였λ₯˜ λ©”μ‹œμ§€λ₯Ό 좜λ ₯ν•˜λŠ” 것을 λͺ©μ μœΌλ‘œ ν•œλ‹€. μ΄λŠ” νŒŒμΌμ„ 찾을 수 μ—†λŠ” 상황 λ“± μ˜ˆμƒμΉ˜ λͺ»ν•œ 였λ₯˜μ— λŒ€λΉ„ν•˜μ—¬ ν”„λ‘œκ·Έλž¨μ˜ μ•ˆμ •μ„±μ„ λ†’μ΄λŠ”λ° 도움을 μ€€λ‹€.

 



λ°˜μ‘ν˜•