FBConnect Issues With UIWebView

Discussion in 'iOS Programming' started by newtoiphonesdk, Aug 23, 2010.

  1. macrumors 6502a

    Joined:
    Jul 30, 2010
    #1
    I have an application that uses a Tab Bar for control. In my thirdviewcontroller I have a webview that I would like to be able to program so that people can connect with facebook, and publish the link the webview is on to their facebook wall. I originally tested just the FBConnect without a webview present, and it worked fine. Afterwards, I added the UIWebView. It will build, but when the UIWebView is present, the FBConnect button will not appear. Here is my .h and .m codes.
    .h:
    Code:
    #import <UIKit/UIKit.h>
    #import "FBConnect.h"
    #import "FBSession.h"
    
    
    @interface ThirdViewController : UIViewController {
    	IBOutlet UIWebView *sermons;
    	IBOutlet UIActivityIndicatorView *activity;
    	NSTimer *timer;
    	FBLoginButton *loginButton;
    	UIAlertView *facebookAlert;
    	FBSession *usersession;
    	NSString *username;
    	BOOL post;
    	
    }
    @property(nonatomic,retain) FBLoginButton *loginButton;
    @property(nonatomic,retain) UIAlertView *facebookAlert;
    @property(nonatomic,retain)  FBSession *usersession;
    @property(nonatomic,retain) NSString *username;
    @property(nonatomic,assign) BOOL post;
    @property (nonatomic, retain) UIActivityIndicatorView *activity;
    
    
    
    - (BOOL)textFieldShouldReturn:(UITextField *)textField;
    -(void)getFacebookName;
    -(void)postToWall;
    
    
    @end
    
    .m:
    Code:
    #import "ThirdViewController.h"
    #import "BellAvenueAppDelegate.h"
    
    #define _APP_KEY @"REMOVED FOR PRIVACY"
    #define _SECRET_KEY @"REMOVED FOR PRIVACY"
    
    @implementation ThirdViewController
    @synthesize loginButton;
    @synthesize facebookAlert;
    @synthesize usersession;
    @synthesize username;
    @synthesize post;
    
    - (void)awakeFromNib
    {
    	[sermons loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.316apps.com/iphonesermons.html"]]];
    	timer = [NSTimer scheduledTimerWithTimeInterval:(1.0/2.0) target:self selector:@selector(tick) userInfo:nil repeats:YES];
    	NSString *currentURL = sermons.request.URL.absoluteString;
    }
    
    -(void)tick {
    	if(!sermons.loading)
    		[activity stopAnimating];
    	else 
    		[activity startAnimating];
    	
    }
    /*
     // The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
        if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
            // Custom initialization
        }
        return self;
    }
    */
    
    /*
    // Implement loadView to create a view hierarchy programmatically, without using a nib.
    - (void)loadView {
    }
    */
    
    - (void)viewDidLoad {BellAvenueAppDelegate *appDelegate =
    	(BellAvenueAppDelegate *)   [[UIApplication
    								  sharedApplication]delegate];
    	if (appDelegate._session == nil){
    		appDelegate._session = [FBSession
    								sessionForApplication:_APP_KEY
    								secret:_SECRET_KEY delegate:self];
    	}
    	if(self.loginButton == NULL)
    		self.loginButton = [[[FBLoginButton alloc] init] autorelease];
    	loginButton.frame = CGRectMake(124, 91, 72, 37);
    	[self.view addSubview:loginButton];
    	
        [super viewDidLoad];
    }
    
    /*
    // Override to allow orientations other than the default portrait orientation.
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
        // Return YES for supported orientations
        return (interfaceOrientation == UIInterfaceOrientationPortrait);
    }
    */
    
    - (void)didReceiveMemoryWarning {
        // Releases the view if it doesn't have a superview.
        [super didReceiveMemoryWarning];
        
        // Release any cached data, images, etc that aren't in use.
    }
    
    - (void)viewDidUnload {
        [super viewDidUnload];
        // Release any retained subviews of the main view.
        // e.g. self.myOutlet = nil;
    }
    
    
    - (void)dealloc {
    	[username release];
    	[usersession release];
    	[loginButton release];	
    	[sermons release];
        [super dealloc];
    }
    - (void)session:(FBSession*)session didLogin:(FBUID)uid {
    	self.usersession =session;
    	NSLog(@"User with id %lld logged in.", uid);
    	[self getFacebookName];
    }
    
    - (void)getFacebookName {
    	NSString* fql = [NSString stringWithFormat:
    					 @"select uid,name from user where uid == %lld",
    					 self.usersession.uid];
    	NSDictionary* params =
    	[NSDictionary dictionaryWithObject:fql
    								forKey:@"query"];
    	[[FBRequest requestWithDelegate:self]
    	 call:@"facebook.fql.query" params:params];
    	self.post=YES;
    }
    
    - (void)request:(FBRequest*)request didLoad:(id)result {
    	if ([request.method isEqualToString:@"facebook.fql.query"]) {
    		NSArray* users = result;
    		NSDictionary* user = [users objectAtIndex:0];
    		NSString* name = [user objectForKey:@"name"];
    		self.username = name;
    		
    		if (self.post) {
    			[self postToWall];
    			self.post = NO;
    		}
    	}
    }
    
    - (void)postToWall {
    	
    	FBStreamDialog *dialog = [[[FBStreamDialog alloc] init] autorelease];
    	dialog.userMessagePrompt = @"Enter Your Message Here:";
    	dialog.attachment = [NSString currentURL];
    	[dialog show];
    	
    }
    @end
    
    UPDATE:
    Ok I have it partially solved. Apparently I didn't get very much sleep last night and I have no idea why I did an awakefromnib and viewdidload statements. I moved
    Code:
    [sermons loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.316apps.com/iphonesermons.html"]]];
    	NSString *currentURL = sermons.request.URL.absoluteString;
    
    into the viewdidload, and the FBConnect button will now show. I can login, but when it tries to pull up the publish to wall part, it crashes. Here is what I have for the code for that part.
    Code:
    - (void)postToWall {
    	
    	FBStreamDialog *dialog = [[[FBStreamDialog alloc] init] autorelease];
    	dialog.userMessagePrompt = @"Enter Your Message Here:";
    	dialog.attachment = [NSString currentURL];
    	[dialog show];
    	
    }
    What I want it to do is to post a link of the current URL the user is on. I thought that setting up the NSString in the view did load and then setting the dialog.attachment to that NSString would work, but it constantly crashes. Any ideas?
     
  2. macrumors 6502

    Joined:
    Jun 22, 2010
    Location:
    @
    #2
    Does this line even compile?

    Code:
    dialog.attachment = [NSString currentURL];
    If so, you have presumably added a category to NSString, so please forgive my question :)
     
  3. thread starter macrumors 6502a

    Joined:
    Jul 30, 2010
    #3
    Everything builds fine, it just crashes when it tries to pull up the dialog box for publishing something to the wall. I do get the warning NSString may not respond to +currenturl
     
  4. macrumors 6502

    Joined:
    Jun 22, 2010
    Location:
    @
    #4
    Ah, ok, the thing is -- that warning, in this case, is fatal. NSString does not respond to +currentURL (try right-clicking on currentURL in XCode and selecting "Find Text in Documentation").

    More generally, I recommend treating "may not respond to" warnings as errors. The compiler does not have enough information to verify that a certain method exists -- and therefore it is very unlikely that correct behaviour will ensue.

    In my projects the Project Build setting is configured with "Treat Warnings as Errors" enabled. A little extreme, perhaps, but it forces one to listen to what the compiler is saying... :D
     
  5. thread starter macrumors 6502a

    Joined:
    Jul 30, 2010
    #5
    I declared it
    Code:
    @interface ThirdViewController : UIViewController {
    	IBOutlet UIWebView *sermons;
    	IBOutlet UIActivityIndicatorView *activity;
    	NSTimer *timer;
    	FBLoginButton *loginButton;
    	UIAlertView *facebookAlert;
    	FBSession *usersession;
    	NSString *username;
    	BOOL post;
    	NSString *currentURL;
    	
    }
    @property(nonatomic,retain) FBLoginButton *loginButton;
    @property(nonatomic,retain) UIAlertView *facebookAlert;
    @property(nonatomic,retain)  FBSession *usersession;
    @property(nonatomic,retain) NSString *username;
    @property(nonatomic,assign) BOOL post;
    @property (nonatomic, retain) UIActivityIndicatorView *activity;
    @property (nonatomic, retain) NSString *currentURL;
    I changed it in the post to wall function
    Code:
    - (void)postToWall {
    	
    	FBStreamDialog *dialog = [[[FBStreamDialog alloc] init] autorelease];
    	dialog.userMessagePrompt = @"Enter Your Message Here:";
    	dialog.attachment = currentURL;
    	[dialog show];
    	
    }
    
    The warning went away on the dialog.attachment line when I changed it.

    What I have in the ViewDidLoad is this
    Code:
    - (void)viewDidLoad {BellAvenueAppDelegate *appDelegate =
    	(BellAvenueAppDelegate *)   [[UIApplication
    								  sharedApplication]delegate];
    	if (appDelegate._session == nil){
    		appDelegate._session = [FBSession
    								sessionForApplication:_APP_KEY
    								secret:_SECRET_KEY delegate:self];
    	}
    	if(self.loginButton == NULL)
    		self.loginButton = [[[FBLoginButton alloc] init] autorelease];
    	loginButton.frame = CGRectMake(124, 91, 72, 37);
    	[self.view addSubview:loginButton];
    	[sermons loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.316apps.com/iphonesermons.html"]]];
    	NSString *currentURL = sermons.request.URL.absoluteString;
    	
        [super viewDidLoad];
    }
    When I build I get the warning on the NSString Line 'unused variable currentURL' and it still crashes.
     
  6. macrumors 6502

    Joined:
    Jun 22, 2010
    Location:
    @
    #6
    Listen to what the compiler is telling you, and review your understanding about variable declaration versus variable assignment. You are nearly there :)
     
  7. macrumors 603

    Joined:
    Aug 9, 2009
  8. thread starter macrumors 6502a

    Joined:
    Jul 30, 2010
    #8
    I left it as
    Code:
    [sermons loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.316apps.com/iphonesermons.html"]]];
    	NSString *currentURL = sermons.request.URL.absoluteString;
        [super viewDidLoad];
    
    And put a breakpoint in at the dialog.attachment line.
    It crashed the app when attempting to redirect to the publish on wall part of the app. Debugger showed the following:
    Code:
    0x94d8aef6 <+0010> jae 0x94d8af06 <__kill+26>
    I then ran it with the
    Code:
    self.currentURL = sermons.request.URL.absoluteString;
    in the ViewDidLoad instance and put in a breakpoint. Debugger came up with this.
    Code:
    2010-08-23 15:19:06.506 Bell Avenue[6313:207] -[ThirdViewController setCurrentURL:]: unrecognized selector sent to instance 0x743f170
    2010-08-23 15:19:06.510 Bell Avenue[6313:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ThirdViewController setCurrentURL:]: unrecognized selector sent to instance 0x743f170'
    *** Call stack at first throw:
    (
    	0   CoreFoundation                      0x026f0919 __exceptionPreprocess + 185
    	1   libobjc.A.dylib                     0x0283e5de objc_exception_throw + 47
    	2   CoreFoundation                      0x026f242b -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
    	3   CoreFoundation                      0x02662116 ___forwarding___ + 966
    	4   CoreFoundation                      0x02661cd2 _CF_forwarding_prep_0 + 50
    	5   Bell Avenue                         0x00002ec3 -[ThirdViewController viewDidLoad] + 747
    	6   UIKit                               0x004cc924 -[UINib instantiateWithOwner:options:] + 1556
    	7   UIKit                               0x004ce4b5 -[NSBundle(UINSBundleAdditions) loadNibNamed:owner:options:] + 168
    	8   UIKit                               0x002dd9bb -[UIApplication _loadMainNibFile] + 172
    	9   UIKit                               0x002de90d -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 198
    	10  UIKit                               0x002e8452 -[UIApplication handleEvent:withNewEvent:] + 1958
    	11  UIKit                               0x002e1074 -[UIApplication sendEvent:] + 71
    	12  UIKit                               0x002e5ac4 _UIApplicationHandleEvent + 7495
    	13  GraphicsServices                    0x02f56afa PurpleEventCallback + 1578
    	14  CoreFoundation                      0x026d1dc4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
    	15  CoreFoundation                      0x02632737 __CFRunLoopDoSource1 + 215
    	16  CoreFoundation                      0x0262f9c3 __CFRunLoopRun + 979
    	17  CoreFoundation                      0x0262f280 CFRunLoopRunSpecific + 208
    	18  CoreFoundation                      0x0262f1a1 CFRunLoopRunInMode + 97
    	19  UIKit                               0x002de226 -[UIApplication _run] + 625
    	20  UIKit                               0x002e9b58 UIApplicationMain + 1160
    	21  Bell Avenue                         0x00002370 main + 102
    	22  Bell Avenue                         0x00002301 start + 53
    )
    terminate called after throwing an instance of 'NSException'
     
  9. macrumors 6502

    Joined:
    Jun 22, 2010
    Location:
    @
    #9
    CHECK the compiler warnings.

    Sorry to shout. This is important. The crash message "unrecognized selector sent to" indicates missing code relating to the property definition for 'currentURL'.

    You can do this! Trust yourself, and listen to the compiler :D
     
  10. thread starter macrumors 6502a

    Joined:
    Jul 30, 2010
    #10
    I figured out part of the problem. I forgot to synthesize currentURL. This fixed the viewdidload part of my code. However when I get to post to wall, it is still crashing at the dialog.attachment line of code.
     
  11. macrumors 6502

    Joined:
    Jun 22, 2010
    Location:
    @
    #11
  12. thread starter macrumors 6502a

    Joined:
    Jul 30, 2010
    #12
    I would assume the currentURL is in standard HTTP format.

    I declare the NSString currentURL and synthesize it, the viewdidload is this
    Code:
    - (void)viewDidLoad {BellAvenueAppDelegate *appDelegate =
    	(BellAvenueAppDelegate *)   [[UIApplication
    								  sharedApplication]delegate];
    	if (appDelegate._session == nil){
    		appDelegate._session = [FBSession
    								sessionForApplication:_APP_KEY
    								secret:_SECRET_KEY delegate:self];
    	}
    	if(self.loginButton == NULL)
    		self.loginButton = [[[FBLoginButton alloc] init] autorelease];
    	loginButton.frame = CGRectMake(124, 91, 72, 37);
    	[self.view addSubview:loginButton];
    	[sermons loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.316apps.com/iphonesermons.html"]]];
    	self.currentURL = sermons.request.URL.absoluteString;
        [super viewDidLoad];
    }
    the post to wall is this
    Code:
    - (void)postToWall {
    	
    	FBStreamDialog *dialog = [[[FBStreamDialog alloc] init] autorelease];
    	dialog.userMessagePrompt = @"Enter Your Message Here:";
    	dialog.attachment = self.currentURL;
    	[dialog show];
    	
    }
    
    UPDATE:
    I cleaned all targets and it will now run without errors, and post to facebook, but it simply will not post the link of the webview's currentURL, it just stays blank.
     
  13. macrumors 6502

    Joined:
    Jun 22, 2010
    Location:
    @
    #13
  14. thread starter macrumors 6502a

    Joined:
    Jul 30, 2010
    #14
    Yea but it seems that you can put stuff there, but it stays the same. I was wanting to use it with a blog page so someone could post their story they are looking at
     
  15. macrumors 6502

    Joined:
    Jun 22, 2010
    Location:
    @
    #15
    Just to be clear...
    • Is the code is now successfully posting blank information to your facebook time-line?
    • And is the attachment parameter structured, like in the sample code?
     
  16. thread starter macrumors 6502a

    Joined:
    Jul 30, 2010
    #16
    It posts a blank message to facebook. I don't really have it structured any. All I have on dialog.attachment is currentURL. Do I need to define currenturl in some way?
     
  17. macrumors 6502

    Joined:
    Jun 22, 2010
    Location:
    @
    #17
  18. thread starter macrumors 6502a

    Joined:
    Jul 30, 2010
    #18
    How do I adjust the dialog.attachment to have it post the currenturl? Everything on that post is in "". Doesn't that mean I can change the text and website to something I manually type in, not what is in the currenturl?
     
  19. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #19
    You already seem to know how to use NSString's stringWithFormat:. Here's an opportunity to use it again.
     
  20. thread starter macrumors 6502a

    Joined:
    Jul 30, 2010
    #20
    But how would I implement the currenturl into the stringwithformat
     
  21. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #21
    Hmm, I guess I was wrong. You don't seem to know how to use it.

    I think, based on this and your various queries throughout these forums, that it would behoove you to step away from the real coding and go learn the basics of Objective-C and iPhone development. Find some guided introduction: a book or some tutorials (hint). Giving yourself a proper foundation is only going to help you in the long run. Learning the fundamentals should allow you to start to creatively put together your own code based on your own needs.
     
  22. thread starter macrumors 6502a

    Joined:
    Jul 30, 2010
    #22
    Can you not help me in this one instance? I am so close to having this figured out right now
     
  23. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #23
    Help you how? By giving you the answer? That I won't do.

    Have you tried reading the documentation for stringWithFormat: ? If or when you have, come back and ask specific questions about things you don't understand and we can move further.
     
  24. thread starter macrumors 6502a

    Joined:
    Jul 30, 2010
    #24
    Ok, here is a different yet similar question. I have the MFMailcomposersheet setup in this as well, attempting to do the same basic thing, email what is in the webview. I set this.
    Code:
    -(void)displayComposerSheet 
    {
    	MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
    	picker.mailComposeDelegate = self;
    	
    	[picker setSubject:@"Guest Form"];
    	
    	
    	// Set up recipients
    	NSArray *toRecipients = [NSArray arrayWithObject:@"bacoc@amaonline.com"]; 
    	
    	[picker setToRecipients:toRecipients];
    	
    	// Fill out the email body text
    	NSString *emailBody = self.currentURL;
    	[picker setMessageBody:emailBody isHTML:YES];
    	
    	[self presentModalViewController:picker animated:YES];
        [picker release];
    }
    It opens up the composer sheet, but the emailbody stays blank. I tried changing self.currentURL to NSString stringWithFormat:currentURL and it won't compile.
     
  25. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #25
    Not sure why we needed to take this from a different tact but okay...

    Time for some basic debugging. What is the value of emailBody before you use it for setMessageBody:?

    Won't compile? Why not? Be specific. Errors/warnings/what?
     

Share This Page