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 .
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Fat Fractal Tutorial for iOS: Getting Started
40 mins
- Why Fat Fractal?
- Getting Started
- Installing FatFractal Locally
- Downloading the SDK and Starter Project
- Setting Up The iOS Client
- Creating Sample Objects
- Adding The FatFractal Instance
- About FFUser
- Building The Authentication System
- Building The Authentication System Part II
- The Login View Controller
- Adding Your First Tweet
- Retrieving And Displaying The First Tweet
- Where To Go From Here?
Building The Authentication System
Next let’s build your authentication system.
Open SignupViewController.m, and add the following code to signupButtonPressed:
right after the “TODO” comment:
// Step 1
FFUser *newUser = [[FFUser alloc] initWithFF:[FatFractal main]];
newUser.firstName = fullname;
newUser.userName = username;
newUser.email = email;
// Step 2
[[FatFractal main] registerUser:newUser password:password onComplete:^(NSError *theErr, id theObj, NSHTTPURLResponse *theResponse) {
// Step 3
if (theErr) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:[theErr localizedDescription] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
[alert show];
return;
} else {
// Step 4
if (theObj) {
// App is now in signed in state.
// Step 5
[self saveUserCredentialsInKeychain];
[MBProgressHUD hideHUDForView:self.view animated:YES];
// Step 6
[self dismissViewControllerAnimated:YES completion:^{
[self handleSuccessfulSignup];
}];
}
}
}];
The above code registers a new user. Let’s go over it step by step:
- Here you create a new
FFUser
instance using the FatFractal singleton. You then assign the properties of the FFUser as the user input in the textfields - You then call the
registerUser:password:onComplete:
method on your FatFractal singleton. This method will attempt to sign up a user, and provide a callback when the backend server replies to you. - If there is an error, you hide the progress view and display an alert.
- If there is no error, you double check that the server returned you an object, which is your
FFUser
object actually. Your app is now in a signed in state. - You then save the user’s credentials in your keychain so you can automatically log the user in from hence forth.
- You then dismiss the modal view controller, and send your delegate a message – that the sign up was successful.
Next inside AppDelegate.h, declare a new class method:
+ (BOOL)checkForAuthentication;
Inside AppDelegate.m, implement this method:
+ (BOOL)checkForAuthentication {
if ([_ff loggedIn] || ([_keychainItem objectForKey:(__bridge id)(kSecAttrAccount)] != nil && ![[_keychainItem objectForKey:(__bridge id)(kSecAttrAccount)] isEqual:@""])){
NSLog(@"checkForAuthentication: FFUser logged in.");
return YES;
} else {
NSLog(@"checkForAuthentication: No user logged in.");
return NO;
}
}
Inside MainFeedViewController.m, import AppDelegate.h:
#import "AppDelegate.h"
Then inside checkForAuthentication
replace the line if (false) {
with the following:
if ([AppDelegate checkForAuthentication]) {
This checks to see if the user is logged in, and if not presents the WelcomeViewController
.
And with this, you can now sign up new users for your application! >Build and run and try to sign up a new user. You should see the modal Welcome View Controller dismiss itself and show you your MainFeedViewController table view if successful.
Not bad for just a few lines of code, eh?
Building The Authentication System Part II
Let’s complete the rest of the authentication system while you are at it.
Open AppDelegate.m, and let’s make the application automatically log in the user if there are user credentials in the keychain.
Inside application:didFinishLaunchingWithOptions:
, add the following code after the “Login with FatFractal by initiating connection with the server” comment:
// Step 1
[_ff loginWithUserName:username andPassword:password onComplete:^(NSError *theErr, id theObj, NSHTTPURLResponse *theResponse) {
// Step 2
if (theErr) {
NSLog(@"Error trying to log in from AppDelegate: %@", [theErr localizedDescription]);
// Probably keychain item is corrupted, reset the keychain and force user to sign up/ login again.
// Better error handling can be done in a production application.
[_keychainItem resetKeychainItem];
return ;
}
// Step 3
if (theObj) {
NSLog(@"Login from AppDelegate using keychain successful!");
[self userSuccessfullyAuthenticated];
}
}];
In the code above, you login an existing user in the keychain by:
- Calling the
loginWithUserName:AndPassword:onComplete
method on your FatFractal instance, which will return with a response from the server. - If there is an error, your keychain item is probably corrupted. Thus, you will clear it, and force the user to sign up and log in again when he next launches the application. In a production application, more robust error handling can be done.
- If there is no error, and the server returns you an
FFUser
object, you will send a message to theMainFeedViewController
to inform it that user is successfully authenticated. This is so that you can know when to download the tweets and user information, as well as refresh the table view in theMainFeedViewController
.
Build and run your application. If all goes well, in the log you should see the FFUser
object being returned by the server and your log message that login from the app delegate using keychain was successful:
The Login View Controller
Registration works great, but the Login View Controller still doesn’t work, so let’s add the code for that next.
Open LoginViewController.m and add the following code to loginUserWithUsername:andPassword:
after the “TODO” comment:
#pragma mark - Helper Methods
// Login with FatFractal, save to keychain and handleSuccessfulLogin if successful
// Step 1
[[FatFractal main] loginWithUserName:usernameText andPassword:passwordText onComplete:^(NSError *theErr, id theObj, NSHTTPURLResponse *theResponse) {
// Step 2
if (theErr) {
NSLog(@"Error logging in from LoginViewController: %@", [theErr localizedDescription]);
[MBProgressHUD hideHUDForView:self.view animated:YES];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Your username and password could not be authenticated. Double check that you entered them correctly and try again." delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
[alert show];
} else {
// Step 3
if (theObj) {
// App is now in signed in state.
[self saveUserCredentialsInKeychain];
[MBProgressHUD hideHUDForView:self.view animated:YES];
[self dismissViewControllerAnimated:YES completion:^{
// Upon successful dismiss, handle login.
[self handleSuccessfulLogin];
}];
}
}
}];
In the code above, you login an user to your Fat Fractal backend by:
- Calling the
loginWithUserName:AndPassword:onComplete
method on your FatFractal instance, which will return with a response from the server. - Handle the error, if any. Notice that you do not display the localized error, you will explain why in a short while.
- Check that the server actually returned you the
FFUser
object, save your credentials in the keychain and dismiss the modal view.
Now, why don’t you show the localized error message?
The reason is that the error message will reveal that the user is either using an incorrect password or user name that does not exist. This is bad in terms of security as you don’t want to make it easy for people to guess user names or passwords. Thus, you give a generic message that makes it hard to guess if the user name exists or the password is wrong. You can see it in the logs below:
For now, you will not be using the Login View Controller, as you are automatically logged in when you sign up, and there is no log out function as of yet.
You will come to that in a while.