Post

Replies

Boosts

Views

Activity

Reply to SwiftUI - What is Identifiable?
Does the compiler automatically generate a unique string like UUID for each element in the array or something? NO. In the code shown, it is the case you need to provide an id parameter to the ForEach initializer. Can I somehow print the raw value of each id? In your case, you specify \.self for id:, meaning -- The id of "Susan" is "Susan" itself. The id of "Kate" is "Kate" itself. The id of "Natalie" is "Natalie" itself. ... And so on. When you define an Identifiable struct explicitly, for example: struct User: Identifiable { var id: String {name} var name: String } Then you have no need to specify id: in ForEach: struct ContentView: View { var users: [User] = ["Susan", "Kate", "Natalie", "Kimberly", "Taylor", "Sarah", "Nancy", "Katherine", "Nicole", "Linda", "Jane", "Mary", "Olivia", "Barbara"] .map(User.init(name:)) var body: some View { List { ForEach(users) { user in Text(user.name) } } } }
Topic: UI Frameworks SubTopic: SwiftUI 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
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 Macos 12 not available after update to Xcode to Version 13.0 (13A233)
The similar thing happened in recent years, when the release of new macOS was planned to be a bit later than iOS. Considering such recent year updates, you may need to continue using the older beta or need to wait until the next beta which supports macOS 12 will be out.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’21
Reply to SwiftUI - What is Identifiable?
Does the compiler automatically generate a unique string like UUID for each element in the array or something? NO. In the code shown, it is the case you need to provide an id parameter to the ForEach initializer. Can I somehow print the raw value of each id? In your case, you specify \.self for id:, meaning -- The id of "Susan" is "Susan" itself. The id of "Kate" is "Kate" itself. The id of "Natalie" is "Natalie" itself. ... And so on. When you define an Identifiable struct explicitly, for example: struct User: Identifiable { var id: String {name} var name: String } Then you have no need to specify id: in ForEach: struct ContentView: View { var users: [User] = ["Susan", "Kate", "Natalie", "Kimberly", "Taylor", "Sarah", "Nancy", "Katherine", "Nicole", "Linda", "Jane", "Mary", "Olivia", "Barbara"] .map(User.init(name:)) var body: some View { List { ForEach(users) { user in Text(user.name) } } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’21
Reply to How to override shadowColor?
shadowColor is a settable property of NSShadow and the class NSShadow is not intended to be subclassed, so override property does not make sense. Can you clarify what you want to achieve?
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Sep ’21
Reply to Cannot find type 'CreateTaskIntentHandling' in scope
Isn't it because Xcode 13 RC does not contain macOS 12 SDK? Have you tried it with an older Xcode 13 beta?
Topic: App & System Services SubTopic: Core OS Tags:
Replies
Boosts
Views
Activity
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:
Replies
Boosts
Views
Activity
Sep ’21
Reply to Is it possible to adjust brightness in SwiftUI?
Have you tried the exact code in your watchOS app?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’21
Reply to Submitting iOS 15 apps with Xcode RC?
Apple says so. Better check News and Updates by yourself. Apple uses the term RC (Release Candidate) instead of GM in this one year or so.
Replies
Boosts
Views
Activity
Sep ’21
Reply to Value of type 'UIStoryboardSegue' has no member 'indentifier'
Isn't it a simple typo? switch segue.indentifier! { ↓ switch segue.identifier! { You might be able to find this sort of typo by yourself, when you had a custom to look into the reference doc: UIStoryboardSegue
Replies
Boosts
Views
Activity
Sep ’21
Reply to create a list from selected items in a "Add to playlist" style
If you could show as much code as you could, more readers would try to help.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’21
Reply to Fetch data from API every 5 seconds
Showing partial code would not help solving your issue. Please show complete code, at least the full code of the method, preferably full code of the class. By the way every 5 seconds may be too much. Your app may be called a battery eater or a packet eater.
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Sep ’21
Reply to Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT) whenever I try to make a network request
From the stack trace, you may hit some generics related bug of Swift Concurrency. Have you tried making post and executeRequest non-generic or adding an explicit type parameter to executeRequest?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’21
Reply to iOS15 NavigationView release sequence
Can you show a code to reproduce the issue? Simplified but enough to reproduce.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’21
Reply to Fetch data from API every 5 seconds
You could show your code as Code Block.
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Sep ’21
Reply to Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT) whenever I try to make a network request
Sorry, I do not know. Please share yours when you find one.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
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:
Replies
Boosts
Views
Activity
Sep ’21