Facebook SDK FBLoginView getting EXC_BAD_ACCESS - iphone

I'm following the HelloFacebookSample project bundled with the Facebook SDK 3.5. I've virtually copied and pasted everything into my own app, even the stuff from the AppDelegate, yet for some reason clicking the Login button freezes my app. Just for the record, everything authenticates correctly when connecting to the integrated framework in iOS 6, which is done through the FB SDK anyway. It's only when I try to log in using the web, i.e. hit the FBLoginView website opens, get authenticated, return to app. Here is the code in the samepl project, and I'll compare it to mine:
FBLoginView *loginview = [[FBLoginView alloc] init];
loginview.frame = CGRectOffset(loginview.frame, 5, 5);
loginview.delegate = self;
[self.view addSubview:loginview];
[loginview sizeToFit];
Mine is a little different:
loginview = [[FBLoginView alloc] init];
loginview.delegate = self;
[self.facebookCell addSubview:loginview];
[loginview sizeToFit];
As for the delegate methods, I've implemented them all verbatim. Why does the app crash? There is no valid reason for a crash when all the code is pretty much identical between my app and the sample app. The debugger doesn't help much even with Zombie Objects on. The actual error is: Thread 1: EXC_BAD_ACCESS (code=2, address=somethingoranother) Anyone got any ideas as to why this is happening?
Regards,
Mike
UPDATE: It appears that the crash happens because something is recurring infinitely on a loop. Seems like over 100,000 processes were put on the main thread by the FB SDK! How?!
UPDATE 2: I'm beginning to think the error is here, even though I copied this straight from the sample AppDelegate.
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
// attempt to extract a token from the url
return [FBAppCall handleOpenURL:url
sourceApplication:sourceApplication
fallbackHandler:^(FBAppCall *call) {
NSLog(#"In fallback handler");
}];
}
Does this help at all?

