2016-04-14 6 views
2

私はユーザー入力(8-10桁の数字)を取り込むアプリケーションを開発しています。これをphpスクリプトにPOSTしてデータベースに問い合わせ、結果を返しますJSON。可能な競合状態ですか?スウィフト2 iOSアプリはランダムにfunc tableViewを呼び出さない(tableView

私はJSONを解析し、配列に値を保存し、その後のtableViewにそれらの配列を読み込む。

をユーザが(NAVコントローラを介して)新しいビューにセグエを導入し、検索を、ヒット、 JSONデータがviewDidLoad()内のテーブルビューに送信されます。JSONを解析して配列に保存し、func tableViewで配列の値を行に読み込んだ後、セルを返します。

私の問題は、配列が常に塗りつぶされても、空のテーブルビューを取得した後、再度クリックして検索を試しても、データが行にロードされないことがあり、停止します。

私は、テーブルビュー用にデリゲートとデータソースをクリックしています。私はplistにHTTP例外を追加しました。

これは私の初めてのプロジェクトですので、どんなヒントもありがとうございます。私のコード配置が競合状態を引き起こす問題かもしれないと思われますか?私はviewDidLoad()関数でJSONを解析するので?

コード:

import UIKit 

class ResultsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 


@IBOutlet weak var tableView: UITableView! 

var ccnit = "" 
var cunsArray : [String] = [] 
var accountsArray : [String] = [] 
var statusArray : [String] = [] 
var typesArray : [String] = [] 
var assignedArray : [String] = [] 



override func viewDidLoad() { 
    super.viewDidLoad() 


    //establish connection 
    let url = NSURL(string: "http:IPADDRESS/App/query.php") 
    let request = NSMutableURLRequest(URL:url!) 
    request.HTTPMethod = "POST" 

    request.HTTPBody = ccnit.dataUsingEncoding(NSUTF8StringEncoding) 

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

     if error != nil { 
      print("error=\(error)") 
      return 
     } 
     //print("response = \(response)") 

     // let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)! 
     //print("responseString = \(responseString)") 



     //parse JSON 

     do { 

      let jsonArray = try (NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers)) as! NSArray 

      //loop through json array and take out strings 
      var counter = 0 
      while counter < jsonArray.count{ 
       let cun = jsonArray[counter]["ticket_no"] as? String 
       self.cunsArray.append(cun!) 

       let account = jsonArray[counter]["accountname"] as? String 
       self.accountsArray.append(account!)    

       let status = jsonArray[counter]["status"] as? String 
       self.statusArray.append(status!) 

       let type = jsonArray[counter]["category"] as? String 
       self.typesArray.append(type!) 

       let assigned_to = jsonArray[counter]["assigned_to"] as? String 
       self.assignedArray.append(assigned_to!) 

       counter = counter + 1 
      } 

      if (self.cunsArray.count > 0) 
      { 
       print("cunsArray has \(self.cunsArray.count) items") 
      } 
      if (self.accountsArray.count > 0) 
      { 
       print("accountsArray has \(self.accountsArray.count) items") 
      } 

      print("Finished populating arrays") 
      self.tableView.delegate = self 
      self.tableView.dataSource = self 

     } catch let err { 
      print(err) 
     } 

    } 
    task.resume() 


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

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

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return cunsArray.count 
} 

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    var cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomCell 
    //print("*****inside tableview func") 
    print("returning cells") 
    // cell.account.text = "" 
    cell.cun.text = cunsArray[indexPath.row] 
    cell.account.text = accountsArray[indexPath.row] 
    cell.status.text = statusArray[indexPath.row] 
    cell.type.text = typesArray[indexPath.row] 
    cell.assigned_to.text = assignedArray[indexPath.row] 

    return cell 
} 
} 
+0

誰も助けることができないをロードした後にメインスレッドにreloadData()を呼び出す必要関連するコードを投稿しない場合は、コードを修正します。 – rmaddy

+0

