2016-10-14 15 views
0

私はFoursquare APiからデータを取得しています。以下は私のコードです。最初にコードを実行してください! Swift

は、しかし、私は個人的に私がcellForRowAtIndexPathが最初に実行されているので、venueItemsがnilであると考えて、プログラミングにはかなり新しいです

override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 
    // Table View 
     self.tableView = UITableView() 

// Location Manager Stuff 
     self.locationManager = CLLocationManager() 
     self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters 
     self.locationManager.delegate = self 
     let status = CLLocationManager.authorizationStatus() 
     if status == .notDetermined { 
      self.locationManager.requestWhenInUseAuthorization() 
     } else if status == CLAuthorizationStatus.authorizedWhenInUse 
      || status == CLAuthorizationStatus.authorizedAlways { 
      self.locationManager.startUpdatingLocation() 
     } else { 
      showNoPermissionsAlert() 
     } 

    exploreVenues() 


    } 

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

    // Func's 

    func exploreVenues(){ 
     guard let location = self.locationManager.location else { 
     return 
     } 
     var parameters = [Parameter.query:"Pubs"] 
     parameters += location.parameters() 

     let task = self.session.venues.explore(parameters) { 
      (result) -> Void in 
      if self.venueItems != nil { 
       return 
      } 
      if !Thread.isMainThread { 
       fatalError("!!!") 
      } 

      if let response = result.response { 
       if let groups = response["groups"] as? [[String: AnyObject]] { 
        var venues = [[String: AnyObject]]() 
        for group in groups { 
         if let items = group["items"] as? [[String: AnyObject]] { 
          venues += items 
         } 
        } 

        self.venueItems = venues 
       } 
       self.tableView.reloadData() 
      } else if let error = result.error , !result.isCancelled() { 
       self.showErrorAlert(error) 
      } 
     } 
     task.start() 
    } 


    // Table View Data source 
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     if let venueItems = self.venueItems { 
      return venueItems.count 
     } 
     return 10 
    } 


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

     let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! VenueTableViewCell 
     // This is where the error occurs 
     let item = self.venueItems![(indexPath as NSIndexPath).row] as JSONParameters! 
     self.configureCellWithItem(cell, item: item!) 
     return cell 
    } 

    func configureCellWithItem(_ cell:VenueTableViewCell, item: JSONParameters) { 

     if let venueInfo = item["venue"] as? JSONParameters { 
      cell.nameLabel.text = venueInfo["name"] as? String 
     } 

    } 

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { 

     let cell = cell as! VenueTableViewCell 

     let tips = self.venueItems![(indexPath as NSIndexPath).row]["tips"] as? [JSONParameters] 

     guard let tip = tips?.first, let user = tip["user"] as? JSONParameters, 
      let photo = user["photo"] as? JSONParameters else { 
       return 
     } 

     let URL = photoURLFromJSONObject(photo) 
     if let imageData = session.cachedImageDataForURL(URL) { 
      cell.venueImageView.image = UIImage(data: imageData) 
     } else { 

      cell.venueImageView.image = nil 
      session.downloadImageAtURL(URL) { 
       (imageData, error) -> Void in 
       let cell = tableView.cellForRow(at: indexPath) as? VenueTableViewCell 
       if let cell = cell, let imageData = imageData { 
        let image = UIImage(data: imageData) 
        cell.venueImageView.image = image 
       } 
      } 

     } 


    } 

nilをvenueItemsがあるcellForRowAtIndexPathではnilエラーを取得しています。これがエラーの場合は、venueItemsに値があるかどうか、cellForRowAtIndexpathのコードが実行されるように、どうすれば修正できますか..または他のより効率的な方法ですか?

+0

if venueItems!= nil {// your code} 'を実行するか、viewWillAppearで配列を入力してください – nighttalker

答えて

4

numberOfRowsInSectionは、self.venueItemsがnilの場合、10を返します。 self.venueItemsは、ネットワーク要求が終了するまで表示されないように見えるため、表の表示には10行が表示され、各行のセルを尋ねるように指示されています。その後、オプションのプロパティ(self.venueItems!)の展開を強制してクラッシュさせようとします。

あなたのself.venueItemsはオプションであると思われます。正当な理由から、その情報を強制解除しないでください(!)。このプロパティがnilのときは0行を返すか、オプションでない空の配列に初期化して、常にcountを要求することができます。

一般に、この種の問題では、cellForRowAtIndexPathが呼び出されるのを防ぐのではなく、いつでも呼び出され、妥当な結果を返すように計画しています(表に0行があることを報告するなど)あなたのバックグラウンドタスクがまだ完了していないとき。

+1

Jonahが正しいです。あなたがしなければならないことの1つは、tableView.reloadData()を使用してvenueItemsが設定された後にtableViewをリロードすることです。 –

関連する問題