2017-02-09 2 views
0

Мое приложение имеет страницу учетной записи пользователя, которая использует табличное представление, чтобы вернуть деталь времени в виде временной шкалы. Я бы хотел, чтобы фактическая введенная пользователем деталь вверху в заголовке таблицы.не может заполнить пользовательский заголовок tableview swift 3: индекс за пределами диапазона

Это обрабатывается на useraccountViewController. Я добавил функцию viewDidLoad с именем getUserAndTimeLine(), которая делает 2 api-звонки на мой веб-сервис, чтобы получить информацию для моего зарегистрированного пользователя (этот контроллер открывается с помощью сеанса со страницы входа).

У меня также есть 2 structs one для loggedUser и один для userPost, который определяет, что я ожидаю получить от вызовов API. У меня также есть массивы для пользователя и сообщения на основе структур.

Код 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 (Timeline) с данными 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, subcode = 0x0), который на выходе является «фатальной ошибкой: индекс за пределами диапазона»

Может ли кто-нибудь помочь, поскольку я скорее застрял!

+1

предположительно, 'arrayOfGrabbUser' не имеет запись для' [раздел ] '- но вы не указали никаких ссылок на то, как определяется массив ... – Russell

+0

извините - это должен быть массивOfLoggedUser. Как проверить, есть ли для этого раздел? Я определенно установил в numberofsections для tableview значение 1, а количество строк в секции - arrayPostData.count – Dave

+0

. Вы должны точно проверить, что находится в 'arrayOfLoggedUser', когда вы попадаете в' viewForHeaderInSection' - установить точку останова и посмотрите – Russell

ответ

0

Асинхронные данные почти всегда являются проблемой.

Массив пользователя будет заполнен после завершения вызова API, но перед этим вы будете обновлять таблицуView.

Простейшая вещь, чтобы поставить галочку в viewForHeaderInSection и если индекс раздела array.count < затем просто вернуться ни с чем, или значение по умолчанию

+0

Я понимаю, что вы говорите (что данные не существуют при загрузке заголовка), но я не понимаю, почему один и тот же подход для ячеек (сделать вызов api, отправить на просмотр) работает или как я могу заставить заголовок работать таким же образом. не возвращая ничего, или значение по умолчанию не будет работать: оно должно показать зарегистрированные данные пользователя. – Dave

+0

Итак, я закончил тем, что вызывал пользователя api на странице входа в систему до segue в учетную запись пользователя и сохранял их в глобальных переменных, поэтому, когда я пришел на страницу пользователя, я смог получить детали из заголовка для этого. поэтому, хотя я до сих пор не понимаю, почему он работал для ячеек таблицы, а не заголовка, я обошел эту проблему. – Dave