App Crash due to FB sdk 3.2 - iphone

I am using new FB IOS SDK and app crash and get below error
Assertion failure in -FBCacheIndex
_updateEntryInDatabaseForKey:entry:, /Users/chrisp/src/ios-sdk/src/FBCacheIndex.m Terminating app due to
uncaught exception 'NSInternalInconsistencyException', reason: ''
* First throw call stack: (0x334072a3 0x3b0a197f 0x3340715d 0x33cdcb13 0x10b3b1 0x10b635 0x10a7bf 0x3b4b911f 0x3b4b899b 0x3b4b8895
0x3b4c7215 0x3b4c73b9 0x3b4eda11 0x3b4ed8a4)
I have made google and found solution like -lsqlite3.0 in other linker flag and add -lsqlite3 framework, FBsession missing. and i have done all but still i am getting same issue.
My code as below:
in FBClass.m which is NSObject type
-(void) getFriendListForInvitation
{
# try {
if (self.friendPickerController == nil) {
// Create friend picker, and get data loaded into it.
self.friendPickerController = [[FBFriendPickerViewController alloc] init];
self.friendPickerController.title = #"Invite Friends";
self.friendPickerController.delegate = self;
[self.friendPickerController clearSelection];
[self.friendPickerController loadData];
self.friendPickerController.itemPicturesEnabled = TRUE;
}
else{
[self.friendPickerController clearSelection];
[self.friendPickerController updateView];
}
self.friendPickerController.allowsMultipleSelection = FALSE;
// iOS 5.0+ apps should use [UIViewController presentViewController:animated:completion:]
// rather than this deprecated method, but we want our samples to run on iOS 4.x as well.
if([[[UIDevice currentDevice] systemVersion] intValue] >= 5.0)
[[[appdelegate.navigationController viewControllers] lastObject] presentViewController:self.friendPickerController animated:TRUE completion:nil];
else
[[[appdelegate.navigationController viewControllers] lastObject] presentModalViewController:self.friendPickerController animated:YES];
}
#catch (NSException *exception) {
NSLog(#"%#",[exception description]);
}
}
Please help me to solve this issue.....
thanks

Did you manage to solve the issue? I suffer from the same problem.
I determined that this exception is caused by the missing file cache.db in the directory facebook is addressing to. You can check that with the help of the simulator. The directory of the missing simulator file is:
/Users/<user name>/Library/Application Support/iPhone Simulator/6.1/Applications/<app id>/Library/Caches/DataDiskCache
Yet I do not know why the file is missing.
EDIT:
The only thing I came up with was to clear the session data from the app with simple two lines of code:
FBSession.activeSession = nil;
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"FBAccessTokenInformationKey"];
Unfortunately this solution never actually closes the session but at least it is providing the proper workflow of the app.

Related

Facebook SDK FBLoginView getting EXC_BAD_ACCESS

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];

What will happen to users running a lower version of IOS if new code is called?

