First, thanks for helping. I am writing an iOs application developed with Swift and i'm using Parse.com. In a class named liste_joueurs, there is around 15 rows. However, I just want to retrieve the first four results.
I read the docs and found the query.limit property. Unfortunately, when I run my code, in my collection, all the rows from my class appear (the query.limit doesn't work).
Does anyone have a solution ?
override func queryForCollection() -> PFQuery {
let query = PFQuery(className: "liste_joueurs")
query.limit = 4 // Useless
query.orderByAscending("nom")
return query
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath, object: PFObject!) -> PFCollectionViewCell? {
println(object["nom"]?.count)
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("statsCell", forIndexPath: indexPath) as! StatsViewCell
// CELL'S TREATMENT
return cell
}
PS : When I used a constraint like this one :
query.whereKey("nom", hasPrefix: "ba")
The query "is filtered" and only rows beginning by "ba" appears in my collection...
With only this code I can say if you are using PFQueryCollectionViewController than make sure paginationEnabled = false, otherwise it will ignore. and if you are using objectsPerPage then it will override limit
Related
I'm using firebase realtime database and it's working fine for some parts of my app. I was going through a tutorial on youtube which populates a collectionView with users. It uses NSDictionary to get the photo URL and username and puts them in the collection view for all users. I deleted some of the users directly in the firebase console, and now have only one user. For some reason it's still pulling the users that I deleted. This is the collectionView file.
import UIKit
import FirebaseDatabase
private let reuseIdentifier = "UserSearchCell"
class UsersCollectionViewController: UICollectionViewController {
var usersDict = NSDictionary?()
var userNamesArray = [String]()
var userImagesArray = [String]()
override func viewDidLoad() {
super.viewDidLoad()
DataService.ds.REF_USERS.observeEventType(.Value, withBlock :{
(snapshot) in
self.usersDict = snapshot.value as? NSDictionary
for(userId,details) in self.usersDict!{
let img = details.objectForKey("profileThumbUrl") as! String
let name = details.objectForKey("username") as! String
self.userImagesArray.append(img)
self.userNamesArray.append(name)
self.collectionView?.reloadData()
}
})
self.collectionView!.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
}
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.userImagesArray.count
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! UserSearchCell
let imageUrl = NSURL(string:userImagesArray[indexPath.row])
let imageData = NSData(contentsOfURL: imageUrl!)
cell.userImage.image = UIImage(data:imageData!)
cell.userName.text = userNamesArray[indexPath.row]
return cell
}
}
Shouldn't this always sync with the database? Where are these deleted users coming from? Also I didn't include the cell code because all it is is the imageView and Label actions being declared. I ran into this problem before but my memory is bad and I don't remember why it was doing it or if I ever solved it.
Okay I figured out the answer to my own question. Apparently the simulator has a problem with firebase and seems to form some sort of cache of firebase data. I tried running it on a phone I had been testing on and it didn't have this cache and everything worked fine. Also I tried running on a different device IN the simulator and it worked fine there too. So I want to leave this up because I think a lot of people may have trouble with Firebase since it's core feature doesn't work well with the IOS simulator.
I am using includeKey to load multiple values from an array column in my PFObject. When I navigate to the tableView, however, the tableView only loads a single row
This is because the Parse cellForRowAtIndexPath method is only called once (when it should be called for the amount of values in the "following" array)
Here's my implementation
override func queryForTable() -> PFQuery {
let query = PFQuery(className: "Followers")
query.whereKey("username", equalTo: username)
query.includeKey("following")
return query
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {
let cell = tableView.dequeueReusableCellWithIdentifier(identifier) as! AccountQueryCell
let followerObject = object as! PFFollowers
cell.usernameLabel.text = followerObject.getFollowing()[indexPath.row]
cell.profileImage.username = followerObject.getFollowing()[indexPath.row]
return cell
}
As you can see, I return a query that includes the "following" array.
My Parse "Followers" class contains the following custom columns: "following" (Array) and "username" (String)
Could someone explain to me why my query isn't calling cellForRowAtIndexPath for every value in the following array?
I think the issue is that you are querying for all Followers objects which match a single username. Based on the description of your data model, this will result with only one object being found.
PFQueryTableViewController automatically sets the table view's data source according to the results of your query. In other words, the table view is being set to only create one cell to correspond to the one result from the query.
I have a UITabController that has 4 tabs. On one of the tabs I have a uitableviewcontroller that hosts cells that contain a UILabel (this UILabel is named 'dataCount) that will display the number of items in an entity found on core data and a UILabel that simply displays a name (this UILabel is named 'nameLabel'). I attempted to, whenever the tab is displayed, search through core data for an attribute with the same name as the cells nameLabel, once found I simply use some business logic to fetch data from core data and then insert the number of items I find in the dataCount UILabel. This works, but what doesn't work is having this data updated constantly on the UITableViewCell whenever the tab is visited. Can anyone show me how I can consistently get data from core data and display it on a UILabel found on a cell whenever that particular tab is visited? Something that did work, but isn't feasable, is reloading the tableview on willDisplayCell. Doing this simply increases the CPU consistently.
My Attempt:
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
// Search for number of notes
var notesFetchRequest = NSFetchRequest(entityName: "Notes")
var numberOfNotes = managedObjectContext.executeFetchRequest(notesFetchRequest, error: nil) as? [NSManagedObject]
var notesCount = 0
if let notes = numberOfNotes {
for items in notes as! [Notes] {
if items.name == (cell as! MyCell).nameLabel.text!{
notesCount += 1
}
}
}
(cell as! MyCell).dataCount.text = String(notesCount)
//self.mytableview.reloadData() -- works but CPU increases exponentially
}
It seems that when I reload the tableview on viewDidAppear the data is correctly displayed and updated. Problem solved. If anyone has any other recommendations in terms of optimization and feasibility please let me know.
override func viewDidAppear(animated: Bool) {
self.mytableview.reloadData()
}
Can't think of a good name for the question...if you can think of a better one, please feel free to edit it :)
I am building an iOS app using Swift and Parse.com.
In my app, I have a main PFQueryTableViewController which loads some data from my Parse cloud into some custom UITableViewCells.
One of the values that I want for a label on the cells takes a while for Parse to return and so I am getting it using findObjectsInBackgroundWithBlock().
In my cellForRowAtIndexPath when I'm loading my table, I have the following code:
// Set cells for each row of table
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {
var cell: CustomTableViewCell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath) as! CustomTableViewCell
// Get Course Object objectID to hand to getCourseGrade function
var anObjectID: String = object!.objectId!
cell.setCell(name: object!["objectName"] as! String, code: object!["objectCode"] as! String, grade: getObjectGrade(anObjectID))
return cell
}
In the code above, I am calling a function called getObjectGrade to pass a value across to my setCell() function which sets up the customTableViewCells as it builds the UITableView which runs as below (simplified):
func getObjectGrade(objectIdString: String) -> Float {
// Set a starting value of objectGrade
var objectGrade: Float = -1
//...I set up a PFQuery
query?.findObjectsInBackgroundWithBlock({ (objects: [AnyObject]?, error: NSError?) -> Void in
//...here I am retrive the value I need from Parse --> valueFromParse
objectGrade = valueFromParse
})
return objectGrade
}
NOW, I am VERY AWARE that this will NOT work...obviously the code does not wait for my findObjectsInBackgroundWithBlock() code to run and so returns the objectGrade before it has been updated.
MY QUESTION: How could I set the value of the label of my cell once the findObjectsInBackgroundWithBlock() code section DOES complete?
SOLVED! I moved the "getObjectGrade" function to my CustomTableViewCell file and called it from there. :) If anyone has this issue and needs help, just comment and i'll try :)
I am hoping someone can help, as I am trying to debug, but am going round in circles.
I have a table in Parse.com and can query and retrieve data successfully.
I did a test with a println and the correct values of the strings are displayed in the output.
What I was trying to do was put these values into a UITableView, but this has taken me down some pretty frustrating paths (I am still trying to learn this as best as I can and sometimes some concepts are hard to comprehend).
My last attempt (see code below) I thought by writing the values to a struct I could use this as I have done in the past, given that I can see the values I need to populate. I don't think this is the right way but I thought it should work.
My code when I put a breakpoint in doesn't get to even defining the tableview :(
I know I am missing something but maybe just need a fresh pair of eyes to help me see what I am missing.
Any help would be greatly appreciated:
#IBOutlet weak var navlabel: UILabel!
var TopicPassed:String!
var storedsentences=[getsentences]()
#IBOutlet weak var sentencetableview: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
navlabel.text = TopicPassed
var query = PFQuery(className:"TalkToMeSentences")
query.whereKey("Topic", equalTo:TopicPassed)
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]!, error: NSError!) -> Void in
if error == nil {
// query successful - display number of rows found
println("Successfully retrieved \(objects.count) sentences")
// print sentences found
for object in objects {
let retrievedsentences = object["Sentence"] as NSString
self.storedsentences = [getsentences(parsesentence: "\(retrievedsentences)")]
println("\(retrievedsentences) ")
}
self.sentencetableview.reloadData()
} else {
// Log details of the failure
println("Error: \(error) \(error.userInfo!)")
}
}
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return storedsentences.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
var sentence : getsentences
// Configure the cell...
cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
cell.textLabel!.lineBreakMode = NSLineBreakMode.ByWordWrapping
sentence = storedsentences[indexPath.row]
cell.textLabel!.text = sentence.parsesentence
cell.textLabel?.numberOfLines = 0
return cell
}
Resolved it, I think.
My problem was I had not assigned outputs for the the datasource or the delegates.
Once I did I could get the table to populate.