コードが追加されました。ありがとうございます。 – Sam

答えて

3

これは、バックグラウンドスレッドでの問題のようになります。

let task = NSURLSession.sharedSession().dataTaskWithRequest(request) 

が内部でバックグラウンドスレッドである可能性があり、その後、あなたが同じスレッドでテーブルのデータソース/デリゲートを設定しています。

てみスワッピング:

dispatch_async(dispatch_get_main_queue(), {() -> Void in 
     self.tableView.delegate = self 
     self.tableView.dataSource = self 
}) 

 self.tableView.delegate = self 
     self.tableView.dataSource = self 

EDIT:

Jeremy Herreroは、正しい解決策は次のようになりそうだとすれば、データソース/デリゲートがストーリーボードレベルで追加された可能性が述べたように:

dispatch_async(dispatch_get_main _queue()、{() - > self.tableView.reloadData() のボイド})

+0

Fantastic!ありがとう@ SeanLintern88。 getData()内のdispatch_async(dispatch_get_main_queue()、{() - > Void in self.tableView.reloadData()})を追加し、デリゲート/データソースの呼び出しを取り除きました。 – Sam

1

あなたがのviewDidLoadにそんなに詰めるべきではありません。また、データを取得したらreloadData()を呼び出す必要があります。そうしないと、tableViewは更新されません。 reloadData()を呼び出す必要がないのは、tableViewの作成時にデータが利用可能なときだけです。

将来は、コードをきれいに整えてください。それは何よりもあなたを助けます。厄介なコードは、厄介な結果と無限の将来の頭痛につながります。

override func viewDidLoad() { 
    super.viewDidLoad() 

    self.tableView.delegate = self 
    self.tableView.dataSource = self 

    getData() 
} 

func getData() { 
    let url = NSURL(string: "http:IPADDRESS/App/query.php") 
    let request = NSMutableURLRequest(URL:url!) 
    request.HTTPMethod = "POST" 

    request.HTTPBody = ccnit.dataUsingEncoding(NSUTF8StringEncoding) 

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

     if error != nil { 
      print("error=\(error)") 
      return 
     } 

     do { 
      let jsonArray = try (NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers)) as! NSArray 
      var counter = 0 
      var accounts = [] 
      while counter < jsonArray.count { 
       let cun = jsonArray[counter]["ticket_no"] as? String 
       self.cunsArray.append(cun!) 

       let account = jsonArray[counter]["accountname"] as? String 
       self.accountsArray.append(account!) 

       let status = jsonArray[counter]["status"] as? String 
       self.statusArray.append(status!) 

       let type = jsonArray[counter]["category"] as? String 
       self.typesArray.append(type!) 

       let assigned_to = jsonArray[counter]["assigned_to"] as? String 
       self.assignedArray.append(assigned_to!) 

       counter = counter + 1 
      } 

      if (self.cunsArray.count > 0) { 
       print("cunsArray has \(self.cunsArray.count) items") 
      } 
      if (self.accountsArray.count > 0) { 
       print("accountsArray has \(self.accountsArray.count) items") 
      } 

      tableView.reloadData() 

     } catch let err { 
      print(err) 
     } 

    } 
    task.resume() 
} 
+0

技術的には、reloadData()を呼び出す必要はありません。自動的にテーブルをリロードするデータを取得した後、デリゲート/データソースを設定しています。 – SeanLintern88

+0

興味深い。私は前にそれを試みたことはありません。ストーリーボードにデリゲートとデータソースを接続したように聞こえました。コードが冗長だった場合、それが影響を与えるかどうか分かりませんか? –

+0

もし彼がストーリーボードにもそれを設定していれば本当にreloadData()は彼のソリューションになりますが、これはスレッドの問題だと思います。 – SeanLintern88

0

、データ

... 
print("Finished populating arrays") 
dispatch_async(dispatch_get_main_queue(), { 
    self.tableView.reloadData() 
}); 
... 
関連する問題