I am fairly new to iOS Development and I've always wondered if a user running my application on iOS 4 were to try and run this code:
//POST TWEET//
- (void)showTweetSheet
{
TWTweetComposeViewController *tweetSheet =
[[TWTweetComposeViewController alloc] init];
tweetSheet.completionHandler = ^(TWTweetComposeViewControllerResult result) {
switch(result) {
case TWTweetComposeViewControllerResultCancelled:
break;
case TWTweetComposeViewControllerResultDone:
break;
}
dispatch_async(dispatch_get_main_queue(), ^{
[self dismissViewControllerAnimated:YES completion:^{
NSLog(#"Tweet Sheet has been dismissed.");
}];
});
};
[tweetSheet setInitialText:#"Check out this cool picture I found on #Pickr_"];
// Add an URL to the Tweet. You can add multiple URLs.
if (![tweetSheet addURL:[NSURL URLWithString:ImageHost]]){
NSLog(#"Unable to add the URL!");
}
[self presentViewController:tweetSheet animated:YES completion:^{
NSLog(#"Tweet sheet has been presented.");
}];
}
What would happen? Would the application just terminate with an error or will the code just not run? And how do I properly implement features that are OS specific? Would I just use something like this:
NSString *DeviceVersion = [[UIDevice currentDevice] systemVersion];
int DeviceVersionInt = [DeviceVersion intValue];
if (DeviceVersionInt > 5)
{
//do something.
}
else
{
//don't do a thing.
}
It will crash on iOS 4 if you write iOS5 features without checking if they are available or not. Try to implement Twitter like this
Class twClass = NSClassFromString(#"TWTweetComposeViewController");
if (!twClass) // Framework not available, older iOS
{
//use iOS4 SDK to implement Twitter framework
}
else {
//use Apple provided default Twitter framework
}
Make sure you have added Twitter Framework with weak link.
Id imagine that it would work the same as with any other api. If you link against a function which is not in a previous version, the program will crash on an attempt to call the function. Therefore, version switches are used, as you demonstrated, to avoid crashes.
The app would crash. If you want to implement features based on iOS, you can use a variety of methods. See this question.

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

Problems building for both iOS4.3 and iOS5.0

I'm running up against problems trying to incorporate some iOS5-specific libraries into an app targeted at both iOS5 and iOS4.3. I've gone through the following steps:
weakly-linked the Twitter framework by setting it as optional in 'Link Binary with Libraries"
added it as a framework for the iOS5.0 SDK in Other Linker Flags with `-framework Twitter.framework'
conditionally linked the framework in the class header:
#if defined(__IPHONE_5_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_5_0
#import <Twitter/Twitter.h>
#import <Accounts/Accounts.h>
#endif
then in the method itself, I'm then checking whether the user's set up for Twitter:
if ([TWTweetComposeViewController class]) {
self.canTweet = [TWTweetComposeViewController canSendTweet];
}
This works beautifully on both the 5.0 and 4.3 simulators. However, I've got problems getting it to run on, or archive for, actual devices.
When I've got either a 3GS running 5.0, or a 4 running 5.0 attached, both show up twice in the Scheme dropdown. Selecting the top one, and attempting build or run the project fails with an Use of unidentified identifier 'TWTweetComposeViewController' error.
Using the second device entry, the build fails with a ld: framework not found Twitter.framework error.
I'm sure there's something I'm missing here, but I'm stumped. Can anyone advise?
If you are using a week linking then you have to check first availability of API using
NSClassFromString, respondsToSelector, instancesRespondToSelector etc.
So, change your if condition. First try to get your class object using above specified runtime function.
here is a link explaining in detail how to do such.
link
The code for presenting twitter controller
Before this you have to add the frameworks as optional and make the import in h file if iOS is min iOS 5
Class TWTweetComposeViewControllerClass = NSClassFromString(#"TWTweetComposeViewController");
if (TWTweetComposeViewControllerClass != nil) {
if([TWTweetComposeViewControllerClass respondsToSelector:#selector(canSendTweet)]) {
UIViewController *twitterViewController = [[TWTweetComposeViewControllerClass alloc] init];
[twitterViewController performSelector:#selector(setInitialText:)
withObject:NSLocalizedString(#"TwitterMessage", #"")];
[twitterViewController performSelector:#selector(addURL:)
withObject:url];
[twitterViewController performSelector:#selector(addImage:)
withObject:[UIImage imageNamed:#"yourImage.png"]];
[self.navigationController presentModalViewController:twitterViewController animated:YES];
[twitterViewController release];
}
}
Further digging into the error thrown back by the compiler suggested that it was ignoring the weak link flag. Although I've no idea how or why, it was fixed by a reinstallation of XCode.
if you link to 4.2 or later and deploy to 3.1 or later, you can use the new weak linking features to make this check simple.
you have to add Twitter frameworks as optional and then
Class TWTweetComposeViewControllerClass = NSClassFromString(#"TWTweetComposeViewController");
if (TWTweetComposeViewControllerClass != nil)
{
if([TWTweetComposeViewControllerClass respondsToSelector:#selector(canSendTweet)])
{
UIViewController *twitterViewController = [[TWTweetComposeViewControllerClass alloc] init];
[twitterViewController performSelector:#selector(setInitialText:)
withObject:NSLocalizedString(#"TwitterMessage", #"")];
[twitterViewController performSelector:#selector(addURL:)
withObject:url];
[twitterViewController performSelector:#selector(addImage:)
withObject:[UIImage imageNamed:#"yourImage.png"]];
[self.navigationController presentModalViewController:twitterViewController animated:YES];
[twitterViewController release];
}
}

Iphone : Application crash because of old encodeObject after updating

Currently, my Iphone application is not released yet. When I worked with the simulator/device and I modify my application to add more cache into the encodeWithCode: and initWithCoder: . The problem is that when the application is loaded, I tried to use some of the encoded object which is not existing before. For example:
In the previous application version (e.g 1.2), I have this encode:
- (void)encodeWithCoder:(NSCoder*)coder {
[coder encodeObject:myArray forKey:NCITEMTABLE_ARCHIVE_HOME_ITEMS_KEY];
}
But with new version (e.g 1.3), I use this init:
- (id)initWithCoder:(NSCoder*)coder {
if (self = [super initWithCoder:coder]) {
myArray = [[coder decodeObjectForKey:NCITEMTABLE_ARCHIVE_HOME_ITEMS_KEY] retain];
myArray2 = [[coder decodeObjectForKey:NCITEMTABLE_ARCHIVE_HOME_ITEMS_2_KEY] retain];
}
return self;
}
and then the application will crash because it cannot find myArray2.
In the simulator or testing, I can just delete the old version and install from fresh. However, I am afraid that when it is released, I cannot tell my user to delete the old app and install the new fresh one. Have anyone experienced about this problem?
In your initWithCoder you should be able to just call containsValueForKey to see if the key exists before trying to call decodeObjectForKey
I tried to use try catch to get the exception. It may not be the best answer but it works now
. The problem is that it may have low performance when it has to do try catch exception, which is not recommended by Apple
if (archive) {
#try {
[self unarchiveInitializingWithData:archive];
}
#catch (NSException * e) {
NCLog (#"Cannot unarchive");
[self normalInitializing];
}
} else {
NCLog (#"Normal init");
// normal init
[self normalInitializing];
}