2015-12-08 4 views
2

Я думал о PFQuery.Использование PFQuery внутри cellForRowAtIndexPath

Я разрабатываю приложение, которое показывает Feed для пользователей, и также отображает счетчик Like для каждого сообщения (например, приложение Facebook или приложение Instagram).

Так что в моем PFQueryTableViewController у меня основной запрос, который в основном показать все сообщения:

override func queryForTable() -> PFQuery { 
    let query = PFQuery(className: "Noticias") 
    query.orderByDescending("createdAt") 
    return query 
} 

И я использую другой запрос, чтобы подсчитать количество лайков на другом классе в синтаксического анализа, которые contais все нравится.

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? { 
    var cell = tableView.dequeueReusableCellWithIdentifier("FeedCellIdentifier") as! FeedCell! 
    if cell == nil { 
     cell = FeedCell(style: UITableViewCellStyle.Default, reuseIdentifier: "FeedCellIdentifier") 
    } 

    let query2 = PFQuery(className:"commentsTable") 
    query2.whereKey("newsColumn", equalTo: object!) 
    query2.findObjectsInBackgroundWithBlock { 
     (objectus: [PFObject]?, error: NSError?) -> Void in 

     if error == nil { 

      let quantidade = objectus!.count 

      let commentQuantidade = String(quantidade) 

      cell.comentariosLabel.text = commentQuantidade 
     } else { 
      // Log details of the failure 
      print("Error: \(error!) \(error!.userInfo)") 
     } 
    } 

Этот способ кодирования работает, и я достигаю того, чего хочу, но! Я знаю, что я повторно использую ячейки, я знаю, что этот блок кода вызывается каждый раз, когда появляется ячейка.

И я знаю, что эти факты:

  1. Много запросов отправляются запрос Разбирает Облако, каждый раз, когда я прокрутить Tableview

  2. Это можно увидеть значение меняется, когда я например, прокрутка таблицы, потому что я повторно использую ячейки, когда сообщение имеет значение моей предыдущей ячейки, а затем с новым обновленным запросом, это работает, но не выглядит хорошо для пользователя.

Итак, мое главное сомнение в том, правильно ли это код? Я думаю, что нет, и я просто хочу другую точку зрения или идею.

Спасибо.

EDIT 1

Как я сказал, я обновил свой метод подсчета в countObjectsInBackgroundWithBlock вместо findObjectsInBackgroundWithBlock, но я не в состоянии переместить запрос в ViewDidLoad, потому что я использую object, чтобы проверить, как именно много комментарии каждый Post есть.

EDIT 2 Я встраивать запрос для подсчета количества комментариев к каждой записи и печати результатов, теперь я думаю, что мой код лучше, чем предыдущая версия, но я не в состоянии передать результат на этикетке, потому что я получаю ошибку:

Use of unresolved identifier 'commentCount'

Я читал некоторые о документации Struct

Следит мой обновленный код ниже:

import UIKit 
import Social 

class Functions: PFQueryTableViewController, UISearchBarDelegate { 

override func shouldAutorotate() -> Bool { 
    return false 
} 

var passaValor = Int() 
let swiftColor = UIColor(red: 13, green: 153, blue: 252) 
struct PostObject{ 
    let post : PFObject 
    let commentCount : Int 
} 

var posts : [PostObject] = [] 


// Initialise the PFQueryTable tableview 
override init(style: UITableViewStyle, className: String!) { 
    super.init(style: style, className: className) 
} 

required init(coder aDecoder: NSCoder) { 
    super.init(coder: aDecoder)! 
    // The className to query on 
    self.parseClassName = "Noticias" 

    // The key of the PFObject to display in the label of the default cell style 
    self.textKey = "text" 

    // Uncomment the following line to specify the key of a PFFile on the PFObject to display in the imageView of the default cell style 
    self.imageKey = "image" 

    // Whether the built-in pull-to-refresh is enabled 
    self.pullToRefreshEnabled = true 

    // Whether the built-in pagination is enabled 
    self.paginationEnabled = true 

    // The number of objects to show per page 
    self.objectsPerPage = 25 
} 

// Define the query that will provide the data for the table view 

override func queryForTable() -> PFQuery { 
    let query = super.queryForTable() 

    return query 
} 



override func viewWillAppear(animated: Bool) { 
    super.viewWillAppear(true) 
    loadObjects() 
} 

// In a storyboard-based application, you will often want to do a little preparation before navigation 
override func viewDidLoad() { 
    super.viewDidLoad() 
    // navigationBarItems() 


    let query = PFQuery(className:"Noticias") 
    query.findObjectsInBackgroundWithBlock { 
     (objects: [PFObject]?, error: NSError?) -> Void in 

     // The find succeeded. 
     print("Successfully retrieved \(objects!.count) scores.") 
     // Do something with the found objects 
     if let objects = objects { 
      for object in objects { 
       let queryCount = PFQuery(className:"commentsTable") 
       queryCount.whereKey("newsColumn", equalTo: object) 
       queryCount.countObjectsInBackgroundWithBlock { 
        (contagem: Int32, error: NSError?) -> Void in 
        let post = PostObject(object, commentCount:commentCount) 
        posts.append(post) 
        print("Post \(object.objectId!) has \(contagem) comments") 
       } 
       self.tableView.reloadData() 
      } 
     } 
    } 

    //Self Sizing Cells 
    tableView.estimatedRowHeight = 350.0 
    tableView.rowHeight = UITableViewAutomaticDimension 


} 



// Define the query that will provide the data for the table view 

//override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? { 
var cell = tableView.dequeueReusableCellWithIdentifier("FeedCellIdentifier") as! FeedCell! 
if cell == nil { 
    cell = FeedCell(style: UITableViewCellStyle.Default, reuseIdentifier: "FeedCellIdentifier") 
} 

cell?.parseObject = object 

if let assuntoNoticia = object?["assunto"] as? String { 
    cell?.assuntoNoticia?.text = assuntoNoticia 
} 


if let pontos = object?["pontos"] as? Int { 
    let pontosPosts = String(pontos) 
    cell?.pontosLabel?.text = String(pontosPosts) 
} 


if let zonaLabel = object?["zona"] as? String { 
    cell?.zonaLabel?.text = zonaLabel 
} 


if let criticidade = object?["criticidade"] as? String { 
    if criticidade == "Problema"{ 

     cell.criticidadeNoticia.backgroundColor = UIColor.redColor() 
    } else { 
     cell.criticidadeNoticia.backgroundColor = UIColor.greenColor() 
    } 
} 

return cell 
} 
} 

