Facebook Tutorial for iOS: How To Use Facebook’s New Graph API from your iPhone App

Ray Wenderlich
Learn how to use the Facebook Graph API on the iPhone!

Learn how to use the Facebook Graph API on the iPhone!

If you are an iPhone developer and want to integrate Facebook into your app, things can be a bit confusing these days.

First, there’s this iPhone library called Facebook Connect that looks pretty cool – but then there’s this other thing called the Graph API too.

So what’s this Graph API thing all about, and how does it relate to Facebook Connect?

Short answer: Facebook Connect uses the old API, but the Graph API is the new API. The new Graph API is simple, has more flexibility, and you can do things with it that you couldn’t do before.

But Facebook Connect doesn’t use the Graph API, so what is a poor developer to do?

Update: Since writing this Facebook tutorial, Facebook Connect now supports the Graph API. However, this Facebook tutorial may still be useful if you want to see how things work under the hood!

That’s where this Facebook tutorial series comes in! In this three-part series, we will cover how the Graph API works step by step, including:

  • How to authenticate the user with the Graph API
  • How to get user information
  • How to post to their wall
  • How to upload photos
  • And even how to add a “like button” to your Facebook fan page!

In this first article, we’ll mainly cover how to authenticate the user using the Graph API, since that’s really the hardest part (the rest is pretty simple). (Jump to Part 2 or Part 3 of the series.) So let’s get started by talking about how the authentication works!

How OAuth Authentication Works

To authenticate users to Facebook, the Graph API uses the new OAuth 2.0 protocol. Don’t worry – the name sounds imposing, but the way it works is actually pretty simple.

The idea is you make an app using the Facebook developer’s portal, and when you do you get a unique ID for your app called an API Key.

Then when you want to log a user into Facebook, you go to the following URL in a web browser:

https://graph.facebook.com/oauth/authorize?
    client_id=[your API key]&
    redirect_uri=http://www.facebook.com/connect/login_success.html&
    scope=[extended permissions you want]&
    type=user_agent&
    display=touch

The user will see a standard Facebook login page and they can enter in their username and password, and give any permissions required.

You don’t need to implement a redirect_uri yourself – you can just use a preset one from Facebook, as shown above. The preset callback will return to you an access token, which is what you’ll need to make all future requests.

When a user logs in, Facebooks stores some information about the login in cookies. So next time you try to login, if the cookies haven’t expired, the login will automatically complete without user intervention!

Where’s the Secret Key?

If you’re familiar with using the old Facebook Connect API, you’ll notice that nowhere in the above steps do you pass your app’s secret key.

This arguably is a security issue, but its effect is mitigated on the iPhone by the fact that Safari stores cookies on a per-app basis, and the user would probably notice if your app was trying to log in as a different app.

This is not really within the scope of this blog post so I’m not going to discuss it futher here, but if you are curious you can check out this Facebook forum post on the matter or contact me.

IMHO, on the iPhone it isn’t a huge deal so I still plan on using Facebook & the Graph API in my apps. But I am going to be very careful what I put on Facebook and what apps I allow to access it, as all of us should already know! :]

Anyway – enough background, let’s get this working in some code!

Creating a Login Dialog

The first thing we need to do is create a web view that we can redirect to the OAuth authentication URL shown above.

Since the user might not have to manually login if cookies from an old login are still valid, we will try logging in behind the scenes, and only show the web view if a manual login is required.

Let’s start by making a new project. Go to File\New Project, choose Application\View-based Application, and click “Choose…”. Name the project FBFun, and click “Save”.

Then click on File\New File, choose iPhone OS\Cocoa Touch Class\UIViewController subclass, make sure “With XIB for user interface” is checked, and click “Next”. Name the file “FBFunLoginDialog’, and click “Finish”.

Open up FBFunLoginDialog.h and replace the contents with the following:

#import <UIKit/UIKit.h>
 
@protocol FBFunLoginDialogDelegate
- (void)accessTokenFound:(NSString *)accessToken;
- (void)displayRequired;
- (void)closeTapped;
@end
 
@interface FBFunLoginDialog : UIViewController <UIWebViewDelegate> {
    UIWebView *_webView;
    NSString *_apiKey;
    NSString *_requestedPermissions;
    id <FBFunLoginDialogDelegate> _delegate;
}
 
@property (retain) IBOutlet UIWebView *webView;
@property (copy) NSString *apiKey;
@property (copy) NSString *requestedPermissions;
@property (assign) id <FBFunLoginDialogDelegate> delegate;
 
