Post

Replies

Boosts

Views

Activity

Reply to Having trouble getting MusicKit Data into my SwiftUI view
@JoeKun, Wow! Thank you so much for this! It clears up a lot of the confusion I was having with MusicKit. I originally stored the tracks separately since that's how it was done in the official sample app but I see now why it is not needed. The Optional extension is a great idea too and really makes things easier. I am still trying to get my Table to be sortable and then write the contents of the Table to a CSV file and I think the cleaner code and Optional extension will make it easier to figure out. It is amazing how much less code I am writing using SwiftUI with MusicKit versus Apple Music API and AppKit. Thanks again for all of your support!
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Dec ’21
Reply to Having trouble getting MusicKit Data into my SwiftUI view
Hey @JoeKun, Thanks so much for responding! I was able some code similar to what you posted, but I used MusicItemCollection() instead. I find it is easier for me to use it as a variable instead of a Type but I am not sure if this is correct. My code is shown below. What is the difference between using "@State var album: Album?" and "@State var album: MusicItemCollection?" So this question is only part of my overall issue which is getting the results into a SwiftUI Table. When trying to use a Table in your code (based off of the Garden official sample app I get errors such as: "Album.Type cannot conform to RandomAccessCollection" or "Initializer 'init(_:columns:)' requires that 'Album' conform to 'RandomAccessCollection'". I am sure it can be done, I just don't know what steps I am missing. In my code I can make a Table but I have to convert each value into a string at the TableColumn. So what is the best way to do this? How would you make a Table (like the one I have in my code) of all of the album details, or a table of the album's tracks in the code you provided? Thanks so much! struct ContentView: View {     @State private var albumDetails = MusicItemCollection<Album>()     @State private var albumTracks = MusicItemCollection<Track>()     @State private var selection = Set<Track.ID>()     @State var sortOrder: [KeyPathComparator<Track>] = [         .init(\.trackNumber, order: SortOrder.forward)     ]               var body: some View {         VStack {             HStack {                 if let artwork = albumDetails.first?.artwork {                     ArtworkImage(artwork, width: 400, height: 400)                                      }             List(albumDetails, id:\.id) { album in                 Text("album id: \(album.id.rawValue)")                     .foregroundColor(.secondary)                     .padding(2)                 Text("title: \(album.title)")                     .foregroundColor(.secondary)                     .padding(2)                 Text("artist: \(album.artistName)")                     .foregroundColor(.secondary)                     .padding(2)                 Text("composer: \(album.artistName)")                     .foregroundColor(.secondary)                     .padding(2)                 Text("total tracks: \(album.trackCount)")                     .foregroundColor(.secondary)                     .padding(2)                 Text("genres: \(album.genreNames.joined(separator: ", "))")                     .foregroundColor(.secondary)                     .padding(2)                 Text("release date: \((album.releaseDate?.formatted(date: .abbreviated, time: .omitted))!)")                     .foregroundColor(.secondary)                     .padding(2)                 Text("record label: \(album.recordLabelName ?? "not available")")                     .foregroundColor(.secondary)                     .padding(2)                 Text("copyright: \(album.copyright ?? "not available")")                     .foregroundColor(.secondary)                     .padding(2)                 Text("upc: \(album.upc ?? "not available")")                     .foregroundColor(.secondary)                     .padding(2)             }             .font(.system(size: 14))             .onAppear {                 albumAPI().requestMusicAuthorization()                 async {                     self.albumDetails = try await albumAPI().getAlbum()                     let firstAlbum = albumDetails.first                     self.albumTracks = (firstAlbum?.tracks)!                     print(firstAlbum!)                     }                 }             }                          if (albumDetails.first?.editorialNotes?.standard) != nil {             Text("\(albumDetails.first?.editorialNotes?.standard ?? "")")                 .font(.system(size: 14))                 .foregroundColor(.secondary)                 .padding(2)                 }                                   Table(albumTracks, selection: $selection, sortOrder: $sortOrder) {                 TableColumn("track") { track in                     Text(String(track.trackNumber!))                 }                 TableColumn("title", value: \.title)                 TableColumn("artist", value: \.artistName)                 TableColumn("release date") { track in                     Text((track.releaseDate?.formatted(date: .abbreviated, time: .omitted))!)                 }                 TableColumn("duration") { track in                     Text(String(track.duration!))                 }                 TableColumn("isrc") { track in                     Text(String(track.isrc!))                 }             }         }     } }     ```
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Dec ’21
Reply to Cannot get [genreNames] into SwiftUI Table
Anyone? If my question was too long the shorter version is: How do I make an Array of Strings into a String that the SwiftUI Table can use? I am trying to get the genreNames returned from an Apple Music API search into my Swift UI Table that only accepts strings (to my knowledge). Any guesses? Thanks!
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Nov ’21
Reply to SwiftUI Table does not work when trying to use Int values
I have a follow up question that I bet you know the answer to. Of course no worries if you don't have the time. How would I get [genreNames] into the table? The genreNames that come back are formatted as an Array of Strings. In my data model I had entered the genreNames as [String] as shown here: struct SongDetails {     var albumName: String     var artistName: String     var artworkURL: String     var composerName: String     var discNumber: Int     var durationInMillis: Int     var genreNames: [String]     var isrc: String     var name: String     var id: String     var releaseDate: String     var trackNumber: Int but when parsing the JSON when it returns from the API call, it would not let me label the genreNames with .string! URLSession.shared.dataTask(with: musicRequest) { (data, response, error) in             guard error == nil else { return }             if let json = try? JSON(data: data!) {                 let result = (json["data"]).array!                 for songDetail in result {                     let attributes = songDetail["attributes"]                     let song = SongDetails(albumName: attributes["albumName"].string!,                                artistName: attributes["artistName"].string!,                                artworkURL: attributes["artwork"]["url"].string!,                                composerName: attributes["composerName"].string ?? "-",                                discNumber: attributes["discNumber"].int!,                                durationInMillis: attributes["durationInMillis"].int!,                                genreNames: attributes["genreNames"].arrayValue,                                isrc: attributes["isrc"].string!,                                name: attributes["name"].string!,                                id: attributes["playParams"]["id"].string!,                                releaseDate: attributes["releaseDate"].string!,                                trackNumber: attributes["trackNumber"].int!)                     songDetails.append(song)                     print(songDetails)                 } so I eventually figured out that it had to be an arrayValue or an Array. So now I have that working but I can't seem to convert the array into a string using join() . I just want a string of the genreNames to put into once table cell. I also re-wrote everything to use Codable, but got stuck at the east same point. So basically I want to get [genreNames] returned from the JSON to a string such as: Alternative, Indie, Pop. I hope the is enough info for you or else anyone trying to help. This is the last piece I am struggling with. Thanks!
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Nov ’21
Reply to Having trouble getting MusicKit Data into my SwiftUI view
@JoeKun, Wow! Thank you so much for this! It clears up a lot of the confusion I was having with MusicKit. I originally stored the tracks separately since that's how it was done in the official sample app but I see now why it is not needed. The Optional extension is a great idea too and really makes things easier. I am still trying to get my Table to be sortable and then write the contents of the Table to a CSV file and I think the cleaner code and Optional extension will make it easier to figure out. It is amazing how much less code I am writing using SwiftUI with MusicKit versus Apple Music API and AppKit. Thanks again for all of your support!
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Dec ’21
Reply to Having trouble getting MusicKit Data into my SwiftUI view
Hey @JoeKun, Thanks so much for responding! I was able some code similar to what you posted, but I used MusicItemCollection() instead. I find it is easier for me to use it as a variable instead of a Type but I am not sure if this is correct. My code is shown below. What is the difference between using "@State var album: Album?" and "@State var album: MusicItemCollection?" So this question is only part of my overall issue which is getting the results into a SwiftUI Table. When trying to use a Table in your code (based off of the Garden official sample app I get errors such as: "Album.Type cannot conform to RandomAccessCollection" or "Initializer 'init(_:columns:)' requires that 'Album' conform to 'RandomAccessCollection'". I am sure it can be done, I just don't know what steps I am missing. In my code I can make a Table but I have to convert each value into a string at the TableColumn. So what is the best way to do this? How would you make a Table (like the one I have in my code) of all of the album details, or a table of the album's tracks in the code you provided? Thanks so much! struct ContentView: View {     @State private var albumDetails = MusicItemCollection<Album>()     @State private var albumTracks = MusicItemCollection<Track>()     @State private var selection = Set<Track.ID>()     @State var sortOrder: [KeyPathComparator<Track>] = [         .init(\.trackNumber, order: SortOrder.forward)     ]               var body: some View {         VStack {             HStack {                 if let artwork = albumDetails.first?.artwork {                     ArtworkImage(artwork, width: 400, height: 400)                                      }             List(albumDetails, id:\.id) { album in                 Text("album id: \(album.id.rawValue)")                     .foregroundColor(.secondary)                     .padding(2)                 Text("title: \(album.title)")                     .foregroundColor(.secondary)                     .padding(2)                 Text("artist: \(album.artistName)")                     .foregroundColor(.secondary)                     .padding(2)                 Text("composer: \(album.artistName)")                     .foregroundColor(.secondary)                     .padding(2)                 Text("total tracks: \(album.trackCount)")                     .foregroundColor(.secondary)                     .padding(2)                 Text("genres: \(album.genreNames.joined(separator: ", "))")                     .foregroundColor(.secondary)                     .padding(2)                 Text("release date: \((album.releaseDate?.formatted(date: .abbreviated, time: .omitted))!)")                     .foregroundColor(.secondary)                     .padding(2)                 Text("record label: \(album.recordLabelName ?? "not available")")                     .foregroundColor(.secondary)                     .padding(2)                 Text("copyright: \(album.copyright ?? "not available")")                     .foregroundColor(.secondary)                     .padding(2)                 Text("upc: \(album.upc ?? "not available")")                     .foregroundColor(.secondary)                     .padding(2)             }             .font(.system(size: 14))             .onAppear {                 albumAPI().requestMusicAuthorization()                 async {                     self.albumDetails = try await albumAPI().getAlbum()                     let firstAlbum = albumDetails.first                     self.albumTracks = (firstAlbum?.tracks)!                     print(firstAlbum!)                     }                 }             }                          if (albumDetails.first?.editorialNotes?.standard) != nil {             Text("\(albumDetails.first?.editorialNotes?.standard ?? "")")                 .font(.system(size: 14))                 .foregroundColor(.secondary)                 .padding(2)                 }                                   Table(albumTracks, selection: $selection, sortOrder: $sortOrder) {                 TableColumn("track") { track in                     Text(String(track.trackNumber!))                 }                 TableColumn("title", value: \.title)                 TableColumn("artist", value: \.artistName)                 TableColumn("release date") { track in                     Text((track.releaseDate?.formatted(date: .abbreviated, time: .omitted))!)                 }                 TableColumn("duration") { track in                     Text(String(track.duration!))                 }                 TableColumn("isrc") { track in                     Text(String(track.isrc!))                 }             }         }     } }     ```
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Dec ’21
Reply to Cannot get [genreNames] into SwiftUI Table
Anyone? If my question was too long the shorter version is: How do I make an Array of Strings into a String that the SwiftUI Table can use? I am trying to get the genreNames returned from an Apple Music API search into my Swift UI Table that only accepts strings (to my knowledge). Any guesses? Thanks!
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Nov ’21
Reply to SwiftUI Table does not work when trying to use Int values
I have a follow up question that I bet you know the answer to. Of course no worries if you don't have the time. How would I get [genreNames] into the table? The genreNames that come back are formatted as an Array of Strings. In my data model I had entered the genreNames as [String] as shown here: struct SongDetails {     var albumName: String     var artistName: String     var artworkURL: String     var composerName: String     var discNumber: Int     var durationInMillis: Int     var genreNames: [String]     var isrc: String     var name: String     var id: String     var releaseDate: String     var trackNumber: Int but when parsing the JSON when it returns from the API call, it would not let me label the genreNames with .string! URLSession.shared.dataTask(with: musicRequest) { (data, response, error) in             guard error == nil else { return }             if let json = try? JSON(data: data!) {                 let result = (json["data"]).array!                 for songDetail in result {                     let attributes = songDetail["attributes"]                     let song = SongDetails(albumName: attributes["albumName"].string!,                                artistName: attributes["artistName"].string!,                                artworkURL: attributes["artwork"]["url"].string!,                                composerName: attributes["composerName"].string ?? "-",                                discNumber: attributes["discNumber"].int!,                                durationInMillis: attributes["durationInMillis"].int!,                                genreNames: attributes["genreNames"].arrayValue,                                isrc: attributes["isrc"].string!,                                name: attributes["name"].string!,                                id: attributes["playParams"]["id"].string!,                                releaseDate: attributes["releaseDate"].string!,                                trackNumber: attributes["trackNumber"].int!)                     songDetails.append(song)                     print(songDetails)                 } so I eventually figured out that it had to be an arrayValue or an Array. So now I have that working but I can't seem to convert the array into a string using join() . I just want a string of the genreNames to put into once table cell. I also re-wrote everything to use Codable, but got stuck at the east same point. So basically I want to get [genreNames] returned from the JSON to a string such as: Alternative, Indie, Pop. I hope the is enough info for you or else anyone trying to help. This is the last piece I am struggling with. Thanks!
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Nov ’21