Fat Fractal Tutorial for iOS: Getting Started

Learn how to make an iOS app with a back end like Twitter in this beginner Fat Fractal tutorial! By .

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

Adding Your First Tweet

What Twitter clone would you have if the user can’t even post his or her tweet?

Let’s create the Micropost object that will hold your tweets.

Choose File > New > New File or ⌘N to bring up the Template Chooser for the new class file. You will use the standard Objective-C class template. Click Next.

Enter the name of the Objective-C class as Micropost, a subclass of NSObject.

Modify Micropost.h as follows:

#import <Foundation/Foundation.h>

@interface Micropost : NSObject

@property (strong, nonatomic) NSString *content;
@property (strong, nonatomic) FFUser *user;

@end

Next, let’s create your AddTweetViewController.

Choose File > New > New File or ⌘N to bring up the Template Chooser for the new class file. We will use the standard Objective-C class template. Click Next.

Enter the name of the Objective-C class as AddTweetViewController, a subclass of UIViewController.

CreatingAddTweetViewControllerOne

Next, let’s create the user interface for your AddTweetViewController in your storyboard. Drag a new View Controller object into your storyboard, select it, and change it’s class to AddTweetViewController under it’s Identity Inspector.

ChangingViewControllerToAddTweetVC

Next, drag a UITextView, UINavigationBar and two UIBarButtonItems and set up your user interface as such:

SettingUpTheAddTweetUI

Connect your text view to an outlet called tweetTextView, the cancel button to an action called cancelButtonPressed:, and the tweet button to an action called tweetButtonPressed::

ConnectingUpAddTweetViewController

Next open AddTweetViewController.m and import the Micropost header at the top of the file:

#import "Micropost.h"

Make the text field the first responder when the view loads and clear the text by adding this to the viewDidLoad method:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [_tweetTextView becomeFirstResponder];
    [_tweetTextView setText:@""];
}

Then in edit the cancelButtonPressed: method to simply dismiss the view controller:

- (IBAction)cancelButtonPressed:(id)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}

And replace tweetButtonPressed: with the following:

- (IBAction)tweetButtonPressed:(id)sender {

    // Check if logged in user exists (logged in)
    if ([[FatFractal main] loggedInUser]) {
        Micropost *myPost = [[Micropost alloc] init];
        myPost.content = _tweetTextView.text;
        myPost.user = [[FatFractal main] loggedInUser];
        [[FatFractal main] createObj:myPost atUri:@"/Micropost" onComplete:^(NSError *theErr, id theObj, NSHTTPURLResponse *theResponse) {
            if (theErr) {
                NSLog(@"Error, can't post at this time.");
            }

            if (theObj) {
                NSLog(@"Success! Micropost created: %@", theObj);
                [self dismissViewControllerAnimated:YES completion:nil];
            }
        } onOffline:^(NSError *theErr, id theObj, NSHTTPURLResponse *theResponse) {
            FFQueuedOperation *operation = (FFQueuedOperation *)theObj;
        }];
    }
}

You first check if the user is logged in, and create a new Micropost object with the text and currently logged in users as the properties.

You then call the createObj: method on your FatFractal singleton to create and post the object to your web service. This should be familiar to you by now.

The interesting thing here is the onOffline: block.

Fat Fractal supports offline queuing for most operations, in case the client is offline. The Fat Fractal SDK will try to complete any queued operations every 1 second while the client is online, and every 10 seconds while your client is offline.

The queued operations are saved to the iOS device local storage, so they survive app restarts, termination etc. This is very useful when designing an app like Twitter, which if your user tweets a post while in an area without network connectivity, the app will ‘hold’ or queue the post for you, and post it to the server when the user has connectivity again.

Allright! The last step is to display the new Add Tweet View Controller modally from the Main Feed View Controller.

Open MainFeedViewController.m and import the file:

#import "AddTweetViewController.h"

Then open MainStoryboard.storyboard and drag a UIBarButtonItem from your Object library to the navigation bar of your Main Feed View Controller like this:

DraggingUIBarButtonToMainVC

Change the Identifier of the UIBarButtonItem under the Attributes Inspector to Add.

ChangingTheUIBarButtonItemAttribute

Next, connect the UIBarButtonItem you added to the AddTweetViewController through a modal segue by Ctrl-Dragging from the button to the AddTweetViewController:

ConnectingModalSegueFromUIBtnToAddTweet

And select Modal Segue when the pop up appears:

ModalSegueSelectionUIBarBtn