- (id)initWithAppId:(NSString *)apiKey 
    requestedPermissions:(NSString *)requestedPermissions 
    delegate:(id<FBFunLoginDialogDelegate>)delegate;
- (IBAction)closeTapped:(id)sender;
- (void)login;
- (void)logout;
 
-(void)checkForAccessToken:(NSString *)urlString;
-(void)checkLoginRequired:(NSString *)urlString;
 
@end

The first thing we do here is create a delegate, which FBFunViewController will eventually implement. We want to be able to tell this guy if we’ve found an access token or if he needs to display us on the screen.

Next, we set up a couple member variables. We need to keep track of our web view, and also store the API key and any permissions that our app wants. And of course, we need a reference to the delegate.

At the end, we just declare the methods that we’ll be implementing in our .m file later.

Ok – time to set up the UI! Open up FBFunLoginDialog.xib, drag a UIWebView to the center of the view, and resize it a bit so there’s some space at the bottom. Add a button into the bottom that says “Close”. When you’re done it should look like the following:

Layout for our Facebook Login Dialog

Then control-drag from “File’s Owner” to the UIWebView and connect it to the “webView” outlet. Also control-drag from the UIWebView back up to the “File’s Owner”, and connect it to the “delegate” outlet. Finally, control-drag from the UIButton up to “File’s Owner”, and connect it to the “closeTapped:” outlet.

That’s it with Interface Builder – save your XIB and head over to FBFunLoginDialog.m!

Loading the Authorization URL

The first thing we’re going to do is load the Authorization URL to get the process rolling. But first we have to take care of some member variables, so start by adding the following to the top of the file:

#import "FBFunLoginDialog.h"
 
@implementation FBFunLoginDialog
@synthesize webView = _webView;
@synthesize apiKey = _apiKey;
@synthesize requestedPermissions = _requestedPermissions;
@synthesize delegate = _delegate;
 
- (id)initWithAppId:(NSString *)apiKey 
    requestedPermissions:(NSString *)requestedPermissions 
    delegate:(id<FBFunLoginDialogDelegate>)delegate {
    if ((self = [super initWithNibName:@"FBFunLoginDialog" 
        bundle:[NSBundle mainBundle]])) {
        self.apiKey = apiKey;
        self.requestedPermissions = requestedPermissions;
        self.delegate = delegate;
    }
    return self;    
}
 
- (void)dealloc {
    self.webView = nil;
    self.apiKey = nil;
    self.requestedPermissions = nil;
    [super dealloc];
}

Pretty standard stuff here – we just set up an initializer which FBFunViewController will call to create the dialog, and synthesize/dealloc our variables.

Next add the login/logout methods that FBFunViewController will call when the user wants to login or logout from Facebook:

