Facebook iOS SDK error when requesting user info - objective-c

I'm working on an iPhone application and part of it relies on Facebook integration. I downloaded version 3.1 of the SDK from the website and followed the first tutorial, found at this link: Authenticate.
I'm using iOS 6.0.1 on an iPhone 4 and Xcode 4.5.
Although the login works fine, when following the steps here in order to request basic user information, the application gives the following error:
2013-01-01 23:13:57.966 AppName[8691:907] Error: HTTP status code: 400
2013-01-01 23:13:57.977 AppName[8691:907] FBSDKLog: Response <#1111> <Error>:
The operation couldn’t be completed. (com.facebook.sdk error 5.)
This is the code I'm using to request the information:
if (FBSession.activeSession.isOpen) {
[FBSettings setLoggingBehavior:[NSSet setWithObjects:
FBLoggingBehaviorFBRequests, nil]];
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection,
NSDictionary<FBGraphUser> *aUser,
NSError *error) {
if (!error) {
NSLog(#"%#", [[FBSession activeSession] accessToken]);
userProfileImage.profileID = aUser.id;
self.user = [[User alloc] initWithName:aUser.name andLocation:[aUser.location objectForKey:#"name"]];
[self.user saveUser];
[nameTextField setText:[self.user getName]];
[locationTextField setText:[self.user getLocation]];
}
}];
}
The weird part is that the FBRequest works in the simulator. I checked the access token and I get one on the iPhone too.
One other thing that might be important: On the simulator the application redirects to the Facebook website where it gets authorized(I can view it in my app list on Facebook). On the other hand, when logging in from the device, I only get a standard alert the first time I login and the app doesn't get added on Facebook.
P.S.: This is my first question, so I apologize for the amount (or lack) of information. Thank you in advance for helping me out!

I have been frantically scouring Google for an answer to this for the last couple of days and couldn't find an answer. It was very upsetting, not necessarily because of the bug itself, but because so many people had it, but so few actual answers were given.
The error seems to be a permission issue. If you login from iOS 6, then delete the app from your Facebook, the device will still think you gave the app authorization, thus returning the error. The best answer I could find was here.
Today, after I loaded the app on the device again, without trying the simulator first, it worked like a charm. My advice if you have the same issue is to work on some other code for a while and try again the following day. It's not the perfect solution and I think Apple/Facebook should try and fix that, but it works.

Related

gtm-oauth2 crash on Mac OSX when authenticating with Instagram API

I'm building a small Instagram client for personal use on Mac OSX. I'm currently using gtm-oauth2 to obtain an oauth2 token from Instagram. I'm following the guide provided with the source to obtain this token. I've got it 90% working. The webView loads with the authentication details, and I can enter my account and the permissions screen comes up asking if I would like to grant my application access. The issue I'm running into is that after authenticating, regardless of whether I "Allow" or "Cancel", the application crashes with no stack trace or additional information. The only info I get regarding the exception is "Thread 1: EXC_BAD_ACCESS (code = 1, address=0x4c1)" and it appears that the thread is doing something to do with the WebCore::ResourceLoader, but it's a bunch of ASM so I've got no idea where this call is actually occurring. Perhaps I'm not calling the windowController properly? I've got my code included below.
- (void)signIntoInstagram {
NSURL *tokenURL =[NSURL URLWithString:kTOKENIURl];
// Set up the OAuth request
GTMOAuth2Authentication *auth = [GTMOAuth2Authentication
authenticationWithServiceProvider:#"Instagram"
tokenURL:tokenURL
redirectURI:kREDIRECTURI
clientID:KCLIENTID
clientSecret:KCLIENTSERCRET
];
// Specify the appropriate scope string, if any, according to the service's API documentation
auth.scope = #"basic";
NSURL *authURL = [NSURL URLWithString:KAUTHURL];
// Display the authentication view
GTMOAuth2WindowController *windowController;
windowController = [GTMOAuth2WindowController controllerWithAuthentication:auth
authorizationURL:authURL
keychainItemName:kKeychainItemName
resourceBundle:nil];
// optional: display some html briefly before the sign-in page loads
NSString *html = #"<html><body><div align=center>Loading sign-in page...</div></body></html>";
[windowController setInitialHTMLString:html];
[windowController signInSheetModalForWindow:_window
delegate:self
finishedSelector:#selector(windowController:finishedWithAuth:error:)];}
If I insert a breakpoint within the windowController:finishedWithAuth:error: method, the application is reaching it. However, it still crashes after I run through, which to me seems like some sort of asynchronous operation causing the error. Hopefully I'm just missing something simple here; I can't imagine there is a major flaw in Google's OAuth project.
I found this on a Google group after having the same problem https://groups.google.com/forum/#!msg/gtm-oauth/N6jlOpL9k5g/n4TdrTJyxzcJ . There is also an issue logged for it https://code.google.com/p/gtm-oauth/issues/detail?id=11
Basically I commented out line 331 of GTMOAuth2WindowController.m and it worked. You can also add your vote to the issue and maybe Google will fix it.

Scrumptuous Facebook Sample Doesn't Work on Real iPhone

I downloaded facebook sdk. I run scurmptuous sample there, which is the main sample.
If I run at simulator, the sdk doesn't post anything.
If I run it at my own iPhone I keep getting this
First it goes to
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI {
return [FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
Then it quickly goes to the completion handler. The state of state is
FBSessionStateClosedLoginFailed
IMMEDIATELY
It doesn't seem to try to connect to facebook or doing anything.
In my own program I used the exact same code and can login just fine.
I can run scrumptuous on simulator just fine.
The error code is this:
(lldb) po error
$0 = 0x1e891580 Error Domain=com.facebook.sdk Code=2 "The operation couldn’t be completed. (com.facebook.sdk error 2.)" UserInfo=0x1dd87870 {com.facebook.sdk:ErrorLoginFailedReason=com.facebook.sdk:ErrorLoginFailedReason}
Before at least I can still see which facebook URL is being called and see where things went' wrong. Now nothing. It just (doesn't) works.
It turns out that in settings, facebook is turned of for scrumptuous Turning that to on would fix the issue.
It's not clear, who turn that off. Is off the default? Who knows.
Deleting scrumptuous from the iPhone doesn't make it default to turn on.
This is just right. Most users would not be able to figure out that they got to go to settings and turned on things.

Getting null back from XML, but only on wi-fi only devices

I have an app that incorporates weather...data that I receive from Google's weather API. I'm busting my brain trying to figure out a problem that I'm having and I've been unsuccessful so I figured it was time to ask around on here.
Here is my code:
query = [[NSString stringWithFormat:#"%#",query] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"query: %#",query);
// SET GOOGLE WEATHER XML LOCATION
CXMLDocument *parse = [[CXMLDocument alloc]initWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://www.google.com/ig/api?weather=%#", query]]options:0 error:nil];
NSLog(#"URL: %#", parse);
The query variable holds my reverse geocoder location (e.g. Chicago,IL) for which I append it to the Google URL to get the XML back.
As you can see I'm logging out both the query and the parse variables. I can see that I'm getting a legit query location for my current location when the code is executed, but by the time I log the parse variable I get nothing. The parse logging shows null...nothing was returned from Google. I can see that the URL is correct and I can even go to my browser and get the data I need by using the same logged link.
Interestingly enough...it works perfectly in the simulator and it also works just fine on my iPhone running 5.1.1. I do have iOS6b4 installed on my iPad which is giving the issue, but since I'm not using any new code that was introduced in iOS6 it shouldn't cause any issues here.
Any ideas as to why the XML parsing refuses to work on a wi-fi only iPad?
BTW, before anyone tells me to start using NSXMLParser instead of TouchXML...I do have a test version that runs NSXMLParser instead and I'm getting the same issue there as well. I'm at a loss.
I finally figured this out...it actually had to do with the locationManager.
I had the following code:
if ([locationManager respondsToSelector:#selector(startMonitoringSignificantLocationChanges)]) {
[locationManager startMonitoringSignificantLocationChanges]; }
else {
[locationManager startUpdatingLocation]; }
Getting rid of the if/else statement and just going with the following resolved it:
[locationManager startUpdatingLocation];

Stumped that [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil] keeps returning nil

I have written a simple test application (Mac/Cocoa) to connect to the Key-Value store in iCloud. I seem to be falling at the first fence.
You can see the code for my simple app here and you'll see that I am not getting a URL back from "URLForUbiquityContainerIdentifier" call.
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
if (!ubiq)
NSLog(#"No iCloud");
else
NSLog(#"Yes iCloud");
}
Screenshot of the app running with output:
In term of trying to see if I've everything setup correctly I looked at the setup of my App Id (Test app is called Radio) in the developer provisioning centre:
So that seemed to be ok. Then I re-created my provisioning profile (called Radio Dev 2) and checked that it was using the correct App Id:
Ok, so that also seemed to be ok. I then checked that entitlements was switched on and Key-Value container was activated:
So they are activated. I then took a look at the file itself, just to see if anything jumped out:
So I couldn't see anything jumping out at me in the entitlements file. Lastly, I confirmed that I was signing the build with the correct cert using the provisioning profile that I expected:
I was happy enough with that.
So I'm stumped. I've regenerated everything, etc, to no avail.
I'd really appreciate if anybody has any ideas. Have I missed anything?
Damien's comment on the question had the solution for me. For anyone using Xcode 4.5, you need to click the + below the Ubiquity Containers box. Until I did that, nothing worked.
I faced same problem. I noticed that in my device setting, I didnt logged in my icloud account. once done with adding my account iCloud. The issue was resolved.
In my case, I implement the Parts "Add Document Type" and "Add Exported UTI" of Section "Configuring your Project for iCloud". And, it will not keep return nil anymore.
http://www.raywenderlich.com/12816/icloud-and-uidocument-beyond-the-basics-part-3

Testing internet connection on iPad app using ios5

I have been searching through the forum regarding how to check whether there is internet or not in my ipad app. I just created a simple webview project with other view controllers and I need to display a UIAlert message when the internet is not available. In my case it is displaying the message when I run the app. When I run the app with internet and then deactivate the internet, it does not show the UIAlert message, that is if I switch between the views, it does not any more show the no internet connection.
I have followed this way of implementation in my project: (sorry my mistake this is the link I followed) http://mozymac.com/forums/f54/how-check-if-there-internet-connection-iphone-os-devices-595/ [This is the new edited question]
Apart from that I went through some of the previous questions in Stackoverflow forum like for ex: How to check for an active Internet connection on iOS or OSX?
But everybody has their own version. If any one has a much more updated method for ios5, xcode 4.2.1 of how to accomplish this then would be helpful for me.
Thanks
Is there a reason why you want to check for internet connection before actually trying to load a request in the UIWebView?
Best practice is to just start loading, and use your UIWebViewDelegate/NURLConnectionDelegate to inspect the NSError to see what is wrong. In case of network failure you will receive an error with a domain equal to NSURLErrorDomain. The error code will indicate what the problem is, see the NSError codes enum.
And only after the first error start your reachability to see when the internet connection becomes available again. Or easier, just let the user retry.
Using the Reachability code will actually cause some overhead. It takes time to check if the internet is available, which you could just have used to set up the actual connection as well.
Example
Since you are using a UIWebView you should implement the following delegate method to be notified of errors.
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
if (![[error domain] isEqualToString:NSURLErrorDomain]) {
// not a nsurl error, take other appropriate action
return;
}
NSInteger code = [error code];
// show appropriate error to user, based on code
}
In this delegate method you should do whatever is needed to achieve what you want. You could retry the request yourself, show a message to the user or start listening for reachability changes using the code from the Reachability example provided by Apple.
Apple has one, it's called Reachability. Here's the link to it.
http://developer.apple.com/library/ios/ipad/#samplecode/Reachability/Introduction/Intro.html
Best way to check internet connection is Reachibility application
link
Or else
+ (BOOL)isNetworkAvailable
{
CFNetDiagnosticRef diag;
diag = CFNetDiagnosticCreateWithURL (NULL, (CFURLRef)[NSURL URLWithString:#"www.apple.com"]);
CFNetDiagnosticStatus status;
status = CFNetDiagnosticCopyNetworkStatusPassively (diag, NULL);
CFRelease (diag);
if ( status == kCFNetDiagnosticConnectionUp )
{
//NSLog (#"Connection is up");
return YES;
} else {
NSLog (#"Connection is down");
return NO;
}
}