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.
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
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..)
}
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! })
}
}