I'm having whats seems to be the exact problem, but I have my application sandbox mode already disabled. This app has been working perfectly before, but I just upgraded the SDK and now this happens.
If I have a facebook account configured in iOs, it will work ok, but if not, It will crash.
One thing worth mentioning is if I remove the url scheme, so the app can't go to the web browser or the facebook app, It will user a web view to log in and this works too
EDIT: As far as I'm able to tell, my problem relies in not having access to my application settings in facebook.
The facebook SDK does an [FBUtility fetchAppSettings:callback:] call, more specifically, it does an
https://graph.facebook.com/267496536695242?fields=supports_attribution,supports_implicit_sdk_logging,suppress_native_ios_gdp,name,
which in the case of my app fails with:
{
"error": {
"message": "Unsupported get request.",
"type": "GraphMethodException",
"code": 100
}
}
In comparision, any of the examples apps, for example this one, SessionLoginSample
https://graph.facebook.com/380615018626574?fields=supports_attribution,supports_implicit_sdk_logging,suppress_native_ios_gdp,name
returns correctly this:
{
"supports_attribution": true,
"supports_implicit_sdk_logging": true,
"suppress_native_ios_gdp": 0,
"name": "SessionLoginSample",
"id": "380615018626574"
}
Because the SDK expects something it keeps making the same request and gets stuck in a loop until the simulator crashes.
To confirm this, I've manually inserted the expected parameters in the callback, modifyng the facebook sdk, and now everything work perfectly.
It's worth mentioning that I upgraded the SDK from 2.0 which was deprecated, and there was a few parameters in the settings page that were outdated (no client token set, authorization as native/Desktop instead Web, without having the app secret key in the app) but I've already set them alright..
EDIT 2:
This is the method from Facebook SDK (in FBUtility.m) that I've modified. I only added the "bad stuff" if clause.
+ (void)fetchAppSettings:(NSString *)appID
callback:(void (^)(FBFetchedAppSettings *, NSError *))callback {
if (!g_fetchedAppSettingsError && !g_fetchedAppSettings) {
NSString *pingPath = [NSString stringWithFormat:#"%#?fields=supports_attribution,supports_implicit_sdk_logging,suppress_native_ios_gdp,name", appID, nil];
FBRequest *pingRequest = [[[FBRequest alloc] initWithSession:nil graphPath:pingPath] autorelease];
if ([pingRequest startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
// Bad stuff
if (error) {
error = nil;
result = [NSDictionary dictionaryWithObjectsAndKeys:#"true", #"supports_attribution",
#"true", #"supports_implicit_sdk_logging",
#"0", #"suppress_native_ios_gdp",
#"Your_App_Display_Name", #"name", nil];
}
if (error) {
g_fetchedAppSettingsError = error;
[g_fetchedAppSettingsError retain];
} else {
g_fetchedAppSettings = [[[FBFetchedAppSettings alloc] init] retain];
if ([result respondsToSelector:#selector(objectForKey:)]) {
g_fetchedAppSettings.serverAppName = [result objectForKey:#"name"];
g_fetchedAppSettings.supportsAttribution = [[result objectForKey:#"supports_attribution"] boolValue];
g_fetchedAppSettings.supportsImplicitSdkLogging = [[result objectForKey:#"supports_implicit_sdk_logging"] boolValue];
g_fetchedAppSettings.suppressNativeGdp = [[result objectForKey:#"suppress_native_ios_gdp"] boolValue];
}
}
[FBUtility callTheFetchAppSettingsCallback:callback];
}
]
);
} else {
[FBUtility callTheFetchAppSettingsCallback:callback];
}
}

Someone found the answer on another thread. In the Facebook Developer centre, the app was set to Sandboxing mode which is what caused this error. Seems it wasn't a problem with the code after all.

Facebook has fixed a server error that was causing this for a lot of developers. However, the server fix only makes the infinite loop problem less likely to happen. It is still there. I created a new bug to track the infinite loop problem.
https://developers.facebook.com/bugs/446010282155033

It's a memory access error, because the loginView is in a __block space.
Just move your controller ( the loginView delegate ) in this zone and it should work.
FBLoginView *loginview = [[FBLoginView alloc] init];
static id staticDelegateInstance = self;
loginview.frame = CGRectOffset(loginview.frame, 5, 5);
loginview.delegate = staticDelegateInstance;
[self.view addSubview:loginview];
[loginview sizeToFit];

Related

SiriKit with VoIP call Application not working in iOS 10

I am doing VoIP call Application. There i can make call through my application. I have integrated SiriKit setup and added following code.
#pragma mark -Start Audio Call
- (void)resolveContactsForStartAudioCall:(INStartAudioCallIntent *)intent
withCompletion:(void (^)(NSArray<INPersonResolutionResult *> *resolutionResults))completion{
NSLog(#"maytest resolveContactsForStartAudioCall");
NSArray<INPerson *> *recipients = intent.contacts;
NSMutableArray<INPersonResolutionResult *> *resolutionResults = [NSMutableArray array];
if (recipients.count == 0) {
completion(#[[INPersonResolutionResult needsValue]]);
return;
}else if(recipients.count==1){
[resolutionResults addObject:[INPersonResolutionResult successWithResolvedPerson:recipients.firstObject]];
}else if(recipients.count>1){
[resolutionResults addObject:[INPersonResolutionResult disambiguationWithPeopleToDisambiguate:recipients]];
}else{
[resolutionResults addObject:[INPersonResolutionResult unsupported]];
}
completion(resolutionResults);
}
- (void)confirmStartAudioCall:(INStartAudioCallIntent *)intent
completion:(void (^)(INStartAudioCallIntentResponse *response))completion{
NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass([INStartAudioCallIntent class])];
INStartAudioCallIntentResponse *response = [[INStartAudioCallIntentResponse alloc] initWithCode:INStartAudioCallIntentResponseCodeReady userActivity:userActivity];
completion(response);
}
- (void)handleStartAudioCall:(INStartAudioCallIntent *)intent
completion:(void (^)(INStartAudioCallIntentResponse *response))completion{
NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass([INStartAudioCallIntent class])];
INStartAudioCallIntentResponse *response = [[INStartAudioCallIntentResponse alloc] initWithCode:INStartAudioCallIntentResponseCodeContinueInApp userActivity:userActivity];
completion(response);
}
But, its not making calls through my app. Its making calls through native dialer and some times showing application not yet set up with siri.
Could anyone guide me and after make call, how to save call history.
Thanks!
I encountered this problem too!!!
I my case, it's because I'm calling Siri in Chinese!!!! It takes me a half day to figure it out!!
If I change Siri language to English and everything works just fine!
In Chinese Siri will only call through native dialer no matter how I specify the application.
I'm not sure if it happens on other languages too since I can only test those two.

Multipeer Connectivity - State Not Changing

I'm working on an app the uses the Multipeer Conectivity Framework. So far everything is going great, I've implemented programmatic browsing and invitations.
My issue is when the user accepts the invitation the Browser is not receiving the state change - thereby not creating the session.
This is the advertiser did receive invitation method i have created using an action sheet integrated with blocks.
- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser
didReceiveInvitationFromPeer:(MCPeerID *)peerID
withContext:(NSData *)context
invitationHandler:(void(^)(BOOL accept, MCSession *session))invitationHandler
{
[UIActionSheet showInView:self.view
withTitle:[[NSString alloc]initWithFormat:#"%# would like to share %# information with you.",peerID.displayName, (NSString *)context]
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:#"Deny"
otherButtonTitles:#[#"Accept"]
tapBlock:^(UIActionSheet *actionSheet, NSInteger buttonIndex) {
NSLog(#"%i",buttonIndex==1?true:false);
MCSession *newSession=[[MCSession alloc]initWithPeer:[[MCPeerID alloc] initWithDisplayName:#"CRAP23456"]];
[newSession setDelegate: self];
NSLog(#"button index %i ",buttonIndex==1?true:false);
invitationHandler(buttonIndex==1?YES:NO,newSession);
}];
}
The above method is being called and the invitation handler is returning the correct value.
My implementation from the browser side is very simple - and this is the method that should be called when the user either accepts/declines the method. However, it's only being called when the user declines the invite:
- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state
{
NSLog(#"%d",state);
NSLog(#"%ld",(long)MCSessionStateConnected);
}
Thanks in advance.
James.
I hope one of these will help:
Implement session:didReceiveCertificate:fromPeer:certificateHandler:
I read here that this is necessary.
Keep browsing and advertising between two peers a one-way deal; that is, don't accept invitations on both ends if both are browsing as well (at least don't accept an invitation and pass same session you're browsing with in invitationHandler()).
Wrap your code in the didChangeState in a block like this:
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"%d",state);
NSLog(#"%ld",(long)MCSessionStateConnected);
});
I ran into this issue too. My code on the browser side looked like this:
MCSession *session = [[MCSession alloc] initWithPeer:[self peerID]];
session.delegate = self;
[browser invitePeer:peerID toSession:session withContext:nil timeout:30.0f];
The issue with this is that the browser does not retain a reference to the session and so ARC comes around and cleans it up before the other end had the opportunity to accept.
Changing it to the following fixed the issue:
_session = [[MCSession alloc] initWithPeer:[self peerID]];
_session.delegate = self;
[browser invitePeer:peerID toSession:_session withContext:nil timeout:30.0f];
.. where _session is an ivar on my class.
HTH

iPhone GameCenter won't showAchievments

So my problem is that after integrating gamecenter nicely into my iphone app, it won't show the achievements list!
The integration was a success I think because when I use the submitAchievement method, I do unlock achievements on the list. But I must look at the list from the GameCenter App on the iPhone, not within my own app as it doesn't work.
ikuragames first help me get the code right (thx you !!) but it still doesn't work ! :(
-(void)showAchievments
{
//NSLog(#"showAchievments");
GKAchievementViewController *achievements = [GKAchievementViewController alloc] init];
if (achievements != nil)
{
achievements.achievementDelegate = self;
[(EAGLView *)self.view achievmentsWillAppear];
[self presentModalViewController:achievements animated:YES];
}
}
- (void)achievementViewControllerDidFinish:(GKAchievementViewController *)viewController
{
//NSLog(#"achievementViewControllerDidFinish");
[glView achievmentsWillDisappear];
[self dismissModalViewControllerAnimated:YES];
}
On debug mode, I can clearly see that each line or code are "processed" and not error whatsoever is displayed. BUT, nothing appears on my screen :(
Can you please help me ? (here is some doc.)
I found the answer.
Turned out that the view controller I was sending showAchievments to was not the view controller I wanted.
I was doing something like:
[[myViewController sharedInstance] showAchievments];
But the sharedInstance method returned a brand-new, vanilla-initialised myViewController, and not the one I was already using.
Now it works perfectly, I hope this will help someone in the future.

twitter ios4 ..Accounts Framework

https://github.com/doubleencore/DETweetComposeViewController
I followed twitter integration here for supporting twitter for both ios5 and ios4.
if ([DETweetComposeViewController canSendTweet]) {
DETweetComposeViewControllerCompletionHandler completionHandler = ^(DETweetComposeViewControllerResult result) {
switch (result) {
case DETweetComposeViewControllerResultCancelled:
NSLog(#"Twitter Result: Cancelled");
break;
case DETweetComposeViewControllerResultDone:
NSLog(#"Twitter Result: Sent");
break;
}
[self dismissModalViewControllerAnimated:YES];
};
DETweetComposeViewController *tcvc = [[[DETweetComposeViewController alloc] init] autorelease];
[tcvc addImage:[UIImage imageNamed:#"YawkeyBusinessDog.jpg"]];
[tcvc addURL:[NSURL URLWithString:#"http://www.DoubleEncore.com/"]];
[tcvc addURL:[NSURL URLWithString:#"http://www.apple.com/ios/features.html#twitter"]];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:tcvc animated:YES];
}
else {
self.oAuth = [[[OAuth alloc] initWithConsumerKey:kDEConsumerKey andConsumerSecret:kDEConsumerSecret] autorelease];
TwitterDialog *td = [[[TwitterDialog alloc] init] autorelease];
td.twitterOAuth = self.oAuth;
td.delegate = self;
td.logindelegate = self;
[td show];
}
The tutorial didn't specify what is self.oAuth so i imported oAuth in my interface file and declared oAuth as a property
I have the following problems now :
1) the code above worked when i didn't put the completion handler block, after adding the handler the build is failing with error in DETweetAccountSelectorViewControllerDelegate in line
#import <Accounts/Accounts.h>
saying no such file or directory exist... which it didn't when there was no completion handler. And yes i have now linked and unlinked to accounts framework more than 5 times now..so it was working before not now.
2) when i run the project without completion handler the twitter dialog pops up. but can't post(authorization request comes up for my twitter app but after authorizing it gets stuck) ..the log in console is
discarded an uncaught exception in the webView:decidePolicyForNavigationAction:request:frame:decisionListener: delegate:
also if i close the dialog ..the program crashes because there is no code to dimiss the controller which i tried to solve using completion handler.
3) if any one have a simpler tutorial to integrate twitter for both ios4 and ios5 ..can you share..
Thanks
I have recently received the:
discarded an uncaught exception in the webView:decidePolicyForNavigationAction:request:frame:decisionListener: delegate:
Error in a different twitter framework that I am using.
The solution to the problem was that I had an error in my Delegate Function twitterDidLogin.
I think that if you solve for the error which you have not included on this post, that the 'discarded an uncaught exception' error will go away. Maybe you could paste that error?
I found the answer..there tutorial takes you in the opposite direction..waste my 5 hours on it..
just have to initialize DETweetComposeViewController ..and the rest is taken care of.. in their tutorial.. they show twitter dialog .and can tweet function which will just confuse

FBConnect won't display Publish to Wall after login

I have an app that I want to be able to connect to Facebook and post to the user's wall. I have the following code:
- (void)viewDidLoad {
static NSString* kApiKey = #"PRIVATE";
static NSString* kApiSecret = #"PRIVATE";
_session = [[FBSession sessionForApplication:kApiKey secret:kApiSecret delegate:self] retain];
// Load a previous session from disk if available. Note this will call session:didLogin if a valid session exists.
[_session resume];
// Set these values from your application page on http://www.facebook.com/developers
// Keep in mind that this method is not as secure as using the sessionForApplication:getSessionProxy:delegate method!
// These values are from a dummy facebook app I made called MyGrades - feel free to play around!
[super viewDidLoad];
}
- (IBAction)postGradesTapped:(id)sender {
_posting = YES;
// If we're not logged in, log in first...
if (![_session isConnected]) {
self.loginDialog = nil;
_loginDialog = [[FBLoginDialog alloc] init];
[_loginDialog show];
}
// If we have a session and a name, post to the wall!
else if (_facebookName != nil) {
[self postToWall];
}
// Otherwise, we don't have a name yet, just wait for that to come through.
}
The problem I have is that when the user clicks the button associated with the IBAction it will pop up the login dialog, but then the window disappears without ever pulling up the Publish Story to Wall dialog. How do I get it to login and then pull up the Publish Story to Wall?
I think you may need to use FBPermissionDialog to ask for "post to wall" permission first (I'm not sure what the exact string is; it might be in the examples).
Also note that "FBSession" is the old "iPhone" SDK (last updated in April); there's a newer "iOS" SDK at http://github.com/facebook/facebook-ios-sdk
I once encountered this behavior when my Security Key was wrong (in the new API you don't need it, but if you're based on old API it still requires it).
Make sure you use "App Id" and "App Secret" from the Facebook app control page. (And not "API Key")
Good luck!