- (void)login {
 
    [_webView loadRequest:
        [NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
 
    NSString *redirectUrlString = 
        @"http://www.facebook.com/connect/login_success.html";
    NSString *authFormatString = 
        @"https://graph.facebook.com/oauth/authorize?
            client_id=%@&redirect_uri=%@&scope=%@&type=user_agent&display=touch";
 
    NSString *urlString = [NSString stringWithFormat:authFormatString, 
        _apiKey, redirectUrlString, _requestedPermissions];
    NSURL *url = [NSURL URLWithString:urlString];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [_webView loadRequest:request];	   
}
 
-(void)logout {    
    NSHTTPCookieStorage* cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    for (NSHTTPCookie* cookie in 
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {
        [cookies deleteCookie:cookie];
    }
}

In the login method, the first thing we do is clear the web view by loading a blank about page, just so there’s nothing left from any previous loads.

Then, we set up our URL string by replacing the client id and requested permissions with the values we have stored, and tell our web view to load that page.

In the logout method, we just clear all the cookies. It’s OK to clear all of them, because cookies are stored on a per-app basis, and in this app we’re only using the web browser for Facebook. If we were using several sites, it might be better to just clear out Facebook’s cookies by examining the cookie’s domain.

Next up, since we set ourselves as the delegate of the UIWebView we’ll get notifications when the web view starts and finishes loading URLs. In our case what we care about is when the web view begins to load a URL, so add this next:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
 
    NSString *urlString = request.URL.absoluteString;
 
    [self checkForAccessToken:urlString];    
    [self checkLoginRequired:urlString];
 
    return TRUE;
}

In the above, when the web browser begins to load a URL, we check for the two cases we care about:

  1. The login completed successfully, and Facebook called the premade redirect URL (checkForAccessToken).
  2. Facebook needs the user to enter in their username and password (checkLoginRequired).

Checking for the Access Token

Let’s write the function to check for the access token in the URL next:

-(void)checkForAccessToken:(NSString *)urlString {
    NSError *error;
    NSRegularExpression *regex = [NSRegularExpression 
        regularExpressionWithPattern:@"access_token=(.*)&" 
        options:0 error:&error];
    if (regex != nil) {
        NSTextCheckingResult *firstMatch = 
            [regex firstMatchInString:urlString 
                options:0 range:NSMakeRange(0, [urlString length])];
        if (firstMatch) {
            NSRange accessTokenRange = [firstMatch rangeAtIndex:1];
            NSString *accessToken = [urlString substringWithRange:accessTokenRange];
            accessToken = [accessToken 
                stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
            [_delegate accessTokenFound:accessToken];               
        }
    }
}

If a login is successful, the web browser will eventually be redirected to a URL that looks like the following:


http://www.facebook.com/connect/login_success.html#access_token=...&...

So in checkForAccessToken, we want to check to see if the URL contains the letters “access_token=” eventually followed by an ampersand, and grab everything in between.

Of course we could do this with some regular string parsing, but I thought this would be a good opportunity to demonstrate the new NSRegularExpression API introduced in iOS 3.2 that is really helpful for stuff like this.

First we create a NSRegularExpression object, passing in a regular expression pattern. Explaining regular expressions is outside of the scope of this article, but if you want to learn more, check out regular-expressions.info.

But in short, the above pattern is saying:

  • Search for anything that contains the letters “access_token”…
  • …Then any amount of any type of characters…
  • …But stop when we see an ampersand!
  • And btw, store the stuff between access_token and the ampersand somewhere so we can grab it later, since it’s marked with parenthesis.

We then call firstMatchInString to check if there’s a matchm, and pull out the first “submatch” (rangeAtIndex:1) to get the access token. We then need to remove the escaped characters in the access token to get the actual value, and then pass that onto our delegate.

So why did we just do all of that work? Again, the access token is what we’ll need in all future calls to the Graph API, such as posing to the wall, uploading photos, etc.

Checking If Manual Login is Required

Two last functions to add:

-(void)checkLoginRequired:(NSString *)urlString {
    if ([urlString rangeOfString:@"login.php"].location != NSNotFound) {
        [_delegate displayRequired];
    }
}
 
- (IBAction)closeTapped:(id)sender {
    [_delegate closeTapped];
}

For checkLoginRequired, we simply check if the “login.php” page shows up in the URL, which appears to work in practice for me. Not sure if there’s a more elegant way to do it than that though.

Finally, if the user taps the close button, we notify our delegate too so he can remove us from display.

Creating Our Main View

Now that we have this fancy Facebook Login Dialog, let’s use it! Open up FBFunViewController.h and replace its contents with the following:

#import <UIKit/UIKit.h>
#import "FBFunLoginDialog.h"
 
typedef enum {
    LoginStateStartup,
    LoginStateLoggingIn,
    LoginStateLoggedIn,
    LoginStateLoggedOut
} LoginState;
 
@interface FBFunViewController : UIViewController <FBFunLoginDialogDelegate> {
    UILabel *_loginStatusLabel;
    UIButton *_loginButton;
    LoginState _loginState;
    FBFunLoginDialog *_loginDialog;
    UIView *_loginDialogView;
}
 
@property (retain) IBOutlet UILabel *loginStatusLabel;
@property (retain) IBOutlet UIButton *loginButton;
@property (retain) FBFunLoginDialog *loginDialog;
@property (retain) IBOutlet UIView *loginDialogView;
 
- (IBAction)loginButtonTapped:(id)sender;
 
@end

Nothing too fancy here. We just create an enum to help us keep track of what state we’re currently in, create a bunch of member variables to keep UI elements that we’ll need, and create an outlet for when the user clicks the login/logout button.

Next open up FBFunViewController.xib and drag a UILabel and a UIButton into the view. Then click Layout\Show Bounds Rectangles to turn on a blue border around each of these, which will make positioning easier. Delete the default text for the button and label, and arrange them on the screen to look similar to the following:

Layout for our Main Facebook View Controller

Then control-drag from “File’s Owner” to the UIButton and UILabel, connecting them to the “loginButton” and “loginStatusLabel”, respectively. Also control-drag from the UIButton back up to the “File’s Owner”, and connect it to the “loginButtonTapped” delegate.

Save your XIB, and let’s head over to FBFunViewController.m to write the implementation. Again there’s a bunch of code here so let’s break it into parts. Start with the following:

#import "FBFunViewController.h"
 
@implementation FBFunViewController
@synthesize loginStatusLabel = _loginStatusLabel;
@synthesize loginButton = _loginButton;
@synthesize loginDialog = _loginDialog;
@synthesize loginDialogView = _loginDialogView;
 
- (void)dealloc {
    self.loginStatusLabel = nil;
    self.loginButton = nil;
    self.loginDialog = nil;
    self.loginDialogView = nil;
    [super dealloc];
}
 
- (void)refresh {
    if (_loginState == LoginStateStartup || _loginState == LoginStateLoggedOut) {
        _loginStatusLabel.text = @"Not connected to Facebook";
        [_loginButton setTitle:@"Login" forState:UIControlStateNormal];
        _loginButton.hidden = NO;
    } else if (_loginState == LoginStateLoggingIn) {
        _loginStatusLabel.text = @"Connecting to Facebook...";
        _loginButton.hidden = YES;
    } else if (_loginState == LoginStateLoggedIn) {
        _loginStatusLabel.text = @"Connected to Facebook";
        [_loginButton setTitle:@"Logout" forState:UIControlStateNormal];
        _loginButton.hidden = NO;
    }   
}
 
- (void)viewWillAppear:(BOOL)animated {
    [self refresh];
}

This is just the boilerplate code to synthesize and deallocate our variables. We also create a refresh method we can call to update our labels and buttons with text to represent our current state.

Calling the Login Dialog

Next add the implementation for when the login button is tapped:

- (IBAction)loginButtonTapped:(id)sender {
 
    NSString *appId = @"8fa673a06891cac667e55d690e27ecbb";
    NSString *permissions = @"publish_stream";
 
    if (_loginDialog == nil) {
        self.loginDialog = [[[FBFunLoginDialog alloc] initWithAppId:appId 
            requestedPermissions:permissions delegate:self] autorelease];
        self.loginDialogView = _loginDialog.view;
    }
 
    if (_loginState == LoginStateStartup || _loginState == LoginStateLoggedOut) {
        _loginState = LoginStateLoggingIn;
        [_loginDialog login];
    } else if (_loginState == LoginStateLoggedIn) {
        _loginState = LoginStateLoggedOut;        
        [_loginDialog logout];
    }
 
    [self refresh];
 
}

First up is our app id, which you get from the Facebook developer’s portal when you create your app. The id in the code is the same ID from the “My Grades” test app we made in the Facebook Connect tutorial. Feel free to use this, or replace it with your own.

Next up we set what extended permissions we want. You can read up on the extended permissions that are available, but for now just know that this is the one you use if you want to post to a user’s wall, or upload photos.

Next we check to see if the login dialog has been created, and if not create it passing in our app id and permissions. Note we also store a reference to the login dialog view, which is retained. You might say to your self: WTFBBQ?

Well, since the view controller is in the background, usually its viewDidLoad will not be called until it is displayed (because that is usually the first time the views are actually needed). This is not good for us, because we want the view (and hence the web view) to be loaded even if it isn’t being displayed, so that it can do some work in the background.

So to trigger that to happen, we just store a reference to the view. Don’t know if there is a better/more elegant way to do that, but this is one way that works.

Next, we check our login state, and either call login or logout on the dialog. We also update our state accordingly, and refresh our display.

Implementing FBFunLoginDialogDelegate

A couple more functions to add and then we’re done: the implementation of the FBFunLoginDialogDelegate!

- (void)accessTokenFound:(NSString *)accessToken {
    NSLog(@"Access token found: %@", accessToken);
    _loginState = LoginStateLoggedIn;
    [self dismissModalViewControllerAnimated:YES];
    [self refresh];
}
 
- (void)displayRequired {
    [self presentModalViewController:_loginDialog animated:YES];
}
 
- (void)closeTapped {
    [self dismissModalViewControllerAnimated:YES];
    _loginState = LoginStateLoggedOut;        
    [_loginDialog logout];
    [self refresh];
}

In accessTokenFound, all we do is print out the access token and dismiss the dialog. Now that we have the access token, we could do all kind of fun things, but this blog post has gone on more than long enough already so we’ll save that for next time :]

In displayRequired, we just present the login dialog so the user can enter their username and password, and in closeDialog we just shut things down.

And that’s it! Compile and run the app, and you should be able to log in and out of Facebook:

Our Completed Facebook Login Dialog

Our Main View Controller Showing We're Logged In

You can also see that it will automatically log you in if you log in, exit the app, restart and log in again, since the cookies will have been saved for your session. However – it appears that the web view must save the cookies periodically in the background, so you’ll have to wait a minute or so after you log in for the cookies to be persisted to disk for it to work.

Where To Go From Here?

Here is a sample project with all of the code we developed in the above Facebook tutorial.

Now that we have a login token, check out the next Facebook tutorial in the series, where we’ll cover how you can use it to get all kinds of interesting data from Facebook – including whether you prefer babes or dudes!

Please comment below if you use or are planning on using the new Facebook Graph API in your Facebook apps – or if you’re just planning on sticking with Facebook Connect for now!

Ray Wenderlich

Ray is an indie software developer currently focusing on iPhone and iPad development, and the administrator of this site. He’s the founder of a small iPhone development studio called Razeware, and is passionate both about making apps and teaching others the techniques to make them.

When Ray’s not programming, he’s probably playing video games, role playing games, or board games.

User Comments

57 Comments

[ 1 , 2 , 3 , 4 ]
  • Hi Ray,
    Thankyou for this wonderful Tutorial. Since i am new to IOS Programming, this tutorial helped me a lot.

    I tried to implement your new Graph API tutorial for IOS 5 which uses Storyboard.
    I just have some issues with the "Calling the Login Dialog". After i press the 'Login' button, my FunLoginDialog page is not Loading.
    When i tried to debug, i found out the view is not loading after in the following code and finally gives Error in main.m page.

    - (IBAction)loginButtonTapped:(id)sender {

    NSString *appId = @"364252050280112";
    NSString *permissions = @"publish_stream";

    if (_loginDialog == nil) {
    self.loginDialog = [[FBFunLoginDialog alloc] initWithAppId:appId
    requestedPermissions:permissions delegate:self];

    self.loginDialogView = _loginDialogView;//Error after this line and not loading FunLoginDialog web view page.
    }
    ...
    ...
    }
    [self refresh];
    }

    I am breaking my head for the past week and would appreciate if you could help me out since i am new to IOS.
    Since I am using Storyboard, Do i have to change that code? If so, Can you help me how?
    Gayathri
  • Is it possible to be able to login into MY Facebook account, behind the scenes, and post pictures to MY wall from my phone, without having the FB dialog popup? I'd like to pass the AppID/Secret/Login/PWD and/or whatever else is needed, from code and then be able to post photos. Thoughts?
    johng1492
  • thank you very much for this great tutorial and for taking the time to do it

    I have a problem is that when using the application I can not login! should not change if the Facebook API but whenever my data entry and I facebook Log me back wing initial window keeps telling me I'm still not connected with facebook

    this is the log

    ?fbconnect=1&skip_api_login=1&m=m&next=https%3A%2F%2Fm.facebook.com%2Fdialog%2Fpermissions.request%3F_path%3Dpermissions.request%26app_id%3D393174900746602%26redirect_uri%3Dhttp%253A%252F%252Fwww.facebook.com%252Fconnect%252Flogin_success.html%26display%3Dtouch%26type%3Duser_agent%26perms%3Dpublish_stream%26fbconnect%3D1%26from_login%3D1%26client_id%3D393174900746602&refsrc=http%3A%2F%2Fm.facebook.com%2Flogin.php&app_id=393174900746602&cancel=http%3A%2F%2Fwww.facebook.com%2Fconnect%2Flogin_success.html%3Ferror_reason%3Duser_denied%26error%3Daccess_denied%26error_description%3DThe%2Buser%2Bdenied%2Byour%2Brequest.&refid=9&e=1348003&email=dcgnomo%40hotmail.com&signup_layout=bottom_link&li=1hJRUO9OWj6rvIypDN2FNL64&_rdr

    i use the xcode 4.3 and ios 5.1 thank you
    dresanl
  • I followed your tutorial closely, but with one change; viz., I created my views (buttons, label, webview, etc) for each of two view controllers in code rather than by using the storyboard. The reason is that the app for which I need this has over 30 screens with a number of dynamic elements, and the storyboard just proved very awkward. I encountered an "Application tried to present modally an active controller <FBFunViewController>..." error when I clicked the Login button on the dialog after providing my particulars. I also tried making it a push connection between FBFunViewController and FBFunLoginDialog, but that didn't even display the Facebook login. My error there I'm sure. I hoped to fare better by downloading your sample project and running that, but I got the same error there too. I don't know what to make of the problem. It would probably be good to know that I am using Xcode 4.4 and iOS 5.1.
    paul@medlock.com
  • Hi Ray wen i'm getting this error message
    Code: Select all
    WebKit discarded an uncaught exception in the webView:decidePolicyForNavigationAction:request:frame:decisionListener: delegate: <NSInvalidArgumentException> Application tried to present modally an active controller


    i also tried with this solution but still facing same problem http://stackoverflow.com/questions/7812061/new-error-in-ios-5-webkit-discarded-an-uncaught-exception#_=_
    Bharat
  • hello,
    im not able to move any further after the login button pressed..:(
    the error shown is...
    *** WebKit discarded an uncaught exception in the webView:decidePolicyForNavigationAction:request:frame:decisionListener: delegate: <NSInvalidArgumentException> Application tried to present modally an active controller <ViewController: 0x718d1f0>.
    but the url i get workes on ma safari web browser in simulator.
    hamdan
  • Hi,

    Really good tutorial, but I have the same problem:

    2013-01-22 13:21:56.889 FBFun[1707:907] *** WebKit discarded an uncaught exception in the webView:decidePolicyForNavigationAction:request:frame:decisionListener: delegate: <NSInvalidArgumentException> Application tried to present modally an active controller <FBFunViewController: 0x1e844c80>.

    I tried this solution: http://stackoverflow.com/questions/7812 ... eption#_=_

    But didn't solve the problem
    rcmcastro
  • Hi!
    You wrote awesome tutorials and they are really helpful for me
    But i stuck in this tutorial
    I follow your steps and did what exactly you mentioned but its not working
    I also tried your sample code of this tutorial but still no solution
    Sir!
    when i run the code and click on login button a web view opens and Facebook UI opens. After entering username and password i press login button but its not working at all no response from that login button.Same case for sign up

    can you please tell me what im doing wrong?..is there any new change in facebook sdk?

    Regards,
    Zeeshan Arif
    zeeshanarif49
  • rabbitrun84 wrote


    "Albert wrote:
    2012-01-14 15:05:53.666 FBFun[961:f803]*** WebKit discarded an uncaught exception in the webView:decidePolicyForNavigationAction:request:frame:decisionListener: delegate: <NSInvalidArgumentException> Application tried to present modally an active controller <ViewController: 0x6c40130>.


    Here's the solution:
    http://stackoverflow.com/questions/7812 ... eption#_=_"


    i have got the same problem but it doesnt solved my problem
    isfando
  • Here is the case study to integrate Open Graph Facebook API into an iPhone & Android Application which I had used in my projects. http://www.spaceotechnologies.com/case- ... plication/
    jigarspaceo
  • thanks helpfull one
    aamir khan
  • *** WebKit discarded an uncaught exception in the webView:decidePolicyForNavigationAction:request:frame:decisionListener: delegate: <NSInvalidArgumentException> Application tried to present modally an active controller <ViewController: 0x6c40130>.


    Here's the solution:
    http://stackoverflow.com/questions/7812 ... eption#_=_" checked this post but not work.

    I run app in ios 7 & i am getting this error & display nothing in web view .

    thanks
    chirag@india
    chirag @ india
[ 1 , 2 , 3 , 4 ]

Other Items of Interest

Ray's Monthly Newsletter

Sign up to receive a monthly newsletter with my favorite dev links, and receive a free epic-length tutorial as a bonus!

Advertise with Us!

Vote for Our Next Tutorial!

Every week, we alternate between Gaming and Non-Gaming tutorial votes. This week: Non-Gaming!

    Loading ... Loading ...

Last week's winner: How to Make a Simple 2D Game with Metal.

Suggest a Tutorial - Past Results

Hang Out With Us!

Every month, we have a free live Tech Talk - come hang out with us!


Coming up in October: Xcode 6 Tips and Tricks!

Sign Up - October

Our Books

Our Team

Tutorial Team

  • Jean-Pierre Distler
  • Matt Galloway

... 53 total!

Update Team

  • Riccardo D'Antoni

... 14 total!

Editorial Team

  • Matt Galloway

... 22 total!

Code Team

  • Orta Therox

... 3 total!

Subject Matter Experts

  • Richard Casey

... 4 total!