I have two parse classes, one is "users" and one is where users enter some comments like "tweets". In "users" class every object has two columns a username and a photo. In tweets table every object has the info of username and comment. I need to make a query that merges these two tables according to username matches, and finally should have 3 columns, username - photo - comment. How can I do this via swift in xcode? Than I will use the result append it as arrays and show them in table view cells.
3 Answers
You should take a look at Parse 1-many relationships. Here you can find Swift-based code snippets.
Basically, you do not link a user's tweets to that user by associating the user name (this is what would happen in a SQL database). What you do is assigning a user object to the tweets, then when you have a tweet, you can access its user attribute and all of its properties.
let user = PFObject(className:"TweetAuthor")
...
let tweet = PFObject(className:"Tweet")
tweet["..."] = ...
tweet["createdBy"] = user
...
let userTweets = PFQuery(className:"Tweet")
tweetQuery.whereKey("createdBy", equalTo: user)
tweetQuery.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
let aTweet = object![...]
let picture = aTweet["createdBy"]["picture"]
...
}
Hope this helps.
EDIT:
How should you use the code above?
I assume that at some place in your app, you create a Tweet and you currently assign it a 'username' (and 'profilePicture', etc.):
tweet["userName"] = user["username"]
Instead of assigning a userName (string), assign it the full user object:
tweet["createdBy"] = user
(remove all code to assign profilePicture, etc.)
Once you have this, you can get the picture associated to a tweet by doing:
let picture = aTweet["createdBy"]["picture"]

- 68,819
- 11
- 102
- 123
-
Hello Sergio, http://i.imgur.com/5CN5K5m.png and http://i.imgur.com/fkstCWw.png are the views of my table. I could not understand well what I should fill the dots with in your code. I am a bit new in swift coding. The classes are "Usertable" and "tweets". I would be really happy if your could make your code a bit clearer :) thank you very much – saner Jun 05 '15 at 09:53
-
I see. That kind of design is suboptimal for Parse (or other NoSQL databases). Why can't you store your full user object in a tweet? you would also avoid having to store separately the email address and the user name... Have a look at this for the "suboptimal" bit: https://parse.com/questions/how-to-join-several-tables-with-one-to-many-relationship – sergio Jun 05 '15 at 10:02
-
@saner: please show me your code where you create tweets, and assign them a username... the dots are basically whatever code you have -- I am just showing the relevant bits... – sergio Jun 05 '15 at 10:03
-
Actually I used to store all the data including picture in tweets table, but I have also a users table in which users have their profile picture. I have a setting in which users update their profile pictures. When a user updates the profile picture it takes too much time for the tweets table to be updated as hundreds of objects' profile picture needs to be updated. – saner Jun 05 '15 at 10:08
-
yeah, you are doing a lot of work that is unnecessary and will necessarily slow down your app. the way to go is what I outlined above. See my edit, I hope it clarifies things a bit. – sergio Jun 05 '15 at 10:19
The code below that I use thats the info of the people who is followed by the current user, and shows their tweet info. However when a user updates his profile picture which is in the users table, the past data of the tweets table (which includes also the profile picture) is not updated.
func refreshResults() {
followArray.removeAll(keepCapacity: false)
resultsNameArray.removeAll(keepCapacity: false)
resultsUserNameArray.removeAll(keepCapacity: false)
resulltsImageFiles.removeAll(keepCapacity: false)
resultsTweetArray.removeAll(keepCapacity: false)
resultsHasImageArray.removeAll(keepCapacity: false)
resultsTweetImageFiles.removeAll(keepCapacity: false)
resultsTweetType.removeAll(keepCapacity: false)
var followQuery = PFQuery(className: "follow")
followQuery.whereKey("user", equalTo: PFUser.currentUser()!.username!)
followQuery.addDescendingOrder("createdAt")
var objects = followQuery.findObjects()
for object in objects! {
self.followArray.append(object.objectForKey("userToFollow") as! String)
}
var query = PFQuery(className: "tweets")
query.whereKey("userName", containedIn: followArray)
query.addDescendingOrder("createdAt")
query.findObjectsInBackgroundWithBlock {
(objects:[AnyObject]?, error:NSError?) -> Void in
if error == nil {
for object in objects! {
self.resultsNameArray.append(object.objectForKey("profileName") as! String)
self.resultsUserNameArray.append(object.objectForKey("userName") as! String)
self.resulltsImageFiles.append(object.objectForKey("photo") as! PFFile)
self.resultsTweetArray.append(object.objectForKey("tweet") as! String)
self.resultsHasImageArray.append(object.objectForKey("hasImage") as! String)
self.resultsTweetImageFiles.append(object.objectForKey("tweetImage") as? PFFile)
self.resultsTweetType.append(object.objectForKey("tweetType") as! Int)
self.resultsTable.reloadData()
}
self.refresher.endRefreshing()
}
}
}

- 821
- 2
- 10
- 32
I could not figured it out how to record a column in parse of an object from another table. As you stated, I am currently recording the username and photo seperately as columns for each tweet. The tweeting code is as below. In parse should I create a new column for this in the tweets table? What should be the type of the column?
var tweetObj = PFObject(className: "tweets")
tweetObj["userName"] = PFUser.currentUser()!.username
tweetObj["profileName"] = PFUser.currentUser()!.valueForKey("profileName") as! String
tweetObj["photo"] = PFUser.currentUser()!.valueForKey("photo") as! PFFile
tweetObj["tweet"] = theTweet
When I try to update the code above as the code below I get an error (I created the column in parse as type of object with name createdBy).
let user = PFObject(className:"TweetAuthor")
var tweetObj = PFObject(className: "tweets")
tweetObj["userName"] = PFUser.currentUser()!.username
tweetObj["profileName"] = PFUser.currentUser()!.valueForKey("profileName") as! String
tweetObj["photo"] = PFUser.currentUser()!.valueForKey("photo") as! PFFile
tweetObj["tweet"] = theTweet
tweetObj["createdBy"] = user

- 821
- 2
- 10
- 32