When is Facebook Connect supposed to call its delegate methods? - iphone

The Facebook connect code is eluding me a bit.
I have no problem doing a login, and a wall post, however, I simply can not
figure out how the delegate methods for the FBDialog andFBStreamDialog is supposed to work.
- (void)postToWall {
FBStreamDialog *dialog = [[[FBStreamDialog alloc] init] autorelease];
dialog.delegate = self;
dialog.userMessagePrompt = #"Enter your message:";
dialog.attachment = [NSString stringWithFormat:#"JSONpost code"];
[dialog show];
}
I adhere to these protocols in my controller:
<FBDialogDelegate, FBSessionDelegate, FBRequestDelegate>
I then implement the two methods:
- (void) dialogDidCancel:(FBDialog *)dialog {
NSLog(#"Failed");
}
- (void) dialogDidSucceed:(FBDialog *)dialog {
NSLog(#"Success");
}
After I tap "publish" and the postToWall methods is done executing the Facebook "pop up" in the UI is empty, except a small "X" in the top right corner and a "F" (facebook logo) in the top left corner.
The UI will stay there until I tap the "X", this results in the dialogDidCancel delegate method being called. The post data is showing up on the Facebook page, everything seems to work.
Why is thedialogDidSucceedmethod never called? I need this to release my facebook controller and restore the UI back to where the user was before "starting" FB Connect.
Thank You:)

Facebook has fixed this issue, as you can see from their post at:
http://bugs.developers.facebook.com/show_bug.cgi?id=10531

I see where the problem is, but not sure what if anything we can do about it. It happens in the UIWebView Delegate method in the FBDialog class. If you click the Skip button, the request.URL is populated with 'fbconnect:success', it should really be 'fbconnect:cancel' but other people have already pointed out this problem out before. Our problem is that when you click the Publish button, the request.URL should read 'fbconnect:success' however, it ends up containing 'http://www.facebook.com/fbconnect/prompt_feed.php', so, it never calls dismissWithSuccess:YES or dialogDidSucceed.
I can't find anyplace where the Publish button's post URL is set, but if we can change it to fbconnect:success, it might work.
FBDialog.m
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
NSURL* url = request.URL;
if ([url.scheme isEqualToString:#"fbconnect"]) {
if ([url.resourceSpecifier isEqualToString:#"cancel"]) {
[self dismissWithSuccess:NO animated:YES];
} else {
[self dialogDidSucceed:url];
}
return NO;
} else if ([_loadingURL isEqual:url]) {
return YES;
} else if (navigationType == UIWebViewNavigationTypeLinkClicked) {
if ([_delegate respondsToSelector:#selector(dialog:shouldOpenURLInExternalBrowser:)]) {
if (![_delegate dialog:self shouldOpenURLInExternalBrowser:url]) {
return NO;
}
}
[[UIApplication sharedApplication] openURL:request.URL];
return NO;
} else {
return YES;
}
}

Related

ios - UIWebView DidFinishLoad not being called

I have a UIWebView that works ok. The delegate is working. When I open a URL, events shouldStartLoadWithRequest and webViewDidFinishLoad are fired.
But when for example I click on a Google search result, only shouldStartLoadWithRequest is fired, and webViewDidFinishLoad is never called.
This is causing problems because if I put a "loading..." indicator on shouldStartLoadWithRequest, in these cases the indicator still remains even after the page is correctly loaded.
Any idea why this is happening?
in .h file add <UIWebViewDelegate>
and in .m:
yourWebview=[[UIWebView alloc]init];
yourWebview.delegate=self;
When you click on search, the navigationType is UIWebViewNavigationTypeFormSubmitted. So in this case, the return type should be YES. If it is not, webViewDidFinishLoad method is not fired.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSLog(#"shouldStartLoadWithRequest");
if ( navigationType == UIWebViewNavigationTypeLinkClicked ){
NSLog(#"UIWebViewNavigationTypeLinkClicked");
return YES;
}
if (navigationType ==UIWebViewNavigationTypeFormSubmitted ) {
NSLog(#"UIWebViewNavigationTypeFormSubmitted");
return YES;
}
if (navigationType ==UIWebViewNavigationTypeBackForward) {
NSLog(#"UIWebViewNavigationTypeBackForward");
return YES;
}
if (navigationType ==UIWebViewNavigationTypeFormResubmitted) {
NSLog(#"UIWebViewNavigationTypeFormResubmitted");
return YES;
}
if (navigationType ==UIWebViewNavigationTypeReload) {
NSLog(#"UIWebViewNavigationTypeReload");
return YES;
}
return YES;
}
This problem is usually found on ipad applications .... but you can solve your problem by using [self performselector:afterdelay] , you have to check in selector method whether webview has loaded or not using [m_pWebview loaded]; and according to that perform indicator stopping .... it's not the proper solution but it works .......
Not an expert on Google API, but as I suspected this might be your reason.

Getting signals from uiwebview

Is there a possibility to get a signal from a uiwebview?
In my case, I display a webpage in the webview. When the user presses a button on the website, my App should (also) react to this.
Thanks for help
Yes you can do this. Implement
– webView:shouldStartLoadWithRequest:navigationType:
This delegate . This method gets called whenever your webview is about to make a request. So now when someone clicks a button on your webpage, you will get a call to this method. After you catch this call, you can choose to do whatever you want with it. Like redirect the link through your own servers, or log a request to your server about user activity etc.
Example - here you are trying to intercept any links clicked on your webpage & pass it through myMethodAction first.
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
if(navigationType == UIWebViewNavigationTypeLinkClicked)
{
if(overrideLinksSwitch.on == TRUE)
{
[self myMethodAction];
[myWebView stopLoading];
return YES;
}
else
{
return YES;
}
}
return YES;
}
Hope this helps...
UIWebViewDelegate provide several methods. I had used one of them like this
-(BOOL) webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType {
if ( inType == UIWebViewNavigationTypeLinkClicked ) {
// do stuff
return NO;
}
return YES;
}

How to post tweet from iPhone without PIN using SA_OAuthTwitterEngine?

I am developing a iPhone application which sends tweets to twitter. For this I am using SA_OAuthTwitterEngine + MGTwitterEngine classes.
I register applicaiton to www.twitter.com/apps and pass Consumer key and Consumer secret to controller my code is this.
if(!_engine){
_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];
_engine.consumerKey = slPcFUjUh5y1hex0zvEhPg;
_engine.consumerSecret = u6ydovMdP9yeiVqDukVhIzZPgJR9XDPUwfxymzNs;
}
UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine:_engine delegate:self];
if (controller){
[self presentModalViewController: controller animated: YES];
intTwitterFlag = 1;
}
Previously on twitter.com/apps I select Application type = client and my application will generate PIN and accessToken. But when i change my Application type = Browser it cannot generate PIN and accessToken.
Previously when application type is client i am giving user name and password and then control return to my application from the webview but now after entering user name and password it cannot dismissModalViewController but showing Select and Copy the PIN.
Thank you for your time and any help you can give me!
Here it is:just replace the method in SA_OAuthTwitterController.m:
- (void) webViewDidFinishLoad: (UIWebView *) webView {
_loading = NO;
//[self performInjection];
if (_firstLoad) {
[_webView performSelector: #selector(stringByEvaluatingJavaScriptFromString:) withObject: #"window.scrollBy(0,200)" afterDelay: 0];
_firstLoad = NO;
} else {
/*
NSString *authPin = [self locateAuthPinInWebView: webView];
NSLog(#"authPin: %#", authPin);
if (authPin.length) {
[self gotPin: authPin];
return;
}
NSString *formCount = [webView stringByEvaluatingJavaScriptFromString: #"document.forms.length"];
if ([formCount isEqualToString: #"0"]) {
[self showPinCopyPrompt];
}*/
//*****************************************************
// This is to bypass the pin requirement
// in case the call back URL is set in Twitter settings
//*****************************************************
[_engine requestAccessToken];
if ([_delegate respondsToSelector: #selector(OAuthTwitterController:authenticatedWithUsername:)])
{
[_delegate OAuthTwitterController: self authenticatedWithUsername: _engine.username];
}
[self performSelector: #selector(dismissModalViewControllerAnimated:) withObject: (id) kCFBooleanTrue afterDelay: 1.0];
//[self dismissModalViewControllerAnimated:YES];
}
[UIView beginAnimations: nil context: nil];
_blockerView.alpha = 0.0;
[UIView commitAnimations];
if ([_webView isLoading]) {
_webView.alpha = 0.0;
} else {
_webView.alpha = 1.0;
}
}
I too faced the same issue, and i just removed callback url from the twitter app settings. For my surprise login proceeds without any issue.
The replacement for this method
(void) webViewDidFinishLoad: (UIWebView *) webView
in the class SA_OAuthTwitterController.m works well.
Its better to use xAuth route for mobile apps
http://dev.twitter.com/pages/xauth
check XAuthTwitterEngine which implements xauth for the MGTwitterEngine

problem with intergating facebook session

I am using Facebook in my music application where user post comment on wall paper after listening the songs . So problem arises that user have to login again for next song. so please provide me code for session retains when he clicked on the tab where it written "keep me login".
Thanks
I have a file called FacebookHelper.m, here is the code there:
- (id)init {
if (self = [super init]) {
session_ = [[FBSession sessionForApplication:kAPIKey secret:kApplicationSecret delegate:self] retain];
[session_ resume];
}
return self;
}
If you want to control the login dialog yourself, here is the code:
- (void)loginByShowingDialog {
self.isDialogShown = YES;
FBLoginDialog* dialog = [[[FBLoginDialog alloc] initWithSession:self.session] autorelease];
dialog.delegate = self;
[dialog show];
}
For your cases, I think you only need to get the session back and resume it.

Adding the Facebook Like Button in an iPhone App

Does anyone know how I would include a facbeook "like button" in an iphone app. I tried calling the iframe inside of a UIWebView but that doesn't work.
Check out this nice bit of code:
http://angelolloqui.blogspot.com/2010/11/facebook-like-button-on-ios.html
Add the FBLikeButton class to your view:
FBLikeButton *likeButton = [[FBLikeButton alloc] initWithFrame:CGRectMake(0, 372, 320, 44)
andUrl:#"http://www.facebook.com/pages/De-Zilk/108209735867960"];
Thanks a lot Angel García Olloqui
EDIT: Nice to add... For bonus points:
If you use above method the webpage is not well formatted for an iPhone. What you can do is run some JavaScript code to remove all the disturbing divs. Use this (long sentence):
[_webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:#"javascript:document.getElementsByClassName('uiButton')[2].style.visibility='hidden';var child1 = document.getElementById('standard_status');var parent1 = document.getElementById('login_form');parent1.removeChild(child1);var child2 = document.getElementById('pageheader');var parent2 = document.getElementById('booklet');parent2.removeChild(child2);document.getElementById('loginform').style.width = '200px';var child3 = document.getElementById('reg_btn_link');var parent3 = document.getElementsByClassName('register_link')[0];parent3.removeChild(child3);var child4 = document.getElementById('signup_area');var parent4 = document.getElementById('login_form');parent4.removeChild(child4);var child5 = document.getElementsByClassName('mbm')[0];var parent5 = document.getElementById('loginform');parent5.removeChild(child5);var child6 = document.getElementsByClassName('reset_password form_row')[0];var parent6 = document.getElementById('loginform');parent6.removeChild(child6);var child7 = document.getElementsByClassName('persistent')[0];var parent7 = document.getElementById('loginform');parent7.removeChild(child7);"]];
You can place it in the delegate method webViewDidFinishLoad from the FBDialog Facebook class.
Fb like Widget can be embedded in our application. You just have to add a webView and get the Fb Like Widget html code/URL here.
in ViewController.h where you want to add fb like button:
#import <UIKit/UIKit.h>
#interface TestViewController : UIViewController <UIWebViewDelegate>
#property (strong, nonatomic) UIWebView * fbLikeWebView;
-(void)embedFBLikeButton;
#end
in TestViewController.m
#import "AboutUsViewController.h"
#implementation AboutUsViewController
#synthesize fbLikeWebView = _fbLikeWebView;
- (void)viewDidLoad
{
[super viewDidLoad];
//Add this code for FbLike Webview
self.fbLikeWebView = [[UIWebView alloc] initWithFrame: CGRectMake(100.0, 50.0, 55.0, 70.0)];
_fbLikeWebView.opaque = NO;
_fbLikeWebView.backgroundColor = [UIColor clearColor];
_fbLikeWebView.delegate = self;
[self.view addSubview:_fbLikeWebView];
for (UIScrollView *subview in _fbLikeWebView.subviews)
{
if ([subview isKindOfClass:[UIScrollView class]]) {
subview.scrollEnabled = NO;
subview.bounces = NO;
}
}
}
then in ViewWillAppear method call the enbeddFBLikeButton Method to add the fbLike button wigdet on web view:
-(void)viewWillAppear:(BOOL)animated
{
[self embedFBLikeButton];
[_fbLikeWebView reload];
}
-(void)embedFBLikeButton
{
NSString *facebookUrl = //here paste the url you get from fb developer link above;
[self.fbLikeWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:facebookUrl]]];
}
You conform to UIWebViewDelegate now its turn to defining th edelegate method here:
#pragma mark - WebView Delgate Methods
- (BOOL)webView:(UIWebView *)webview shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if ([request.URL.lastPathComponent isEqualToString:#"login.php"])
{
[self login];
return NO;
}
return YES;
}
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
[_fbLikeWebView stopLoading];
}
This method for login the user to facebook Account:
- (void)login
{
[FBSession setActiveSession: [[FBSession alloc] initWithPermissions:#[#"publish_actions", #"publish_stream", #"user_photos"]]];
[[FBSession activeSession] openWithBehavior: FBSessionLoginBehaviorForcingWebView completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
switch (status) {
case FBSessionStateOpen:
// call the legacy session delegate
//Now the session is open do corresponding UI changes
if (session.isOpen) {
FBRequest *me = [FBRequest requestForMe];
[me startWithCompletionHandler: ^(FBRequestConnection *connection,
NSDictionary<FBGraphUser> *my,
NSError *error) {
if (!my) {
NSLog(#"Facebook error:\n%#", error.description);
[[[UIAlertView alloc] initWithTitle: #"Error"
message: #"Facebook Login error."
delegate: self
cancelButtonTitle: #"Ok"
otherButtonTitles: nil, nil] show];
return;
}
}];
[_fbLikeWebView reload];
[[[UIAlertView alloc] initWithTitle: #""
message: #"Successfully Login. Please click on like button"
delegate: self
cancelButtonTitle: #"Ok"
otherButtonTitles: nil, nil] show];
}
break;
case FBSessionStateClosedLoginFailed:
{
[_fbLikeWebView reload];
}
break;
default:
break; // so we do nothing in response to those state transitions
}
}];
}
It is an old question, but we just got the answer
By using fb sdk now we can simply add the like button
FBLikeControl *likeButton = [[FBLikeControl alloc] init];
like.objectID = #"http://ihackthati.wordpress.com/photo1/";
[self addSubview:like];
https://developers.facebook.com/docs/ios/like-button/
Several of the solutions above (e.g. #floorjiann, #fabiobeta, #Stephen-Darlington, #scott) assume that the iPhone application is also a Facebook application (with its own id).
However if your iPhone application just has a fan page, this is not the case.
You can include it in a UIWebView, just make sure it's inside <html><body>. The problem is that once the user clicks the button, the UIWebView may redirect to a log-in form, so you would have to make it large enough to fit that thing.
Have fun creating a design that presents the button in a sensible fashion.
maybe this is helpful
http://www.raywenderlich.com/1626/how-to-post-to-a-users-wall-upload-photos-and-add-a-like-button-from-your-iphone-app
Facebook have recently updated their iPhone Facebook Connect framework to work with the Graph API. This is the API that you need to "Like" objects on Facebook.
Here you go - w the source code...enjoy -and please leave a comment if its useful.
http://nowbranded.com/blog/adding-a-facebook-like-button-to-an-iphone-application/
First check your authentication on Facebook, then use url code instead of iFrame like this:
NSURL *url = [NSURL URLWithString:#"http://www.facebook.com/plugins/like.php?href=https%3A%2F%2Fwww.facebook.com%2FRemtechConfessionChambers&width=200&height=80&colorscheme=light&layout=standard&action=like&show_faces=true&send=false"];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
[webViewFb loadRequest:req];
You can use the open source SOOMLA Profile plugin:
https://github.com/soomla/ios-profile
There are code examples there for lots of Facebook related actions (login, like, share status, upload image, get contacts, invite, etc.). See:
https://github.com/soomla/ios-profile/blob/master/SoomlaiOSProfileExample/SoomlaiOSProfileExample/ViewController.m
I this moment in time you can't. The mobile APIs are not exposing this capability.
You can use some workaround consisting in embedding the html way of doing it in your app.
Some details on the workaround here: http://petersteinberger.com/2010/06/add-facebook-like-button-with-facebook-connect-iphone-sdk/