Alek Piasecki Alek Piasecki - 2 months ago 17
Swift Question

How to structure data for saving user comments?

I am using xcode to program an iOS app. I want to set up a section in the app where users can leave comments. I am a bit confused on how I should go about storing the set of comments for a particular post. I basically need to save only three things per comment. The user's ID, the comment itself, and the number of the comment (ie the first comment posted for that post, or the second, the third, etc...) but I do not know how best to actually save this to the database. I am using parse-server as the primary database and the issue is that while this database can store multiple qualities for objects, saving a dictionary is not possible. (I would have wanted to save the info as):

Desired Strategy (but won't work)

var commentCount = 5 //will hold value of number of comments for post
var commentString = "hello"
var commenterID = "e1das312"


var commentSavingDict = [Int: [String]]()
func addComment(){
commentCount = commentCount + 1
commentSavingDict[commentCount] = [commenterID, commentString]
}


The issue is that in parse-dashboard only arrays can be saved, not dictionaries as
commentSavingDict
is. I considered merely saving its string roughly as so:

2nd Strategy

var commentCount = 5 //will hold value of number of comments for post
var commentString = "hello"
var commenterID = "e1das312"


var commentSavingArray = [String]()
func addComment(){
commentCount = commentCount + 1
commentSavingArray.append("\(commentCount) :::: \(commentString) :::: \(commenterID)")
}


This approach would work, but would require pulling each entry from the array, and then separating the string with
.split
at the
::::
positions, dumping each part into 3 separate arrays and then utilizing them that way. This would take a bit longer as the splitting would need to be client side.

3rd Strategy

The final way I conceived would just be to have each comment be its own object in the database, with four different qualities: the number of the comment, the comment, the post's ID, and the user's ID. This too would work, but it now makes each comment its own object, as opposed to being held in an array of all comments (as a single object) for a particular post and I think this would be inefficient and use up space quickly.

Since I cannot save dictionaries, is there a better approach to this problem than I have suggested? Or am I incorrectly analyzing the ones I proposed?

Answer Source

Your third strategy is the way to go. In fact, the Parse iOS Developer's Guide has a pretty familiar example. Each comment is linked to the original post by a pointer. This does involve an additional fetch when you come to retrieve the comments for a post, but it is much more scalable than attempting to put your comment objects inside an array column on the post itself. Array columns are more typically useful for smaller, simpler collections.

This isn't without some edge-case limitations. If you want to display a count of the comments on a post in a timeline, for example, you would have to fetch all comments for every post on screen. The usual solution for this is to store a counter on the post itself, and update it when comments are added/removed (ideally via an afterSave trigger in your Cloud Code).

One additional note - you can probably avoid storing the 'comment number' and instead rely on the comments createdAt date. You can retrieve your comments by filtering on the post, and sorting by creation date.