2016-12-20 35 views
1

我正在用Swift爲iOS構建一個小部件。主要應用程序的目的是連接到URL新聞提要並獲取最新消息,而小部件只能在Today視圖中的tableView中顯示標題。Json數據沒有顯示在桌面上查看

我已經爲小部件編寫了這個方法來獲取數據來填充表,但由於某種原因沒有顯示。我試圖調試它,但作爲一個小部件,它似乎幾乎是不可能的。

這是cellForRowAt,我連接到feed並嘗試提取數據。有趣的是,主要應用程序使用基本相同的代碼,它的工作原理非常完美。

 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 


     let urlRequest = URLRequest(url: URL(string: "https://newsapi.org/v1/articles?source=techcrunch&sortBy=top&apiKey=c64849bc30eb484fb820b80a136c9b0a")!) 


     let task = URLSession.shared.dataTask(with: urlRequest) { (data,response,error) in 

      do{ 

       let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: AnyObject] 

       if let articlesFromJson = json["articles"] as? [[String: AnyObject]] { 

        if !(error != nil) { 

          var resultArray: NSMutableArray = NSMutableArray() 

          for articlesFromJson in articlesFromJson { 

           if let title = articlesFromJson["title"] as? String{ 
            resultArray.add(title) 

           } 

           let array:NSArray = resultArray.reverseObjectEnumerator().allObjects as NSArray 
           resultArray = array as! NSMutableArray 
           let title:String = resultArray.object(at: indexPath.row) as! String 
           cell.textLabel?.text = title 

          } 
        }    
       } 

       //reload on main thread to speed it up 
       DispatchQueue.main.async { 
       self.tableView.reloadData() 
       } 

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

     return cell 
} 

如果有人能幫助我找出其中的錯誤這將是一個巨大的幫助,從來就一直停留在這個問題上幾天了。謝謝

+2

不要試圖複製你的Objective-C的習慣斯威夫特。例如,不要使用NSArray/NSMutableArray/NSDictionary/NSMutableDictionary,而應使用Swift集合等。並避免強制解包和強制轉換。最後的建議:不要在tableView內部進行網絡和解析。讓tableView使用來自另一個正在下載和分析作業的類的準備好的內容。 – Moritz

+0

謝謝,我已經把所有的網絡連接到了另外一個方法,比如Justin下面提到的方法,我會研究使用集合而不是NSMutableArrays。 – MrRobot0150

回答

3

您希望在cellForRow之外創建網絡請求,然後在完成後重新裝載數據以使tableView重新載入調用cellForRow的單元。

存儲請求之外的數據數組,因此您可以從函數外部引用它。

var resultArray: NSMutableArray = [] 

override func viewDidLoad() { 
    super.viewDidLoad() 
    getData() 
}  

func getData() { 
    let urlRequest = URLRequest(url: URL(string: "https://newsapi.org/v1/articles?source=techcrunch&sortBy=top&apiKey=c64849bc30eb484fb820b80a136c9b0a")!) 

    let task = URLSession.shared.dataTask(with: urlRequest) {[weak self] (data,response,error) in 
    guard let strongSelf = self else { return } 
    do{ 
     let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: AnyObject] 
     if let articlesFromJson = json["articles"] as? [[String: AnyObject]] { 
      if error == nil { 
       for articlesFromJson in articlesFromJson { 
        if let title = articlesFromJson["title"] as? String{ 
         strongSelf.resultArray.add(title) 
        } 
        let array:NSArray = strongSelf.resultArray.reverseObjectEnumerator().allObjects as NSArray 
        strongSelf.resultArray = array as! NSMutableArray 

        DispatchQueue.main.async { 
         strongSelf.tableView.reloadData() 
        } 

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

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 

    let title:String = resultArray.object(at: indexPath.row) as! String 

    cell.textLabel?.text = title 

    return cell 
} 
+0

絕對遵循上面的Eric Aya建議。這個答案的重點在於重組以獲得期望的結果。 – JustinM

+0

感謝您的回答,遺憾的是我嘗試了您的建議,但它並沒有加載數據,它實際上現在說「無法加載」而不是之前的三個空表。 – MrRobot0150

+0

我注意到我在原始答案中犯的一個錯誤。我把它寫成'如果錯誤!=無'{如果沒有錯誤,你會怎麼做}。我將它改爲'if error == nil'。這可能是你爲什麼遇到這個問題。做出這樣的改變,讓我知道如果你仍然有問題 – JustinM

0
checks proper if TableView delegate or datasource proper connected. and check array count before load data in cell 
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 
if (resultArray.count > 0){ 
     let title:String = resultArray.object(at: indexPath.row) as! String 

    cell.textLabel?.text = title 
} 
else 
{ 
    print("Error: resultArray contain nil value ") 
} 


    return cell 
}