Swiftui 2.0 如何访问 api 数组中的值并对其进行操作

Swiftui 2.0 how can I access values in an api array and manipulate them

我是 swift 和 swift 的新手。我有一个 api 调用 returns 数组,现在我正在获取数据并将其显示在列表中。我想要做的是访问数组中的各个字段并在它显示在列表中之前更改它们。这是我的代码。在 class MainViewModel 中,我从 API 得到结果,我想在那里访问 fullname 字符串,所以我可以全部大写。任何帮助都会很棒

struct MainModel: Decodable,Identifiable {
    var id: Int?
    var fullname: String?
    var time: String?
}

class MainViewModel: ObservableObject {
    func MainViewRequest(completion: @escaping([MainModel]) -> ())
    {
        let parameter = "id=1"
        
        let request = RequestObject(AddToken: true, Url: "Home/MainView", Parameter: parameter)
        URLSession.shared.dataTask(with: request) { data, response, error in
            guard let Data = data else { return }
            do {
                let value = try JSONDecoder().decode(Array<MainModel>.self, from: Data)
                DispatchQueue.main.async {
                    // how can I get FullName property here
                    completion(value)
                }

            }
            catch {
                print(error)
            }
        }.resume()
        
    }
}


struct MainView: View {
    @StateObject var mainVM = MainViewModel()
   @State var model: [MainModel] = []
    var body: some View {
    
        List {
            ForEach(model) { value in
                Text("\(value.fullname ??  "")")
                Spacer()
                Text("\(value.time ??  "")")
            }
        }.onAppear(){
         mainVM.MainViewRequest() { data in
             model = data
         }
            }
        }
    }

有几种方法可以实现您的目标。

使用map转换值

任何时候你想要转换值集合 map 都值得考虑。 您提供的闭包会在集合的每个元素上调用,您可以 return 转换后的值(它甚至可以是不同的类型)。为了简单起见,我将把东西打包回您的 MainModel 对象之一。

这就是它的样子:

let values = try JSONDecoder().decode(Array<MainModel>.self, from: Data)
// Process the values off the main thread
let modifiedValues = values.map { value in
    MainModel(id: value.id,
              fullname: value.fullname?.uppercased(),
              time: value.time
    )}
DispatchQueue.main.async {
    // Use the processed values in the main thread
    completion(modifiedValues)
}

但这可能不是理想的做事方式。我这样说的原因是因为将某些东西转换为大写不是可逆操作,所以, 在经历了所有下载数据的麻烦之后,你就扔掉了 信息。

在视图中变换

如果你只是为了演示目的而将其大写,你可能会更好 在你看来停止这样做:

ForEach(model) { value in
    Text("\(value.fullname?.uppercased() ??  "")")
    Spacer()
    Text("\(value.time ??  "")")
}

在扩展中计算 属性

这个选项是我在自己的代码中经常使用的选项。在扩展中,我添加了计算显示和格式相关的计算属性。

extension MainModel {
    var displayFullName: String { fullname?.uppercased() ?? "" }
}

然后您修改视图代码的循环如下:

ForEach(model) { value in
    Text("\(value.displayFullName)")
    Spacer()
    Text("\(value.time ??  "")")
}

我喜欢这种方法,因为原始的外壳版本仍然可用,您没有丢失任何信息。您可以在整个代码中的任何需要的地方使用扩展...它会整理视图代码。