如何将字典项分别添加到 SwiftUI 列表中

Posted

技术标签:

【中文标题】如何将字典项分别添加到 SwiftUI 列表中【英文标题】:How to add Dictionary items to a SwiftUI List respectively 【发布时间】:2022-01-16 00:25:46 【问题描述】:

我一直在使用 Swift 中的 API,并且想知道 最直接的方法来获取“brandResults”变量及其索引并将其放入使用 SwiftUI 的视图内的列表中。

我是 SwiftUI 新手,因此我们将不胜感激。

查看下面的代码...

我收到如下回复:

    "results": [
        "ASICS",
        "ADIDAS",
        "AIR JORDAN",
        "ALEXANDER MCQUEEN",
        "BAIT",
        "BALENCIAGA",
        "BURBERRY",
        "CHANEL",
        "COMMON PROJECTS",
        "CONVERSE",
        "CROCS",
        "DIADORA",
        "DIOR",
        "GUCCI",
        "JORDAN",
        "LI-NING",
        "LOUIS VUITTON",
        "NEW BALANCE",
        "NIKE",
        "OFF-WHITE",
        "OTHER",
        "PRADA",
        "PUMA",
        "REEBOK",
        "SAINT LAURENT",
        "SAUCONY",
        "UNDER ARMOUR",
        "VANS",
        "VERSACE",
        "YEEZY"
    ]
 

我有这样的结构/模型:

struct Brands:  Codable, Identifiable 
    let id = UUID()
    let results: [String]

我有一个视图模型,它发出请求并转换为字典:

    @Published var brandResults = [Brands]()
  
    func fetch(completion: @escaping ([Brands]) -> ()) 
        
        //Setup the request
        let url = URL(string: "https://v1-.p.rapidapi.com/v1/")
        guard let requestUrl = url else return
        
        var request = URLRequest(url: requestUrl)
        request.httpMethod = "GET"
        request.setValue("x-rapidapi-host", forHTTPHeaderField: "")
        request.allHTTPHeaderFields = ["x-rapidapi-key":""]
        

        //Convert to object
        let task = URLSession.shared.dataTask(with: request) (data, response, error) in
            
        do 
            if let convertedJsonIntoDict = try JSONSerialization.jsonObject(with: data!, options: []) as?
                NSDictionary 
                print("Converted JSON to Dictionary \(convertedJsonIntoDict)")
            
        catch let error as NSError 
            print(error.localizedDescription)
        
        

        //Parse
        guard let data = data else return
        let brandResult = self.parseJSON(data: data)
        
        //Brand results has the list of brands that I need
        guard let brandResults = brandResult else return
        
        task.resume()
    
    
    func parseJSON(data: Data) -> Brands? 
        var returnValue: Brands?
        do 
            returnValue = try JSONDecoder().decode(Brands.self, from: data)  catch 
                print("")
            
        return returnValue
    

【问题讨论】:

您可能会发现both answers to this question 很有帮助。您发布的代码有点过时了。此外,您应该使用guardif let 来解开它,而不是强制解开您的data,否则您可能会崩溃您的应用程序。避免使用!,除非您绝对肯定该变量不会为零。 拥有一个只包含一个字符串数组的结构没有什么意义,当然也没有必要让它可识别,因为你只有一个。因此,要么提取字符串数组并保留它,要么直接解码为 [String: [String]] 并保留字典值。 【参考方案1】:

这是适合您的工作代码:

let stringOfJSON = """

"results": [
    "ASICS",
    "ADIDAS",
    "AIR JORDAN",
    "ALEXANDER MCQUEEN",
    "BAIT",
    "BALENCIAGA",
    "BURBERRY",
    "CHANEL",
    "COMMON PROJECTS",
    "CONVERSE",
    "CROCS",
    "DIADORA",
    "DIOR",
    "GUCCI",
    "JORDAN",
    "LI-NING",
    "LOUIS VUITTON",
    "NEW BALANCE",
    "NIKE",
    "OFF-WHITE",
    "OTHER",
    "PRADA",
    "PUMA",
    "REEBOK",
    "SAINT LAURENT",
    "SAUCONY",
    "UNDER ARMOUR",
    "VANS",
    "VERSACE",
    "YEEZY"
]

"""

struct Brand: Decodable 
    var results: [String]



let dataOfJSON: Data? = stringOfJSON.data(using: String.Encoding.utf8)


func decoderFunction<T: Decodable>(dataOfJSON: Data?, decodedValue: (T) -> Void) 
    
    if let unwrappedDataOfJSON: Data = dataOfJSON 

        do 
            let value: T = try JSONDecoder().decode(T.self, from: unwrappedDataOfJSON)
            decodedValue(value)
         catch 
            print("The Data could not be decoded!")
        
    

用例:

struct ContentView: View 
    
    @State private var array: [String] = [String]()
    
    var body: some View 

        List 
 
            ForEach(array, id:\.self)  item in
                
                Text(item)
                
            

        
        .animation(.default, value: array)

        Button("load JSON") 
            
            decoderFunction(dataOfJSON: dataOfJSON, decodedValue:  (value: Brand) in

                array = value.results

            )
            
        
    

【讨论】:

以上是关于如何将字典项分别添加到 SwiftUI 列表中的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI如何将列表项重构为子视图

如何将页脚视图添加到 SwiftUI 中的列表?

SwiftUI 如何创建一个将项目添加到包含导航链接的列表的按钮

SwiftUI:如何让列表视图中的图像与列表项的操作不同?

如何在swiftUI中将背景颜色添加到列表中

在 ForEach 循环中绑定时,如何阻止 SwiftUI TextField 失去焦点?