2014-09-19 2 views
1

Я начинаю с Swift и Xcode, и я пытаюсь выполнить fetch данные API из TMDb API и отобразить его в UITableView. я получаю следующее сообщение об ошибке:reloadData() using Swift

fatal error: unexpectedly found nil while unwrapping an Optional value 

Выделенная линия:

self.nyheterTableView.reloadData() 

И мой полный код для ViewController является:

import UIKit 

class nyheterViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, APIControllerProtocol { 

    @IBOutlet weak var nyheterTableView: UITableView! 

    var searchResultsData: NSArray = [] 
    var api: APIController = APIController() 

    func JSONAPIResults(results: NSArray) { 
     dispatch_async(dispatch_get_main_queue(), { 
      self.searchResultsData = results 
      print(self.searchResultsData.count) // <- 20 
      self.nyheterTableView.reloadData() 
     }) 
    } 


    override func viewDidLoad() { 
     super.viewDidLoad() 

     //Construct the API URL that you want to call 
     var APIkey: String = "The deeper thought is, the taller it becomes." //Replace with your Api Key" 
     var APIBaseUrl: String = "http://api.themoviedb.org/3/movie/upcoming?api_key=" 
     var urlString:String = "\(APIBaseUrl)" + "\(APIkey)" 

     //Call the API by using the delegate and passing the API url 
     self.api.delegate = self 
     api.GetAPIResultsAsync(urlString) 
    } 

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

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     print(self.searchResultsData.count) // <- 00 
     return searchResultsData.count 
    } 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cellIdentifier: String = "nyheterResultsCell" 


     let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as UITableViewCell 

     //Create a variable that will contain the result data array item for each row 
     var cellData: NSDictionary = self.searchResultsData[indexPath.row] as NSDictionary 
     //Assign and display the Title field 

     cell.textLabel?.text = cellData["original_title"] as? String 

     // Get the release date string for display in the subtitle 
     var releaseDate: String = cellData["release_date"] as String 

     cell.detailTextLabel?.text = releaseDate 

     return cell 
    } 
} 

Полный код для APIController является:

import UIKit 

protocol APIControllerProtocol { 
    func JSONAPIResults(results: NSArray) 

} 

class APIController: NSObject { 
    var delegate:APIControllerProtocol? 

    func GetAPIResultsAsync(urlString:String) { 

     //The Url that will be called 
     var url = NSURL.URLWithString(urlString) 
     //Create a request 
     var request: NSURLRequest = NSURLRequest(URL: url) 
     //Create a queue to hold the call 
     var queue: NSOperationQueue = NSOperationQueue() 

     // Sending Asynchronous request using NSURLConnection 
     NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler:{(response:NSURLResponse!, responseData:NSData!, error: NSError!) ->Void in 
      var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil 
      //Serialize the JSON result into a dictionary 
      let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(responseData, options:NSJSONReadingOptions.MutableContainers, error: error) as? NSDictionary 

      //If there is a result add the data into an array 
      if jsonResult.count>0 && jsonResult["results"]?.count > 0 { 

       var results: NSArray = jsonResult["results"] as NSArray 
       //Use the completion handler to pass the results 
       self.delegate?.JSONAPIResults(results) 

      } else { 

       println(error) 
      } 
     }) 
    } 
} 

Я верю, что проблема возникает в reloadData(), так как перед перезагрузкой число строк равно 20, а позже, когда возвращается функция, она равна 00. В качестве альтернативы это происходит в APIController, который не совсем полностью понимает. Я следил за следующим руководством: http://www.sitepoint.com/introduction-swift-programming-language/ (О 3/4 вниз по странице)

Как уже говорилось, я новичок в Swift, Xcode и родном программировании на iOS, очень благодарен за помощь.

Cheers.

ответ

2

Ваш @IBOutlet для вашего UITableView неправильно подключен.

Дважды проверить выходы в Interface Builder и убедитесь, что nyheterTableView было связано:

@IBOutlet weak var nyheterTableView: UITableView! 

Обратите внимание на ! в конце вашего заявления. Это правильно, и как вы должны определить свои торговые точки. Но, это также немного опасно в том, что он позволяет вам использовать nyheterTableView, не проверяя, чтобы это было не nil. Это называется «неявно развязанным дополнительным», и в этом случае используется для удобства для вас, поэтому вам не нужно использовать if let, чтобы проверить все ваших торговых точек перед их использованием. Это хорошо, Предполагая, что правильно подключены к розеткам.

+0

-1 Потому что во время перезагрузки приложения сбой, поэтому все розетки правильно подключены. – Ramesh

+0

Я не согласен. Я мог ошибаться, но я считаю, что приложение терпит крах, когда OP вызывает 'reloadData()', *, потому что * представление таблицы является «nil». Я не думаю, что он действительно видит строки, значение «20», которое он упоминает, это консоль 'print()', прежде чем он действительно попытается перезагрузить таблицу в первый раз. Таким образом, он * имеет * 20 значений из своего HTTP-запроса, но терпит неудачу между фоновым извлечением и заполнением таблицы. –

+0

Ты абсолютно прав, Крейг. –