j bel
j bel

Reputation: 153

Create list from nested struct swift ui

Im testing a list picker in my IOS app which allows users to choose a playlist. The example compiles however the preview is not what is expected. From the JSON file you can see that there is different data in each collection however in my list it only seems to pick the 1st value and repeat it for the size of the collection. What am I missing from my List, I thought the syntax was List( your collection, identifier: .name of identifier in your struct. its basically printing the same index upon each entry.

[
{
    "id" :"1",
"partyinfo": {
"artwork_url": "Rectangle 34",
"id": 1234,
"stream_url": "https://api.soundcloud.com/tracks/1234/stream",
"partyname": "Josh's Party",
"songs": "4 songs",
"participants":"3",
"location":"1010",
"user": {
  "avatar_url": "https://i1.sndcdn.com/avatars-large.jpg",
  "id": 12345,
  "kind": "user",
  "last_modified": "2020/09/03 14:08:25 +0000",
  "permalink": "permalink",
  "permalink_url": "https://soundcloud.com/permalink",
  "uri": "https://api.soundcloud.com/users/12345",
  "username": "Josh",
  "$$ref": "#/components/examples/UserOf/value"
}
}
},
{
    "id" :"2",
"partyinfo": {
"artwork_url": "Rectangle 35",
"id": 1234,
"stream_url": "https://api.soundcloud.com/tracks/1234/stream",
"partyname": "Alan's Party",
"songs": "4 songs",
"participants":"3",
"location":"1010",
"user": {
  "avatar_url": "https://i1.sndcdn.com/avatars-large.jpg",
  "id": 12345,
  "kind": "user",
  "last_modified": "2020/09/03 14:08:25 +0000",
  "permalink": "permalink",
  "permalink_url": "https://soundcloud.com/permalink",
  "uri": "https://api.soundcloud.com/users/12345",
  "username": "Alan",
  "$$ref": "#/components/examples/UserOf/value"
}
}
}
]

PartyList

import SwiftUI

struct PartyList: View {

var partyInfoList: [PartyInfo]{

    var b: [PartyInfo] = []
    for n in partylist {
        b.append(n.partyinfo)
        print(n.partyinfo.partyname)
       
    }
    return b
 

}

    
var body: some View {

    
    List(partyInfoList, id: \.id){ party in
        Text(party.partyname)
    }

}
}


struct PartyList_Previews: PreviewProvider {

static var previews: some View {
    PartyList()
}
}

Model Data

import Foundation

var tracklist: [Tracklist] = load("tracklist.json")
var partylist: [Party] = load("partylist.json")

final class ModelData: ObservableObject {

//@Published var tracklist: [Tracklist] = load("tracklist.json")
//@Published var partylist: [Party] = load("partylist.json")

}

func load<T: Decodable>(_ filename: String) -> T {
let data: Data

guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
    else {
    print("error 1")
        fatalError("Couldn't find \(filename) in main bundle.")
    
}

do {
    data = try Data(contentsOf: file)
} catch {
    print("error 2")
    fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}

do {
    let decoder = JSONDecoder()
    print("Successful")
    return try decoder.decode(T.self, from: data)
} catch {
    print("error 3")
    fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}

Party Struct

import Foundation
import SwiftUI

struct Party:Hashable, Codable {

let partyinfo: PartyInfo
}


struct PartyInfo : Hashable, Codable,  Identifiable {

var id: Int
var partyname: String
var songs: String
var participants: String
var location: String


private var artwork_url: String
var image: Image {
    getSafeImage(named: artwork_url)
}

func getSafeImage(named: String) -> Image {
   let uiImage =  (UIImage(named: named) ?? UIImage(named: "Default.png"))!
   return Image(uiImage: uiImage)
}
}

Upvotes: 0

Views: 195

Answers (1)

jnpdx
jnpdx

Reputation: 52595

Both entities in your JSON data have the same id right now: 1234.

Because your List is using .id to differentiate between items, unexpected things can happen with entities with duplicate ids.

To fix, this, make sure that your entities have unique id fields.

Upvotes: 1

Related Questions