Integrating Facebook and Parse Tutorial: Part 2

In part 2 of our Parse + Facebook tutorial series, you’ll wrap up the image sharing app with image wall and comments features. By Toby Stephens.

Leave a rating/review
Save for later
Share
You are currently viewing page 4 of 5 of this article. Click here to view the first page.

Saving Comments to Parse

Now it’s time to provide your friends with a way to comment on your images.

First, you need to create the Comms method to submit a new comment.

Open Comms.h and the following method declaration:

+ (void) addComment:(NSString *)comment toWallImage:(WallImage *)wallImage;

Since you need to save the new comment to Parse asynchronously and be informed when the the save is complete, NSNotificationCenter will serve the purpose nicely.

Add the following static string to the top of Comms.h:

extern NSString * const N_CommentUploaded;

Now add the following definition to Comms.m:

NSString * const N_CommentUploaded = @"N_CommentUploaded";

Still in Comms.m add the method below:

+ (void) addComment:(NSString *)comment toWallImage:(WallImage *)wallImage
{
	// Save the new Comment to the Wall Image
	PFObject *wallImageCommentObject = [PFObject objectWithClassName:@"WallImageComment"];
	wallImageCommentObject[@"comment"] = comment;
	wallImageCommentObject[@"userFBId"] = [[PFUser currentUser] objectForKey:@"fbId"];
	wallImageCommentObject[@"user"] = [PFUser currentUser].username;

	// Set the object id for the associated WallImage
	wallImageCommentObject[@"imageObjectId"] = wallImage.objectId;
	
	// Save the comment to Parse
	[wallImageCommentObject saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
		// Notify that the Comment has been uploaded, using NSNotificationCenter
		[[NSNotificationCenter defaultCenter] postNotificationName:N_CommentUploaded object:nil];
	}];
}

The above method accepts a string argument — the text of the comment — as well as a WallImage object so that you can link the comment to the WallImage object. Once the saveInBackgroundWithBlock: block has executed, you then post a notification noting that the comment upload is complete.

To make things easy for the user, you’ll provide an inline text entry for the user, much like you’d see in Facebook. This will occupy another cell in the table, and will always be the last row of each section. Therefore, you need to add an extra row to the bottom of each section to hold the comment entry cell.

Open ImageWallViewController.m and replace the following line in tableView:numberOfRowsInSection:

return wallImage.comments.count;

… with the code below::

return wallImage.comments.count + 1; // Add a row for the New Comment cell

This will return an extra line at the bottom of each section of the table for your new comment cell.

Next, add the following property to the ImageWallTableNewCommentCell class extension at the top of ImageWallViewController.m:

@property (nonatomic, strong) WallImage *wallImage;

The above property tells ImageWallTableNewCommentCell which WallImage is being commented on, so you have it for reference later.

Now, on to render the new comment cell. Add the following code to tableView:cellForRowAtIndexPath: in ImageWallViewController.m, directly after you get the WallImage from the DataStore:

static NSString *NewCommentCellIdentifier = @"NewCommentCell";
if (indexPath.row >= wallImage.comments.count) {
	// If this is the last row in the section, create a NewCommentCell
	ImageWallTableNewCommentCell *newCommentCell = (ImageWallTableNewCommentCell *)[tableView dequeueReusableCellWithIdentifier:NewCommentCellIdentifier];

	// Set the WallImage on the cell so that new comments can be associated with the correct WallImage
	newCommentCell.wallImage = wallImage;
		
	return newCommentCell;
}

In the code above, check if this is the last row of the section; if so, set the WallImage for this cell and then return the new ImageWallTableNewCommentCell.

Build and run your project; below your comment you’ll see the new text field for entering comments:

ts_FBParse_imagewall5

Using the New Comment Field

You’re now going to send a comment about your own image. A little insular perhaps, but this app isn’t public yet, so it’ll have to do for now. :]

Open ImageWallViewController.m and locate the ImageWallTableNewCommentCell implementation. You will notice there is already a textFieldShouldReturn: method set up with no content. This is called when the user hits return on the keyboard – you will implement this method to submit the new comment.

Add the following code to textFieldShouldReturn: in ImageWallViewController.m, just before the return statement at the end:

if (_txtComment.text.length == 0) return YES;

// We have a new comment, so send it off
[_txtComment resignFirstResponder];
[Comms addComment:_txtComment.text toWallImage:_wallImage];
[_txtComment setText:@""];

The above code closes the keyboard by resigning first responder, and then makes the call to your addComment:toWallImage: method in the Comms class so that the comment is stored on the server.

Now, add the following lines to the bottom of viewDidLoad in ImageWallViewController.m:

// Listen for uploaded comments so that we can refresh the image wall table
[[NSNotificationCenter defaultCenter] addObserver:self
					 selector:@selector(commentUploaded:)
					     name:N_CommentUploaded
					   object:nil];

Here you listen for notifications of the submitted comment being loaded into Parse.

Add the following method to ImageWallViewController.m:

- (void) commentUploaded:(NSNotification *)notification
{
	[Comms getWallImagesSince:_lastImageUpdate forDelegate:self];
}

In the above method, once you receive a notification that the comment has been uploaded, you request the WallImages from Parse again so you can download the latest data, which includes your new comment.

Build and run your project; in the text field below your initial comment, make a new comment and press Return. After a short wait, you should see your comment appear below the image and the text field will be empty, ready for your next comment, as demonstrated below:

ts_FBParse_imagewall6

Uploaded Image Notifications

When you upload a new image using the app, there’s currently no way to notify the app that it needs to request and download the new app. You’re going to sort that out now with a new NSNotification.

Open Comms.h and add a new static string at the top:

extern NSString * const N_ImageUploaded;

Then, open Comms.m and define the static string at the top of the file:

NSString * const N_ImageUploaded = @"N_ImageUploaded";

This will be the Notification name to use when the new image has been uploaded successfully.

Open UploadImageViewController.m and find commUploadImageComplete:. Add the following code just after you pop the view controller on a successful upload:

// Notify that a new image has been uploaded
[[NSNotificationCenter defaultCenter] postNotificationName:N_ImageUploaded object:nil];

Now open ImageWallViewController.m and add the following code to the bottom of viewDidLoad:

// Listen for new image uploads so that we can refresh the image wall table
[[NSNotificationCenter defaultCenter] addObserver:self
					 selector:@selector(imageUploaded:)
					     name:N_ImageUploaded
					   object:nil];

Here you tell NSNotificationCenter that you want to listen for notifications of new image uploads; when you receive a new notification of an image upload, you call imageUploaded.

Still working in ImageWallViewController.m, add the following method:

- (void) imageUploaded:(NSNotification *)notification
{
	[Comms getWallImagesSince:_lastImageUpdate forDelegate:self];
}

When a new image is uploaded, this queries Parse for any new images and gets the new image and accompanying comment.

Build and run your project; upload a new image along with a comment and you’ll see your new image appear in the Image Wall once it has successfully been uploaded to Parse.

Toby Stephens

Contributors

Toby Stephens

Author

Over 300 content creators. Join our team.