2017-02-09 25 views
0

我的應用程序有一個用戶帳戶頁面,它使用tableview返回時間軸類型的詳細信息。我希望在表頭的頂部有實際的登錄用戶詳細信息。無法填充自定義表格標題swift 3:索引超出範圍

這是在useraccountViewController上處理的。我在viewDidLoad中添加了一個叫做getUserAndTimeLine()的函數,它使得我的web服務的2個api調用獲取我登錄用戶的詳細信息(這個視圖控制器是通過登錄頁面的segue打開的)。

我也有2個結構,一個用於loggedUser,另一個用於定義我期望從API調用接收的userPost。我也有基於結構的用戶和帖子的數組。

的getUserAndTimeLine()的代碼如下:

//creates api url to get user 
    let url = URL(string: "myapi.url/getuser?uid=" + user) 
    //httpget sent to the api and listens for response 
    URLSession.shared.dataTask(with:url!) { (data, response, error) in 
     if error != nil { 
      print(error as Any) 
     } 
     else { 
      do{ 
       //parses the json data 
       let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! NSDictionary 

       //get the user data 
       let thisUser = parsedData["userName"] as? String 
       let thisUserImage = parsedData["userAvatar"] as? String 

       let thisLoggedUser = loggedUser(userAvatar: thisUserImage, userName: thisUser) 

       self.arrayOfLoggedUser.append(thisLoggedUser) 

      } 
      catch{ 
       print("parse error") 
      } 
     } 
     }.resume() 


    //creates api url to get user TL 
    let tlurl = URL(string: "myapi.url?uid=" + user) 
    //httpget sent to the api and listens for response 
    URLSession.shared.dataTask(with:tlurl!) { (data, response, error) in 
     if error != nil { 
      print(error as Any) 
     } 
     else { 
      do{ 
       //parses the json data 
       let parsedTLData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:AnyObject] 

       guard let posts = parsedTLData["timeline"] as? [[String:AnyObject]] else {return} 
       for post in posts { 
        let thisPost = postData(postText: post["postText"] as! String, postURL: post["postURL"] as! String, postImageURL: post["postImage"] as! String, 
         postDomainName: post["postSource"] as! String, 
         postDomainLink: post["postDomainLink"] as! String, 
         postPoster: post["postPoster"] as! String, 
         postPosterAvatar: post["postPosterAvatar"] as! String, 
         postDate: post["postCreateDate"] as! String) 

        self.arrayOfPostData.append(thisPost) 

        self.tableView.reloadData()     } 
      } 
      catch{ 
       print("parse error") 
      } 
     } 
     }.resume() 

在單個細胞,我能夠成功通過,以填充我的tableview(時間軸)與arrayOfPostData數據:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

let cell = Bundle.main.loadNibNamed("postTimeLineCell", owner: self, options: nil)?.first as! postTimeLineCell 

     cell.postImage.sd_setImage(with: URL(string: arrayOfPostData[indexPath.row].postImageURL)) 
     cell.postText.setTitle(arrayOfPost[indexPath.row].postText, for:.normal) 

     cell.postDate.text = arrayOfPostData[indexPath.row].postDate 

     // etc. 

     return cell 
} 

但我不能返回標題:

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 

    let loggedUserHeader = Bundle.main.loadNibNamed("userHeader", owner: self, options: nil)?.first as! userHeader 

    loggedUserHeader.userName.text = arrayOfLoggedUser[section].userName 

    return loggedUserHeader 
} 

因爲我收到錯誤:EXC_BAD_INSTRUCTION(代碼= EXC_1386_INVOP,子代碼= 0x0)它在輸出是「致命錯誤:索引超出範圍」

任何人都可以幫助,因爲我相當卡住!

+1

推測,'arrayOfGrabbUser'不具備'[第一個條目]' - 但是你沒有包含任何有關如何定義數組的參考... – Russell

+0

抱歉 - 它應該是arrayOfLoggedUser。我如何檢查是否有一個部分?我已經在tableview的number的部分中設置了1的值,並且在arrayPostData.count的部分中設置了行的數量 – Dave

+0

當你進入'viewForHeaderInSection'時,你需要準確地檢查'arrayOfLoggedUser'中的內容 - 設置一個斷點並看看 – Russell

回答

0

異步數據幾乎總是問題。

用戶數組將在API調用完成後填充 - 但在此之前您將刷新tableView。

最簡單的辦法是把在一個viewForHeaderInSection檢查,如果array.count <部分索引那麼就什麼也沒有返回,或默認值

+0

我明白你在說什麼(數據在加載標題時不存在),但我不明白爲什麼對於單元格的相同方法(使api調用,發送到視圖)確實工作或我如何讓標題以相同的方式工作。沒有返回或默認值不起作用:它需要顯示登錄用戶的詳細信息。 – Dave

+0

所以我最終在用戶帳戶的segue之前在登錄頁面上調用用戶api,並將它們存儲在全局變量中,所以當我來到用戶頁面時,我能夠從頭部獲取詳細信息。所以雖然我仍然不明白爲什麼它爲表格單元格而不是頭部起作用,我解決了這個問題。 – Dave