I am trying to display a string in a List in Swift but the next error appears:
Cannot convert value of type '[String?]' to expected argument type 'LocalizedStringKey'
struct EmergencyView: View {
// For loadData Function
@StateObject private var viewModel = EmergencyViewModel()
// Contains the info of the JSON
@State var emergencies: [EmergencyNumberModel] = []
var body: some View {
List(emergencies) { emergency in
if emergency.country.name.isEmpty || emergency.police.all.isEmpty {
Text("No Country or Phone Number")
} else {
let telephone = emergency.police.all
Label(telephone, systemImage: "phone.fill") // <<<<<< ERROR here
.font(.headline)
}
}
.onAppear {
if let emer = viewModel.loadData(from: "emergency") {
emergencies = emer
}
}
}
}
The type [String?] comes from a struct that was generated from a JSON file:
// MARK: - EmergencyNumberModelElement
struct EmergencyNumberModel: Codable, Identifiable {
let id = UUID()
let country: Country
let ambulance: Ambulance
let fire: Fire
let police: Ambulance
enum CodingKeys: String, CodingKey {
case country = "Country"
case ambulance = "Ambulance"
case fire = "Fire"
case police = "Police"
}
}
// MARK: - Ambulance
struct Ambulance: Codable {
let all: [String?] // <<<<< Here is the type
let gsm: [String]?
enum CodingKeys: String, CodingKey {
case all = "All"
case gsm = "GSM"
}
}
I tried with:
guard let telephone = emergency.police.all // Error: "Type of expression is ambiguous without more context"
And with Force unwrapping (That didn't go well)
Is there a way to cast the variable?
Sources:
CodePudding user response:
Your error stem from having [String?]
in the Label, where a Label takes just String/LocalizedStringKey
.
To fix your error you could do this:
if let telephone = emergency.police.all.compactMap{$0}, let firstNumber = telephone.first {
Label(firstNumber, systemImage: "phone.fill").font(.headline)
}
If you want all numbers to be displayed, use this:
let telephone = emergency.police.all.compactMap{$0}
ForEach(telephone, id: \.self) { phone in
Label(phone, systemImage: "phone.fill").font(.headline)
}