И результат печати:

Successfully retrieved 5 scores.

Post wSCsTv8OnH has 4 comments

Post LbwBfjWPod has 0 comments

Post fN4ISVwqpz has 0 comments

Post 1rXdQr2A1F has 1 comments

Post eXogPeTfNu has 0 comments

ответ

3

Лучшая практика заключается в том, чтобы запросить все данные на загрузке вида, сохраняя его в модели, а затем читать данные из него в прокрутке таблицы. При обработке запроса вы можете отображать индикатор загрузки или данные заполнителя.Когда запрос будет завершена, вы будете называть tableView.reloadData()

Вы можете сделать это, создав новую переменную так:

var cellModels : [PFObject] = [] 

В вашей query2.findObjectsInBackgroundWithBlock:

for object in objectus{ 
    self.cellModels.append(object) 
} 
self.tableView.reloadData() 

И cellForRowAtIndexPath:

let model = cellModels[indexPath.row] 
// configure cell according to model 
// something like cell.textLabel.text = model.text 

P.S Вы должны посмотреть на метод countObjectsInBackgroundWithBlock, если вам нужно только получить количество объектов. Потому что, если есть много комментариев, например, findObjectsInBackgroundWithBlock вернет максимум 1000 объектов, и вы не будете загружать целые объекты, а только одно число, это ускорит запрос и освободит сотовый план пользователя.

Update: Кроме того, если вам нужно хранить число комментариев, которые можно создавать простые struct так:

struct PostObject{ 
let post : PFObject 
let commentCount : Int 
} 

var posts : [PostObject] = [] 

И когда вы запрашиваете для вас сообщение вы Переберите полученные объекты и заполнить posts массив.

for object in objects{ 
    // create countObjectsInBackgroundWithBlock query to get comments count for object 
    // and in result block create 
    let post = PostObject(object, commentCount:commentCount) 
    posts.append(post) 

} 
tableView.reloadData() 

И cellForRowAtIndexPath:

let post = posts[indexPath.row] 
cell.postCountLabel.text = String(post.commentCount) 
// configure cell accordingly 
+0

Великий ответ, я пытаюсь применить в своем коде, что вы объяснили, я выложу обновление. –

+0

Я прочитал документацию и улучшил свой метод до 'countObjectsInBackgroundWithBlock' вместо' findObjectsInBackgroundWithBlock', теперь, когда я перемещаю запрос в viewDidLoad, я не могу ссылаться на объект 'query2.whereKey (" newsColumn ", equalTo: object!) ' –

+0

Какой тип' object'? Где вы его назначаете? – njuri

0

Вы должны сделать ваши запросы, прежде чем представить информацию в вашем Tableview.

Смежные вопросы