使用Alamofire使用JSON数组填充UIPickerView时出现问题|迅速

时间:2019-07-02 18:28:54

标签: ios swift alamofire uipickerview uipickerviewcontroller

基本上,我有一个textField,当按下时需要打开UIPickerView并带有来自JSON的选择

在选择Traceback (most recent call last): File "some.py", line 78, in <module> cursor.executemany(query, [(l,) for l in list1], [(l,) for l in list2]) TypeError: executemany() takes exactly 3 arguments (4 given) 并在Swift中从JSON创建数组时,我曾分别触发过UIPickerView,但是在组合时遇到了一些麻烦。

对于UItextField,我之所以使用Almofire仅仅是因为它简化了流程 JSON是用程序编写的。

我正在使用的JSON看起来像这样:

UIPickerView

到目前为止,Almofire看起来像这样:

[{“model”:”model1”},{“model":"model2”},
{“model":"model3”},{“model":"model4”},{“model":"model5”},{“model":"model6”}]

使用以下代码触发 let url = NSURL(string: "https://www.test.com/test/test") let data = NSData(contentsOf: url! as URL) var tmpValues = try! JSONSerialization.jsonObject(with: data! as Data, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSArray tmpValues = tmpValues as NSArray reloadInputViews() for candidate in tmpValues { if let cdict = candidate as? NSDictionary { //model is the column name in sql/json let model = cdict["model"] self.values.append(model! as AnyObject) } } 来打开UIPickerView:

textField

如何用JSON响应替换硬编码的数组?

1 个答案:

答案 0 :(得分:0)

您使用了很多不良做法

  • 在Swift中请勿使用NSURLNSDataNSArrayNSDictionaryAnyObject(用于JSON数据)。使用本机类型。
  • 请勿在Swift中使用.mutableContainers。该选项没有意义。省略options参数
  • 快速变量名称以小写字母开头。
  • 永远不会从具有同步Data(contentsOf的远程URL加载数据。使用异步URLSession

最有效的解决方案是使用Decodable

解码JSON

在类之外声明结构

struct Model : Decodable {
    let model : String
}

将选择器源声明为变量并采用复数形式

var models = [String]()

viewDidLoad末尾插入

let url = URL(string: "https://www.test.com/test/test")!
let dataTask = URLSession.shared.dataTask(with: url) { data, _, error in
    if let error = error { print(error); return }
    do { 
        let result = try JSONDecoder().decode([Model].self, from: data!)
        self.models = result.map{$0.model}
        DispatchQueue.main.async {
          self.pickerview.reloadAllComponents()
        }
    } catch { print(error) }
}
dataTask.resume()

即使使用JSONSerialization(没有Model结构),它也非常简单

let url = URL(string: "https://www.test.com/test/test")!
let dataTask = URLSession.shared.dataTask(with: url) { data, _, error in
    if let error = error { print(error); return }
    do { 
        if let result = try JSONSerialization.jsonObject(with: data!) as? [[String:String]]
            self.models = result.compactMap{$0["model"]}
            DispatchQueue.main.async {
              self.pickerview.reloadAllComponents()
            }
        }
    } catch { print(error) }
}
dataTask.resume()

选择器数据源方法是

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return models.count
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    return models[row]
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    TextField.text = models[row]
}

Alamofire对于一个简单的GET请求来说是过分的