无法显示数据异步swift2,tableView在检索数据之前刷新

时间:2016-06-09 09:53:00

标签: ios swift uitableview swift2

我正在尝试使用自定义tableview单元格加载tableview。

这是我的tableview控制器的viewDidLoad()看起来的样子:

override func viewDidLoad(){
        super.viewDidLoad()

        self.tableView?.delegate = self;
        self.tableView?.dataSource = self;

        //Clean array data
        TableData.removeAll()

        //Retrieve data asynchronously
        let call = webApi()
        call.retrieveAllShops()

        doTableRefresh()

    }

TableData是一个全局数组,我将所有json数据放入其中。 所以我先把它清理干净再填充它。 我填写call.retrieveAllShops()

private func retrieveAllShops(){
        let request = NSMutableURLRequest(URL: NSURL(string: userApiCallUrl)!)

        request.HTTPMethod = "POST"

        request.HTTPBody = postParam.dataUsingEncoding(NSUTF8StringEncoding)
        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
            guard error == nil && data != nil else {
                // check for fundamental networking error
                print("error=\(error)")
                return
            }
            if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 {
                // check for http errors
                print("statusCode should be 200, but is \(httpStatus.statusCode)")
                print("response = \(response)")
            }


            let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)

            let json: AnyObject? = responseString!.parseJSONString

            self.parseJson((json as! NSMutableArray))

        }

        task.resume()
    }

最后在parseJson()中填写全局数组TableData:

private func parseJson(json : NSMutableArray){

for j in json {
//Create main value
            guard let value = j.valueForKey("value")?.valueForKey("value")! else{
                continue
            }

//Get name
            guard let Name : String = (value.valueForKey("Name")?.valueForKey("en") as? String) else {
                continue
            }
TableData.append(Name)
}
}

然后回到tableView控制器,我调用doTableRefresh()

private func doTableRefresh(){
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            self.tableView.reloadData()
            return
        })
    }

最后我有这两种方法。

    func tableView(tableView:UITableView, numberOfRowsInSection section:Int) -> Int
    {
        if(searchActive) {
            return filtered.count
        }
        return TableData.count
    }

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

        let cell : shopsTableViewCell = tableView.dequeueReusableCellWithIdentifier("shopCell", forIndexPath: indexPath) as! shopsTableViewCell
        if(searchActive){
            cell.textLabel?.text = filtered[indexPath.row]
        } else {
            cell.textLabel?.text = TableData[indexPath.row]
        }

cell.shopTitle = TableData[indexPath.row]
return cell
}

现在如果我在方法return TableData.count的{​​{1}}行中设置断点,它总是在异步调用加载全局数组之前首先进入此处,因此它返回0并且我的tableview单元格根本不显示。

有人可以告诉我,我做错了吗?

编辑:

在我的tableView(tableView:UITableView, numberOfRowsInSection section:Int)方法中做了一些更改之后:

viewDidLoad

在我的 override func viewDidLoad(){ super.viewDidLoad() self.tableView?.delegate = self; self.tableView?.dataSource = self; //Clean array data TableData.removeAll() //Retrieve data asynchronously let call = webApi() call.retrieveAllShops({ data in self.doTableRefresh() }) } 方法中:

func retrieveAllShops(success:SuccessClosure){     setGetShopsListUrl()

retrieveAllShops()

}

我的应用程序崩溃了:

enter image description here

这是我收到的错误消息:

call()

success(data: "sucess")

可能看起来没有连接插座所以,我删除了旧连接并做了一个新连接,但结果相同(旧连接没问题):

enter image description here

enter image description here

enter image description here

enter image description here

2 个答案:

答案 0 :(得分:0)

在json解析后调用doTableRefresh

    let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)

    let json: AnyObject? = responseString!.parseJSONString

    self.parseJson((json as! NSMutableArray))

    self.doTableRefresh()
    ...

被修改

//全局创建

public typealias SuccessClosure = (data: String?) -> (Void)

并在您的班级中调用call.retrieveAllShops() 将SuccessClosure作为参数传递

 call.retrieveAllShops({
  data in 
 self.doTableRefresh()
 //  refresh tableview here

})

和retrieveAllShops方法

private func retrieveAllShops(success: SuccessClosure) {

...
 self.parseJson((json as! NSMutableArray))
success("sucess") // you can pass data according to your requirment here

}

答案 1 :(得分:0)

你没有做错任何事。这就是异步网络的本质。

您唯一认为缺少的是,在retrieveAllStops()方法的完成时段结束时,您需要添加对doTableRefresh()的通话(正好在self.parseJason()的调用下

在viewDidLoad中调用doTableRefresh()没有任何帮助,所以你也可以删除该调用。 (表视图数组数据尚不可用。)

编辑:

如果在另一个类中定义了表视图,则添加方法dataIsAvailable并调用它。 (或者@SahilBeri说,在retrieveAllStops()方法中添加一个闭包,并在下载和解析数据后调用闭包。)

如果您决定调用dataIsAvailable方法,那么您可能希望将一个委托添加到JSON提取类,并将dataIsAvailable()方法作为委托方法。