Allright! Run the app now try adding a tweet.

To do this, click on the + Bar Button, and you should see the AddTweetViewController’s modal view appear. Type in what ever you like, and hit the Tweet button:

RunYourFirstTweet

You should see something like the following in your logs, signifying that your post was successful!

FirstTweetSuccessPartOne

FirstTweetSuccessPartTwo

If you go to your Fat Fractal domain, using your web browser, at https://[YOUR DOMAIN].fatfractal.com/[YOUR APP NAME]/ff/resources/Micropost, you will see that your object has been created in your backend, along with other JSON data:

FirstTweetSuccessPartThreeBackedn

Our table view is still empty though.. So let’s retrieve this data and format it to your table view.

Retrieving And Displaying The First Tweet

Open MainFeedViewController.m, import your Micropost.h file:

#import "Micropost.h"

Next, you need an array to hold all the posts that you download from the web service, and a property to keep track of your current user. Change the @interface directive inside MainFeedViewController.m to look like this:

@interface MainFeedViewController ()
@property (strong, nonatomic) NSMutableArray *postsArray;
@property (strong, nonatomic) FFUser *currentUser;
@end

Then add this new method:

- (void)refresh {
    if ([[FatFractal main] loggedInUser]) {
        self.currentUser = [[FatFractal main] loggedInUser];
        [self refreshTableAndLoadData];
    }
}

Basically, what you are doing here is to check if there is a logged in user. If there is, you will assign the currentUser to the currently logged in user, as well as refresh the table with the new data from your backend.

Call this method from both viewDidLoad and userIsAuthenticatedFromAppDelegateOnLaunch:

[self refresh];

Let’s implement the refreshTableAndLoadData method now. Add the method below your viewDidLoad method:

-(void)refreshTableAndLoadData {

    // Clean the array
    if (_postsArray) {
        [_postsArray removeAllObjects];
        _postsArray = nil;
    }

    // (Re) Create the array
    _postsArray = [NSMutableArray array];

    [[FatFractal main] getArrayFromUri:@"/Micropost" onComplete:^(NSError *theErr, id theObj, 	 	NSHTTPURLResponse *theResponse) {

		if (theObj) {
            _postsArray = (NSMutableArray *)theObj;

            [self.tableView reloadData];
        }
    }];
}

You will check if the postsArray instance variable exists. If so, you will remove all objects from it and set it to nil. You then create the postsArray again.

To retrieve data from your FatFractal backend, you just need to call getArrayFromUri: on your singleton, and pass in the URI endpoint for the data you want to retrieve. In this case, it is /Micropost. This will retrieve all the objects from https://.fatfractal.com//ff/resources/Micropost for us.

Remember to call the refreshTableAndLoadData method in your callback too, so that this method will be invoked when you log in from the App Delegate.

#pragma mark - Public Methods
-(void)userIsAuthenticatedFromAppDelegateOnLaunch {
    [self refreshTableAndLoadData];
}

Lastly, you need to set up your table view to be able to show the data. Change your table view data source methods to look like this:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return [_postsArray count];
}

And add this code inside your tableView:cellForRowAtIndexPath: after the “To Do: Display Microposts from posts array” comment:

if ([_postsArray count] > 0) {
    Micropost *micropost = [_postsArray objectAtIndex:indexPath.row];
    NSString *text = micropost.content;
    CGSize constraint = CGSizeMake(TEXT_WIDTH, 20000.0f);
    CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:[UIFont systemFontSize]] 						constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
    if (!micropostLabel) {
        micropostLabel = (UILabel *)[cell viewWithTag:1];
    }
    [micropostLabel setText:text];
    [micropostLabel setFrame:CGRectMake(TEXTOFFSET_X, TEXTOFFSET_Y, TEXT_WIDTH, MAX(size.height + 										5, 60.0f))];

    if (!fullnameLabel) {
        fullnameLabel = (UILabel *)[cell viewWithTag:3];
    }
    [fullnameLabel setText:micropost.user.firstName];

    if (!profileImageView) {
        profileImageView = (UIImageView *)[cell viewWithTag:2];
    }
    profileImageView.frame = CGRectMake(CELL_CONTENT_MARGIN, (MAX(size.height + 35, 60.0f) - 								IMAGE_SIDE)/ 2, IMAGE_SIDE, IMAGE_SIDE);

    [micropostLabel sizeToFit];
}

Allright – it’s to see the fruits of your labour! Build and run the app, and you should see the tweet that you posted earlier appear:

FirstTweetAppearingInTable