Skip to content

Instantly share code, notes, and snippets.

@fx-studio
Created November 24, 2021 04:42
Show Gist options
  • Save fx-studio/1e153397fcdd13dff45a6bcede8d5624 to your computer and use it in GitHub Desktop.
Save fx-studio/1e153397fcdd13dff45a6bcede8d5624 to your computer and use it in GitHub Desktop.
Parse JSON from API with Swift
import Foundation
import UIKit
// Data to JSON
typealias JSON = [String: AnyObject]
extension Data {
func toJSON() -> JSON? {
var json: JSON? = nil
do {
if let jsonObj = try JSONSerialization.jsonObject(with: self, options: .mutableContainers) as? JSON {
json = jsonObj
}
} catch {
print("JSON casting error")
}
return json
}
}
// Create API Model
struct Song {
var artistName: String
var id: String
var name: String
var releaseDate: String
var url: String
}
// Define Error
enum APIError: Error {
case error(String)
case errorURL
var localizedDescription: String {
switch self {
case .error(let string):
return string
case .errorURL:
return "URL String is error."
}
}
}
// Load API --> update call back
func loadAPI(completed: @escaping (Error?, [Song]?) -> Void) {
// Create Request
let urlString = "https://rss.applemarketingtools.com/api/v2/us/music/most-played/10/songs.json"
guard let url = URL(string: urlString) else {
// call back
completed(APIError.errorURL, nil)
return
}
var request = URLRequest(url: url)
// add method
request.httpMethod = "GET"
// Connection
// config
let config = URLSessionConfiguration.ephemeral
config.waitsForConnectivity = true
// URLSession
let session = URLSession(configuration: config)
// task + call bacl
let task = session.dataTask(with: request) { data, response, error in
// main thread
DispatchQueue.main.async {
// check error
if let error = error {
// Request failed
// call back
completed(error, nil)
} else {
// Request success
print("API OKAY!")
// check data
if let data = data,
let json = data.toJSON() {
// parse json
// Feed > Results > Item
let feed = json["feed"] as! JSON // dictionary
let results = feed["results"] as! [JSON] // array
// array items
var songs: [Song] = []
for item in results {
// get infor
let artistName = item["artistName"] as! String
let id = item["id"] as! String
let name = item["name"] as! String
let releaseDate = item["releaseDate"] as! String
let url = item["url"] as! String
// create object
let song = Song(artistName: artistName,
id: id,
name: name,
releaseDate: releaseDate,
url: url)
songs.append(song)
}
// call back
completed(nil, songs)
} else {
// call back
completed(APIError.error("Data format is error."), nil)
}
}
}
}
// resume
task.resume()
}
// call api
loadAPI { error, songs in
if let error = error {
print("ERROR: \(error.localizedDescription)")
} else {
if let songs = songs {
for song in songs {
print("name: \(song.name) - \(song.artistName)")
}
} else {
print("Data error!")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment