[swift]获得价值内 NSURLSession

标签: Xcode ios Swift
发布时间: 2017/3/6 23:30:15
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我的代码不起作用,你知道吗为什么?我想要向我的差额显示一些数据,从请求的 HTTP

class contactView : UITableViewController{
    var values: NSMutableArray!

@IBOutlet var tbview: UITableView!

override func viewDidLoad() {

    if(signed != 1){
        self.navigationItem.title = ""
    }else{

        let outbtn = UIBarButtonItem(title: "Sign out", style: .Plain, target: self, action: #selector(contactView.out_action))
        navigationItem.leftBarButtonItem = outbtn

        let reloadData = UIBarButtonItem(title: "Reload", style: .Plain, target: self, action: #selector(contactView.loadData))
        navigationItem.rightBarButtonItem = reloadData

        //Check Connection

        if(reachability.isConnectedToNetwork() == true) {
            loadData()
        }else{
            let alert = UIAlertController(title: "Error Connection", message: "Not Internet Connection", preferredStyle: .ActionSheet)
            let alertAct = UIAlertAction(title: "I'll connect later !", style: .Destructive){
                (actions) -> Void in
            }
            alert.addAction(alertAct)
            self.presentViewController(alert, animated: true, completion: nil)
        }
    }

}
func loadData(){
    let url = NSURL(string: url_friends)

    let to_post = "user=iam&pin=101218"
    let request = NSMutableURLRequest(URL: url!)
    request.HTTPMethod = "POST"
    request.HTTPBody = to_post.dataUsingEncoding(NSUTF8StringEncoding)

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request){
        (let data,let response,let error) -> Void in

        dispatch_async(dispatch_get_main_queue(),{
            do{
                self.values = try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSMutableArray
                print(self.values)

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

我想要在我的表中显示变量的"值"数据但保持发生错误,说它是零的时候叫我表函数 cellForRowAtIndexPath

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

  let cell = tableView.dequeueReusableCellWithIdentifier("cellidentity") as UITableViewCell!
  let mainData = values[indexpath.row] as! String
  let x = cell.viewWithTag(2) as! UILabel

  if(signed != 1){
      print("No people")
  }else{
      let x = cell.viewWithTag(2) as! UILabel
      x.text = mainData["name"]

  }
  return cell
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let x : Int
    if(reachability.signed() != 1){
        x = 1
    }else{
        x = values.count        
    }
    return x
}

解决方法 1:

是的第一次加载表,它将是 nildataTaskWithRequest完成块具有显式调用 self.tableview.reloadData() ,告诉要更新本身既然网络请求已完成的表。请记住, dataTaskWithRequest 运行异步,意味着它完成已经给出了表。所以你要告诉要重新加载它本身的表 (并因此调用 UITableViewDataSource 方法再一次)。

因此,您可能希望类似︰

let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {  data, response, error in
    guard data != nil && error == nil else {
        print(error)
        return
    }

    do {
        if let values = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSMutableArray {
            dispatch_async(dispatch_get_main_queue()) {
                self.value = values
                print(values)
                self.tableview.reloadData()
            }
        } 
    } catch let parseError {
        print(parseError)
        return
    }
}
task.resume()

注意之前做强迫展开的, datadata! ,我第一次保护以确保它不是 nil 。从来不使用 ! 除非你已经知道它不可能是 nil


为什么在你 UITableView 方法失败他们被称为第一次,这是因为他们依靠 reachability.signed()signed 。但真正的问题是是否 valuesnil 或不。

所以,也许︰

var values: NSMutableArray?    // make this a standard optional, not an implicitly unwrapped one

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

    let cell = tableView.dequeueReusableCellWithIdentifier("cellidentity") as UITableViewCell!
    let x = cell.viewWithTag(2) as! UILabel    // btw, using `UITableViewCell` subclasses are more elegant than using cryptic `tag` numbers

    if let mainData = values?[indexPath.row] as? [String: String] {
        x.text = mainData["name"]
    } else {
        print("No people")
        x.text = "(retrieving data)"  // perhaps you want to tell the user that the request is in progress
    }
    return cell
}

// if `values` is `nil`, return `1`, otherwise returns `values.count`

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return values?.count ?? 1
}

您的代码配置为返回一个单元格,如果没有可用的数据,所以在这里,已经重复那就好了,但一般我返回零行,如果没有数据。如果你做到这一点,它简化了 cellForRowAtIndexPath 甚至更多,就是它没有,甚至担心"无数据"状态。但这完全取决于你。

现在,我已经取得上述一些假设 (例如, mainData 真是一本字典,既然你下标它与一个字符串 "name" )。但比这些小细节同样重要的是大图片,即那个应严格避免使用 ! 强迫展开或使用隐式拆开包装件,除非你知道绝对肯定地底层可选绝不能 nil

官方微信
官方QQ群
31647020