iOS & Swift 공부 - Parsing JSON (영)

김영채 (Kevin)·2020년 12월 31일
0

iOS & Swift

목록 보기
5/107
post-thumbnail

What is JSON?


JavaScript Object Notation

→ an open-standard file format or data interchange format that uses human-readable text to transmit data objects.

→ 데이터 덩어리로 생각하면 됨

Parsing JSON data → processing the JSON data format into a usable format

Key Value Pairs

"firstName": "Tom"

→ This represents one piece of data

{
"firstName": "Tom",
"lastName": "Hardy"
}

→ This is called a JSON Object

JSON Array

[
 {
   "firstName": "Christian",
   "lastName": "Bale"
 },
 {
   "firstName": "Tom",
   "lastName": "Hardy"
 }
]

→ A list of JSON Objects

→ Square brackets needed

→ This is how how data is organized in JSON format

example:

{
"status": "ok",
"totalResults": 4873,
-"articles": [
-{
-"source": {
"id": null,
"name": "newsBTC"
},
"author": "Nick Chong",
"title": "XRP Loses Even More Exchange Support as Uncertainty Continues",
"description": "XRP has continued to crash in the face of news that it will be listed from a new round of leading crypto asset exchanges. The altcoin is now down by over 20 percent in the past 24 hours, reaching multi-month lows at $0.21. XRP is also down by 55 percent in th…",
"url": "https://www.newsbtc.com/analysis/xrp/xrp-loses-even-more-exchange-support-as-uncertainty-continues/",
"urlToImage": "https://www.newsbtc.com/wp-content/uploads/2020/12/marcos-paulo-prado-588l4wraJQo-unsplash.jpg",
"publishedAt": "2020-12-29T10:00:50Z",
"content": "XRP has continued to crash in the face of news that it will be listed from a new round of leading crypto asset exchanges.\r\nThe altcoin is now down by over 20 percent in the past 24 hours, reaching mu… [+2374 chars]"
},
.
.
.
//source: newsapi.org

note:

In the Key Value pair, the value part doesn't always have to be an Int, String, Float etc. It can be another JSON object/array.

Parsing JSON using Swift


  • Think about what information you need to display/use in your app

  • There is a JSON Decoder Class that we can use

  • Codable protocol

  • Create a structure (구조체) in swift that represents data in JSON (map)

    → The structure will have the same properties mapped with the Keys in the JSON Object

    → You don't have to put Keys that you don't want to use

    → Make it as a separate Swift file

example:

{
"status": "ok",
"totalResults": 4873,
+"articles": [ … ]
}

...from News API

  • Create "NewsFeed.swift" file in your Xcode project
  • map the same value
struct NewsFeed: Codable{        //Codable is a protocol we need to use
    
    var status: String = ""
    var totalResults:Int = 0
    var articles:[Article]?      //an array of Articles (contains: content, url, etc..)
    
}
  • Create a separate swift file named "Article.swift"
  • Create a structure for Article
struct Article: Codable{
    
    var author:String?
    var title:String?
    var description:String?
    var url:String?
    var urlToImage:String?
    var publishedAt:String?
    var content:String?
    
}

→ Declare all variables as Optionals if you are not sure if they can be nil or not.

ViewController.swift

//
//  ViewController.swift
//  JSON_example
//
//  Created by Kevin Kim on 2020/12/29.
//

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Hit the API endpoint
        let urlString = "http://newsapi.org/v2/everything?q=bitcoin&from=2020-11-29&sortBy=publishedAt&apiKey=ad476a2319b24e7191a7d845537b9f1f"
        
        //turning the string into a URL object
        //URL() may return a nil, so we need a guard statement so it doesn't
        let url = URL(string: urlString)
        
        guard url != nil else{
            return
        }
        
        let session = URLSession.shared
        
        let dataTask = session.dataTask(with: url!) { (data,response,error) in
            
            //Check that there are no errors and that data exists
            if error == nil && data != nil {
                
                //Parse JSON
                let decoder = JSONDecoder()
                
                do{
                 
                    let newsFeed = try decoder.decode(NewsFeed.self, from: data!)
                
                    print(newsFeed)
                }
                catch{
                    print("Error in JSON parsing")
                }
            }
            
        }
        //Make the API Call
        dataTask.resume()
}

DataLoader.swift

import Foundation

//A DataLoader class to actually retrieve
//and store data from the JSON file

public class DataLoader {
    
    @Published var resultList = [Results]()
    
    init(){
        load()
        sort()
    }
    
    //We want to run this function when DataLoader class is created.
    func load(){
        
        //Bundle refers to everything in the project folder
        if let fileLocation = Bundle.main.url(forResource: "GetToDoList", withExtension: "json"){
            
            //do catch in case of an error
            do{
                
                let data = try Data(contentsOf: fileLocation)       //we put "try" cause it may throw an error
                let jsonDecoder = JSONDecoder()
                
                //[Results]을 하는 이유는 배열을 받아오기 때문 -> a lot of data
                //Creates an array of Results object from the JSON file
                let dataFromJson = try jsonDecoder.decode([Results].self, from: data)
                
                //resultList 에 받아온 데이터를 저장
                self.resultList = dataFromJson
                
                
                
            }catch{
                print(error.localizedDescription)
            }
            
        }
    }
    
    func sort(){
    
        //Sort by id
        self.resultList = self.resultList.sorted(by: { $0.id! < $1.id! })
    }
}
profile
맛있는 iOS 프로그래밍

0개의 댓글