URLSESSION中不可用的变量

时间:2018-03-31 08:54:52

标签: ios swift uitableview mvvm urlsession

我正在使用mvvm method.my代码,如下所示。

foodModel: -

class foodModel: NSObject {



        var name :String!
        var city :String!
        var imageurl :String!

    init?(dictionary :JSONDictionary) {

        guard let name = dictionary["name"] as? String,
            let imageurl = dictionary["imageurl"] as? String,
            let city = dictionary["city"] as? String else {
                return
        }

        self.name = name
        self.city = city
        self.imageurl = imageurl

}
}

foodDataSourceModel: -

class foodDataSourceModel: NSObject {


    var dataListArray:Array<foodModel>? = []


    init(array :Array<[String:Any]>?) {
        super.init()
        var newArray:Array<[String:Any]> = []
        if array == nil{

            newArray = self.getJsonDataStored1()
        }
        else{
            newArray = array!

        }

        var datalist:Array<foodModel> = []
        for dict in newArray{

            let model = foodModel(dictionary: dict)

            datalist.append(model!)
        }
        self.dataListArray = datalist
    }



}

typealias dummyDataSource1 = foodDataSourceModel
extension dummyDataSource1{

    func getJsonDataStored1() ->Array<Dictionary<String,String>>{

        let jsonArray = [["name":"Anjapar","imageurl":"","city":"india"],["name":"Anjapar","imageurl":"","city":"india"]] as Array<Dictionary<String,String>>

        return jsonArray
    }




}

foodViewModel: -

class foodViewModel: NSObject {






    var datasourceModel:foodDataSourceModel

    init(withdatasource  newDatasourceModel:foodDataSourceModel) {
        datasourceModel = newDatasourceModel
    }


    func datafordisplay(atindex index: Int) -> foodModel {
        return  datasourceModel.dataListArray![index]

    }


   func numberOfItemsInSection(section:Int) -> Int {

       return (datasourceModel.dataListArray?.count)!
   }


    func loadData(){


        loadFromWebserviceData { (newDataSourceModel) in

            self.datasourceModel = newDataSourceModel!
        }
    }

    func loadFromWebserviceData(completion :@escaping (foodDataSourceModel?) -> ()){


        let url = URL(string :"http://example.com")!

        URLSession.shared.dataTask(with: url) { data, _, _ in

            if let data = data {

                let json = try! JSONSerialization.jsonObject(with: data, options: [])
                //let dictionaries = json as! [JSONDictionary]

                let array = json as! Array<[String:Any]>
                let newDataSource:foodDataSourceModel =  foodDataSourceModel(array: array)
                //                DispatchQueue.main.async {
                //
                //                }
                completion(newDataSource)
            }

            }.resume()

    }

}

foodViewController: -

@IBOutlet private weak var tableView: UITableView!


    private var foodViewModel :foodViewModel!

    init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?, withViewModel viewModel:foodViewModel) {

        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)

        foodViewModel  = viewModel
    }


    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }



    override func viewDidLoad() {
        super.viewDidLoad()

     //   tableView.register(UINib(nibName: "foodCell", bundle: nil), forCellReuseIdentifier: "cell")

        foodViewModel.loadData()

        self.tableView .reloadData()

        // Do any additional setup after loading the view.
    }

 //  func numberOfSections(in tableView: UITableView) -> Int {
     //   return restaurtantViewModel.numberOfItemsInSection(section: Int)
   // }



    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {


   let cell:UITableViewCell = self.tableView.dequeueReusableCell(withIdentifier: "cell")! as! foodCell


     //cell.setRestaurtantData(restaurtant: foodModel)
        cell.textLabel?.text = "rtyuiop"
    //

             return cell
   }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    /*

    }
    */

}

玻璃纸: -

class foodCell: UITableViewCell {

    @IBOutlet weak var name: UILabel!
    @IBOutlet weak var city: UILabel!


    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    func setRestaurtantData(restaurtant:foodModel)
    {
        self.name.text = restaurtant.name
        self.city.text = restaurtant.city

    }


    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

此处输出未获取。我需要在tableview中显示值。显示错误,因为无法从dataSource获取单元格

{
    "query": "sandwich",
    "results_count": 12,
    "page": 1,
    "results": [
        {
            "name": "Caffè Macs",
            "coordinates": {
                "lat": 37.330576,
                "lng": -122.029739
            },
            "meals": ["breakfast", "lunch", "dinner"]
        },
        ...
    ]
}

这是模式,所以从这里我需要得到的值为&#34; name&#34;,&#34; lng&#34;和&#34; lat&#34;。 从Json加载数据时存在一些问题。在urlsession任务中 - 显示为变量不可用。请检查。如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

请更新您的viewDidLoad()。您必须设置tableview的委托和数据源。

首先在课堂上设置: -

class yourClass: UIViewController,UITableViewDelegate , UITableViewDataSource

现在

override func viewDidLoad() {
    super.viewDidLoad()

 //   tableView.register(UINib(nibName: "foodCell", bundle: nil), forCellReuseIdentifier: "cell")

    foodViewModel.loadData()
    self.tableView .delegate = self
    self.tableview.dataSource = self
    self.tableView .reloadData()

答案 1 :(得分:0)

从Web服务获取数据时,通常以异步方式完成。在viewDidLoad方法中,您将在开始获取数据的调用之后立即更新表视图。

override func viewDidLoad() {
    ...
    // Start fetching the data
    foodViewModel.loadData()
    // Reloading the table view even though the data might not be ready
    self.tableView.reloadData()
    ...
}

您可以通过将回调传递到loadData中的foodViewModel功能来解决此问题:

func loadData(completion: (() -> ()) {
    loadFromWebserviceData { (newDataSourceModel) in
        self.datasourceModel = newDataSourceModel!
        completion()
    }
}

然后在foodViewController中,您将等待更新表格视图,直到数据源准备好显示为止:

override func viewDidLoad() {
    ...
    foodViewModel.loadData {
        self.tableView.reloadData()
    }        
    ...
}

虽然上面的代码应该有效,但这只是为了突出您目前面临的问题,因此尽可能简单。