Post

Replies

Boosts

Views

Activity

Reply to Older versions of Xcode for Catalina
I do not understand what you mean by intel 7 Mac, but the requirements of recent Xcodes are described here: https://developer.apple.com/support/xcode/ Seems Xcode 12.4 is the latest Xcode which can run on Catalina. (You need to upgrade your macOS to 10.15.4 or later to run it.) You can download older Xcodes through More Downloads pages. Please remember, if you are planning to develop an iOS app for App Store, you can use Xcode 12.x only till April 2022. App Store submissions now open for iOS 15 & iPadOS 15 Starting April 2022, all iOS and iPadOS apps submitted to the App Store must be built with Xcode 13 and the iOS 15 SDK.
Sep ’21
Reply to XCode 13 work on 2014 Mac PowerBook?
Does XCode 13 work on 2014 Mac PowerBook? PowerBook is an ancient brand name of Apple's and no product models named PowerBook are not out in 2014. You should better check the exact model name with opening About This Mac: The requirements of Xcode 13 RC is described in the release notes simply: Xcode 13 RC Release Notes Xcode 13 RC requires a Mac running macOS 11.3 or later. So generally, if you can upgrade your Mac to macOS 11.3 or later, you can run Xcode 13 RC on it. What is the minimum available memory requirement?  I could not find any clear documentations about memory requirements of recent Xcodes. But in my experience, 8GB is minimum, though it may not be enough when building some practical apps. Also you might need at least a few tens of GB of free disk space to test/run your apps.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’21
Reply to Fetch data from API every 5 seconds
Thanks for showing your code. Generally, easily triable code would help involving more readers. Very few people would dive into the external links, even though they are safe enough as GitHub. And have you tried Paste and Match Style as suggested by Claude31? It will help preventing extra empty lines added. Seems you use asyncAfter in the wrong place. You need to trigger fetching the next nowPlaying after the current nowPlaying is processed. Please try something like this: override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. overrideUserInterfaceStyle = .light setupRemoteCommandCenter() requestNowPlaying() } private var songArtUrl: URL? = nil private func requestNowPlaying() { //Radio API endpoint title and artist labels 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.songtitle.text = radio.nowPlaying.song.title self.artist.text = radio.nowPlaying.song.artist //albumcover art section if let artUrl = URL(string: radio.nowPlaying.song.art), artUrl != self.songArtUrl { //I need to load an image from `artUrl` let imageDatatask = session.dataTask(with: artUrl) { imageData, imageResponse, imageError in if let imageError = imageError { print(imageError) return } guard let imageData = imageData else { print("image_data is nil") return } DispatchQueue.main.async { self.songArtUrl = artUrl let albumArt = UIImage(data: imageData) //↓ Assuming you connected `artUrl` to the right UIImageView //Generally, naming `...Url` for a property of type `UIImageView` may be confusing... self.artUrl.image = albumArt } } imageDatatask.resume() } let intervalToNextRequest = radio.nowPlaying.remaining ?? 5 // Re-consider if this is appropriate print("intervalToNextRequest=\(intervalToNextRequest)") DispatchQueue.main.asyncAfter(deadline: .now() + TimeInterval(intervalToNextRequest)) { print("Next request triggered...") self.requestNowPlaying() } } } catch { print("Error Parsing JSON: \(error)") } } dataTask.resume() }
Topic: Programming Languages SubTopic: Swift Tags:
Sep ’21
Reply to JSON parsing from a static JSON file into the label
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() }
Topic: UI Frameworks SubTopic: UIKit Tags:
Sep ’21