there is json (link below), you need to put the data from it into picker swiftui, is this possible?
This is the class that loads the necessary data.
class pickerAPI: ObservableObject {
@Published var groupModel: GroupModel = [GroupModelElement]()
init() {
loadPickerData()
}
func loadPickerData() {
guard let url: URL = URL(string: "https://gist.githubusercontent.com/lisindima/a3246c9eebae2e152c1f8211d10d4255/raw/30ee8647261b839c3a00024a851a340295300787/group") else { return }
URLSession.shared.dataTask(with: url) { (data, response, error) in
do {
guard let json = data else { return }
let swift = try JSONDecoder().decode(GroupModel.self, from: json)
DispatchQueue.main.async {
self.groupModel = swift
print(self.groupModel)
}
}
catch {
print(error)
}
}
.resume()
}
}
public struct GroupModelElement: Codable, Hashable {
public let startYear: Int?
public let name: String?
public let facultyID: String?
public let specialityID: String?
public let groupBr: Int?
public let id: String?
enum CodingKeys: String, CodingKey {
case startYear
case name
case facultyID
case specialityID
case groupBr
case id
}
public init(startYear: Int?, name: String?, facultyID: String?, specialityID: String?, groupBr: Int?, id: String?) {
self.startYear = startYear
self.name = name
self.facultyID = facultyID
self.specialityID = specialityID
self.groupBr = groupBr
self.id = id
}
}
public typealias GroupModel = [GroupModelElement]
It is necessary that only the "name" field from json get into the picker
let group: GroupModelElement
Picker(selection: $session.choiseGroup, label: Text("Выбранная группа")) {
ForEach(0 ..< group.name.count) {
Text(self.group.name[$0])
}
}
An error appears at all in another place that is not related to this code.
The problem is that name
is optional. You must unwrap it in order to make it work.
struct ContentView: View {
var elements:[GroupModelElement] = [
GroupModelElement(startYear: 1990, name: "name1", facultyID: "1", specialityID: "2", groupBr: 3, id: "abc1"),
GroupModelElement(startYear: 1991, name: "name2", facultyID: "10", specialityID: "20", groupBr: 30, id: "abc2"),
GroupModelElement(startYear: 1992, name: "name3", facultyID: "100", specialityID: "200", groupBr: 300, id: "abc3")
]
@State var selectedIndex = 0
var body: some View {
NavigationView {
Form {
Section {
Picker(selection: $selectedIndex, label: Text("elements")) {
ForEach(0 ..< elements.count) {
Text(self.elements[$0].name ?? "unknown")
}
}
}
}.navigationBarTitle("Select your name")
}
}
}
What I can suggest you do in your GroupModelElement
class. Make a computed property for each optional variable as follows:
public struct GroupModelElement: Codable, Hashable {
public let startYear: Int?
public var wrappedStartYear:Int{
startYear ?? -1
}
public let name: String?
public var wrappedName:String{
name ?? "unknown name"
}
//...
Then its much easier to work with optional values and you can call inside of the picker Text(self.elements[$0].wrappedName)
.