First of all, it looks like you are using UIKit, not SwiftUI. Putting the right tags would help you getting the right solution sooner.
This one is standard API: https://admin.radiopromil.online/api/nowplaying/radio_promil
Seems the result of the API is a little bit long and complex:
API result
The first thing you need to do is defining the right structs for the API result, but it seems to be difficult to do it manually.
There are some sites which generates Swift structs from JSON automatically.
You should better search with json to swift and can easily find one.
From one of them, I could get the followings from the API result:
import Foundation
// MARK: - RadioAPI
struct RadioAPI: Codable {
let station: Station
let listeners: Listeners
let live: Live
let nowPlaying: NowPlaying
let playingNext: PlayingNext
let songHistory: [NowPlaying]
let isOnline: Bool
let cache: String
enum CodingKeys: String, CodingKey {
case station, listeners, live
case nowPlaying = "now_playing"
case playingNext = "playing_next"
case songHistory = "song_history"
case isOnline = "is_online"
case cache
}
}
// MARK: - Listeners
struct Listeners: Codable {
let total, unique, current: Int
}
// MARK: - Live
struct Live: Codable {
let isLive: Bool
let streamerName: String
//let broadcastStart: JSONNull? // Modified from generated code
enum CodingKeys: String, CodingKey {
case isLive = "is_live"
case streamerName = "streamer_name"
//case broadcastStart = "broadcast_start"
}
}
// MARK: - NowPlaying
struct NowPlaying: Codable {
let elapsed, remaining: Int?
let shID, playedAt, duration: Int
let playlist, streamer: String
let isRequest: Bool
let song: Song
enum CodingKeys: String, CodingKey {
case elapsed, remaining
case shID = "sh_id"
case playedAt = "played_at"
case duration, playlist, streamer
case isRequest = "is_request"
case song
}
}
// MARK: - Song
struct Song: Codable {
let id, text, artist, title: String
let album, genre, lyrics: String
let art: String
//let customFields: [JSONAny] //Modified
enum CodingKeys: String, CodingKey {
case id, text, artist, title, album, genre, lyrics, art
//case customFields = "custom_fields" //Modified
}
}
// MARK: - PlayingNext
struct PlayingNext: Codable {
let cuedAt, duration: Int
let playlist: String
let isRequest: Bool
let song: Song
enum CodingKeys: String, CodingKey {
case cuedAt = "cued_at"
case duration, playlist
case isRequest = "is_request"
case song
}
}
// MARK: - Station
struct Station: Codable {
let id: Int
let name, shortcode, stationDescription, frontend: String
let backend: String
let listenURL: String
let url: String
let publicPlayerURL: String
let playlistPlsURL: String
let playlistM3UURL: String
let isPublic: Bool
let mounts: [Mount]
//let remotes: [JSONAny] //Modified
enum CodingKeys: String, CodingKey {
case id, name, shortcode
case stationDescription = "description"
case frontend, backend
case listenURL = "listen_url"
case url
case publicPlayerURL = "public_player_url"
case playlistPlsURL = "playlist_pls_url"
case playlistM3UURL = "playlist_m3u_url"
case isPublic = "is_public"
case mounts//, remotes //Modified
}
}
// MARK: - Mount
struct Mount: Codable {
let path: String
let isDefault: Bool
let id: Int
let name: String
let url: String
let bitrate: Int
let format: String
let listeners: Listeners
enum CodingKeys: String, CodingKey {
case path
case isDefault = "is_default"
case id, name, url, bitrate, format, listeners
}
}
(From https://app.quicktype.io, some parts commented out to ignore unspecified results.)
You can use the structs like this:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
overrideUserInterfaceStyle = .light
setupRemoteCommandCenter()
//Radio API endpoint
let urlString = "https://admin.radiopromil.online/api/nowplaying/radio_promil"
let url = URL(string: urlString)!
let session = URLSession.shared
let dataTask = session.dataTask(with: url) { data, response, error in
if let error = error {
print(error)
return
}
guard let data = data else {
print("data is nil")
return
}
let decoder = JSONDecoder()
do {
let radio = try decoder.decode(RadioAPI.self, from: data)
print(radio)
DispatchQueue.main.async {
self.titleLabel.text = radio.nowPlaying.song.title
self.artistLabel.text = radio.nowPlaying.song.artist
if let artUrl = URL(string: radio.nowPlaying.song.art) {
//TODO: You need to load an image from `artUrl`,
//but that's another issue...
}
}
} catch {
print("Error Parsing JSON: \(error)")
}
}
dataTask.resume()
}