2017-02-24 31 views
0

我想用json結果填充UITable。我調用一個函數從服務器獲取json並將結果存儲在NSDictionary中。我想能夠使用這個集合,然後填充一個表格。我遇到了一個問題,但是因爲func numberOfRowsInSection我需要集合的數量,並且由於我的json結果在try/catch內的另一個函數內,我似乎無法返回該值。使用回調從調用數據庫獲取JSON值

這就是我對我在ViewDidLoad()調用函數:

func getSubjects() -> NSDictionary{ 

    let myUrl = NSURL(string: "www.mydomain.com/script.php"); 
    let request = NSMutableURLRequest(url:myUrl as! URL) 
    let user_id = UserDetails[0] 

    request.httpMethod = "POST"; 
    let postString = "user_id=\(user_id)"; 
    request.httpBody = postString.data(using: String.Encoding.utf8); 

    let task = URLSession.shared.dataTask(with: request as URLRequest){ 

     data, response, error in 

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

     var err: NSError? 
     do { 
      let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary 

      if let parseJSON = json { 

       let resultValue: NSDictionary = parseJSON["subjects"] as! NSDictionary 

      } 

     } catch let error as NSError { 
      err = error 
      print(err!); 
     } 
    } 
    task.resume(); 
} 

如果我打印resultValue我得到了我所需要的,在這個例子是:

{ 
1 =  (
    Maths, 
    Lecture 
); 
2 =  (
    Science, 
    Lecture 
); 
3 =  (
    English, 
    Seminar 
); 

}

但令人困惑的是,我該如何去回覆這個值呢?和哪裏?我將如何在桌上執行它?如果我嘗試返回resultValue當我解析JSON我得到的錯誤,這是unexpected non-void return in void function,如果我嘗試在函數的最後返回的值,我得到一個unresolved identifier error

我覺得我錯誤地實現這一點。我已經檢查了很多關於這個的教程,似乎沒有人用POST JSON填充表格,所以我不知道如何去返回值或正確的實現方法。任何幫助將不勝感激!

+1

無關爲什麼你在你的Swift代碼中使用Objective-C類型?使用Swift字典代替'NSDictionary'等。 – rmaddy

+0

注意點,謝謝 – Nouman

回答

0

您遇到的問題是,當您嘗試返回字典時,該字典尚未檢索到。從數據庫中檢索字典後,可以使用異步回調來獲取字典。

func getSubjects(callback: @escaping (NSDictionary)-> Void){ 

let myUrl = NSURL(string: "www.mydomain.com/script.php"); 
let request = NSMutableURLRequest(url:myUrl as! URL) 
let user_id = UserDetails[0] 

request.httpMethod = "POST"; 
let postString = "user_id=\(user_id)"; 
request.httpBody = postString.data(using: String.Encoding.utf8); 

let task = URLSession.shared.dataTask(with: request as URLRequest){ 

    data, response, error in 

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

    var err: NSError? 
    do { 
     let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary 

     if let parseJSON = json { 

      let resultValue: NSDictionary = parseJSON["subjects"] as! NSDictionary 

      callback(resultValue) 

     } 

    } catch let error as NSError { 
     err = error 
     print(err!); 
    } 
} 
task.resume(); 
} 

,然後你會調用該函數像...

getSubjects(callback: {(resultValue)-> Void in 
    print(resultValue) 
    //here you could set your tableView data equal to the values in the dictionary that was just received and then call self.tableView.reloadData to update your table view 
}) 

因此,也許在你的UITableViewController的或viewDidAppear(_:)viewDidLoad()功能,這取決於你的觀點的生命週期中,你會請撥打getSubjects(...),正如我上面所示,然後當調用回調時,您可以調用self.tableView.reloadData(),正如我在函數調用中所述。如果您不確定設置一個tableview中的數據源,以及如何委派那麼你或許應該打開另一個問題是

編輯 在回答您的意見詢問如何使用檢索到的值從您的服務器提供給一個變量你全班,你可以做這樣的事情...

class: ExampleViewController { 
    var resultsDictionary: [Int: [String: String]]? 

    override func viewDidLoad(){ 
     getSubjects(callback: {(resultValue)-> Void in 
      resultsDictionary = resultValue 
     }) 
    } 

    //Use the actual getSubjects function I have already shown you above 
    func getSubjects(){...} 


} 
+0

我很欣賞你花時間回答。我有幾個查詢:(1)'關閉使用非轉義參數可能允許它轉義'所以我現在聲明函數爲'func getSubjects(callback:@escaping(NSDictionary) - > Void){'(2)Your函數調用不能編譯?除非我做錯了什麼。在'ViewDidLoad()'我打電話給你的功能 – Nouman

+0

對不起。你是對的,我錯過了函數參數前面的'@ escaping',我也錯過了函數調用中的''''。我已經編輯了我的代碼上面它現在應該工作 – MikeG

+0

嘿邁克,謝謝。但是,雖然這沉默了'錯誤',我實際上得不到返回值?例如,我想返回字典的計數或填充我的表。我在'ViewDidLoad'中運行這個函數。我返回'resultValue'。在'tableView行數func'或'cellForRowAt'中,我想訪問所述字典的計數並填充表格。我怎麼能夠?我在該函數中運行該函數,並且一旦回調函數被執行,我就會得到Type()沒有下標成員' – Nouman