App crashes when Facebook login dialog appears


#1

Hi, I am a novice in cocos2d-x, so I faced a problem during Facebook integration for iOS version of app.
The problem is app crashes when Facebook registration dialog appears and app goes to background.
Using the debugger I found out that method applicationDidEnterBackground() is executed without errors.

// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground()
{
    CCDirector::sharedDirector()->stopAnimation();

    CCDirector::sharedDirector()->pause();

}

Objective-C applicationDidEnterBackground: method is executed without errors too.
Then throws to the window with assembly code. After several steps app crashes with message in Target Output:
Cocos2d: cocos2d: deallocing 0x315bf8

What could be the reason?

Regards,
Svyatoslav


#2

hi,

how you integrate the facebook?


#3

Hi,
I used materials from http://www.plungeinteractive.com/blog/ .
All work with native facebook sdk was done in AppController.
Facebook SDK was added to the project by adding it’s source files.

AppController.h

#import "FBConnect.h"
@class RootViewController;

@interface AppController : NSObject  {
    UIWindow *window;
    RootViewController    *viewController;
    Facebook* facebook;
    BOOL isConnected;
}
@property (retain, nonatomic) Facebook* facebook;
@property (nonatomic) BOOL isConnected;

+(AppController*)getSharedInstance;
-(BOOL)login;
-(void)post:(NSString*)message;
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url;
- (void)fbDidLogin;
- (void)fbDidNotLogin:(BOOL)cancelled;
- (void)request:(FBRequest *)request didLoad:(id)result;
- (void)fbDidLogout;
- (void)fbDidExtendToken:(NSString *)accessToken expiresAt:(NSDate *)expiresAt;
- (void)fbSessionInvalidated;

@end

AppController.mm

#include "FacebookSDK.h"
// cocos2d application instance
static AppDelegate s_sharedApplication;
// Static accessor to the classs
static AppController *sharedInstance;

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
    // attempt to extract a token from the url
    return [facebook handleOpenURL:url];
}

-(BOOL) login{
    [self checkForPreviouslySavedAccessTokenInfo];
    if(!isConnected){
        facebook = [[Facebook alloc] initWithAppId:@"YOUR_APP_ID" andDelegate:self];
        [facebook authorize:[NSArray arrayWithObject:@"publish_actions"]];
        return NO;
    }
    else{
        return YES;
    }
 }

-(void)post:(NSString*)message{
    NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                   @"My app name", @"name",
                                   @"http://www.facebook.com/myAppName", @"link",
                                   message, @"message",
                                   nil];
    [facebook requestWithGraphPath:@"me/feed" andParams:params andHttpMethod:@"POST" andDelegate:self];
}

- (void)fbDidLogin {
    [self saveAccessTokenKeyInfo];
    isConnected = YES;
}

- (void)fbDidExtendToken:(NSString *)accessToken expiresAt:(NSDate *)expiresAt{
    [self saveAccessTokenKeyInfo];
}

-(void)checkForPreviouslySavedAccessTokenInfo{
    // Initially set the isConnected value to NO.
    isConnected = NO;
    // Check if there is a previous access token key in the user defaults file.
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if ([defaults objectForKey:@"FBAccessTokenKey"] &&
        [defaults objectForKey:@"FBExpirationDateKey"]) {
        facebook.accessToken = [defaults objectForKey:@"FBAccessTokenKey"];
        facebook.expirationDate = [defaults objectForKey:@"FBExpirationDateKey"];
        // Check if the facebook session is valid.
        // If it’s not valid clear any authorization and mark the status as not connected.
        if (![facebook isSessionValid]) {
            [facebook authorize:nil];
            isConnected = NO;
        }
        else {
            isConnected = YES;
        }
    }
}

-(void)saveAccessTokenKeyInfo{
    // Save the access token key info into the user defaults.
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:[facebook accessToken] forKey:@"FBAccessTokenKey"];
    [defaults setObject:[facebook expirationDate] forKey:@"FBExpirationDateKey"];
    [defaults synchronize];
}

FacebookManagerIOS.h

@interface FacebookManagerIOS : NSObject {
 }
+(BOOL) login;
+(void) publish:(NSString*)message;
+(void) showAlert;
@end

FacebookManagerIOS.m

#import "FacebookManagerIOS.h"
#import "AppController.h"

@implementation FacebookManagerIOS
+(BOOL) login{
    if([AppController getSharedInstance].isConnected){
        return YES;
    }
    else
    {
       return [[AppController getSharedInstance] login]; 
    }
}

+(void) publish:(NSString*)message{
    [[AppController getSharedInstance] post:message];
}

+(void) showAlert{
    UIAlertView *alertDialog;
    alertDialog = [[UIAlertView alloc]
                   initWithTitle:@"Facebook"
                   message:@"Your message posted"
                   delegate:nil
                   cancelButtonTitle: @"OK"
                   otherButtonTitles: nil];
    [alertDialog show];
    [alertDialog release];
}

@end

FcebookManager.h

#include 

namespace FacebookBridge{
    class  FacebookManager {
    public:
        static bool login();
        static void publish(std::string message);
        static void showAlert();
    };
}

FacebookManager.cpp

#import "FacebookManager.h"
#import "FacebookManagerIOS.h"

namespace FacebookBridge{
    bool FacebookManager::login()
    {
        return [FacebookManagerIOC login];
    }

    void FacebookManager::publish(std::string message){
         [FacebookManagerIOC publish:[NSString stringWithCString:message.c_str() encoding:NSUTF8StringEncoding]];
    }

    void FacebookManager::showAlert(){
        [FacebookManagerIOC showAlert];

    }
}

Note: FacebookManager.cpp is Objective C++ file.
I posted only the code that is needed for this topic.

Thus with cocos2dx code I use FacebookManager class. Hope it was useful for you.

Regards,
Svyatoslav


#4

I added your code but there is lot of errors when i run my app…
: warning: directory not found for option '-L/Applications/cocos2d-2.0-x-2.0.2/samples/TestCpp/proj.ios/MoSync/bin/freetype219/lib’
ld: warning: directory not found for option '-L/Applications/cocos2d-2.0-x-2.0.2/samples/TestCpp/proj.ios/MoSync/bin’
ld: warning: directory not found for option '-L/Applications/cocos2d-2.0-x-2.0.2/samples/TestCpp/proj.ios/MoSync/bin/ImageMagick/ImageMagick/lib’
ld: warning: directory not found for option '-L/Applications/cocos2d-2.0-x-2.0.2/samples/TestCpp/proj.ios/MoSync/bin/ImageMagick/lib’
ld: warning: directory not found for option '-L/Applications/cocos2d-2.0-x-2.0.2/samples/TestCpp/proj.ios/MoSync/profiles/runtimes/iphoneos/1/template/libs/Debug-iphoneos’
ld: warning: directory not found for option '-L/Applications/cocos2d-2.0-x-2.0.2/samples/TestCpp/proj.ios/MoSync/profiles/runtimes/iphoneos/1/template/libs/Debug-iphonesimulator’
ld: warning: directory not found for option '-L/Applications/cocos2d-2.0-x-2.0.2/samples/TestCpp/proj.ios/MoSync/profiles/runtimes/iphoneos/1/template/libs/Release-iphoneos’
ld: warning: directory not found for option '-L/Applications/cocos2d-2.0-x-2.0.2/samples/TestCpp/proj.ios/MoSync/profiles/runtimes/iphoneos/1/template/libs/Release-iphonesimulator’
ld: warning: directory not found for option '-L/Applications/cocos2d-2.0-x-2.0.2/samples/TestCpp/proj.ios/Versions/A’
ld: warning: directory not found for option '-L/Applications/cocos2d-2.0-x-2.0.2/samples/TestCpp/proj.ios/Versions/Current’
ld: warning: directory not found for option '-L/Applications/cocos2d-2.0-x-2.0.2/samples/TestCpp/proj.ios/FacebookSDK/Versions/A’
ld: warning: directory not found for option '-L/Applications/cocos2d-2.0-x-2.0.2/samples/TestCpp/proj.ios/FacebookSDK/Versions/Current’
ld: warning: directory not found for option '-L/Applications/cocos2d-2.0-x-2.0.2/samples/TestCpp/proj.ios/FacebookSDK.framework/Versions/A’
ld: warning: directory not found for option '-L/Applications/cocos2d-2.0-x-2.0.2/samples/TestCpp/proj.ios/FacebookSDK.framework/Versions/Current’
ld: warning: directory not found for option '-F/Applications/cocos2d-2.0-x-2.0.2/samples/TestCpp/proj.ios/FacebookSDK’
Undefined symbols for architecture armv7:
"_sqlite3_reset", referenced from:
_initializeStatement in FacebookSDK(FBCacheIndex.o)
"_sqlite3_prepare_v2", referenced from:
_initializeStatement in FacebookSDK(FBCacheIndex.o)
"_sqlite3_open_v2", referenced from:
___36-[FBCacheIndex initWithCacheFolder:]_block_invoke_0 in FacebookSDK(FBCacheIndex.o)
"_sqlite3_bind_text", referenced from:
-[FBCacheIndex _updateEntryInDatabaseForKey:entry:] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _writeEntryInDatabase:] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _readEntryFromDatabase:] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _readEntriesFromDatabase:excludingFragment:] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _removeEntryFromDatabaseForKey:] in FacebookSDK(FBCacheIndex.o)
"_sqlite3_step", referenced from:
-[FBCacheIndex _updateEntryInDatabaseForKey:entry:] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _writeEntryInDatabase:] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _createCacheEntityInfo:] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _fetchCurrentDiskUsage] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _removeEntryFromDatabaseForKey:] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _dropTrimmingTable] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _trimDatabase] in FacebookSDK(FBCacheIndex.o)

"_sqlite3_bind_double", referenced from:
-[FBCacheIndex _updateEntryInDatabaseForKey:entry:] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _writeEntryInDatabase:] in FacebookSDK(FBCacheIndex.o)
"_sqlite3_bind_int", referenced from:
-[FBCacheIndex _updateEntryInDatabaseForKey:entry:] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _writeEntryInDatabase:] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _trimDatabase] in FacebookSDK(FBCacheIndex.o)
"_sqlite3_finalize", referenced from:
_releaseStatement in FacebookSDK(FBCacheIndex.o)
"_sqlite3_column_text", referenced from:
-[FBCacheIndex _createCacheEntityInfo:] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _trimDatabase] in FacebookSDK(FBCacheIndex.o)
"_sqlite3_exec", referenced from:
___36-[FBCacheIndex initWithCacheFolder:]_block_invoke_0 in FacebookSDK(FBCacheIndex.o)
"_sqlite3_errmsg", referenced from:
_releaseStatement in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _updateEntryInDatabaseForKey:entry:] in FacebookSDK(FBCacheIndex.o)
_initializeStatement in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _writeEntryInDatabase:] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _readEntryFromDatabase:] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _readEntriesFromDatabase:excludingFragment:] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _fetchCurrentDiskUsage] in FacebookSDK(FBCacheIndex.o)

"_sqlite3_column_int", referenced from:
-[FBCacheIndex _createCacheEntityInfo:] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _fetchCurrentDiskUsage] in FacebookSDK(FBCacheIndex.o)
-[FBCacheIndex _trimDatabase] in FacebookSDK(FBCacheIndex.o)
"_sqlite3_close", referenced from:
___23-[FBCacheIndex dealloc]_block_invoke_0 in FacebookSDK(FBCacheIndex.o)
"_sqlite3_column_double", referenced from:
-[FBCacheIndex _createCacheEntityInfo:] in FacebookSDK(FBCacheIndex.o)
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

why these errors help me…:frowning:


#5

Hi,
seems like linker problems. Try to add “-lsqlite3.0” to the Debug and Realise in the Other Linker Flags.


#6

is it necessary to add isqlite? what i know is i just have to add Facebook sdk in my xcode project and then have to do what you are doing in code…


#7

According to yours log it seems that you need to add it. Especially that you need to add only one line :slight_smile:
Try it.


#8

and the line is?


#9

-lsqlite3.0


#10

Or try this: Select the Build Phases tab. The Link Binary with Libraries section lists the libraries and frameworks already included in the project. To add another library or framework click on the ‘+’ button to display the full list. From this list, select the required item (in this case libsqlite3.dylib) and click Add.


#11

I added sqllite and there is no error now…:slight_smile: but when i added your facebookManager class i have many errors…The reason i think is i created it as c*+ class but you are saying it is objective-c*+ class…how can i create objective c++ file?


#12

And the errors are on these lines…

FOUNDATION_EXPORT NSString NSStringFromSelector;
FOUNDATION_EXPORT SEL NSSelectorFromString;
FOUNDATION_EXPORT NSString
NSStringFromClass(Class aClass);
FOUNDATION_EXPORT Class NSClassFromString(NSString aClassName);
FOUNDATION_EXPORT NSString
NSStringFromProtocol(Protocol proto) NS_AVAILABLE;
FOUNDATION_EXPORT Protocol
NSProtocolFromString(NSString namestr) NS_AVAILABLE;
FOUNDATION_EXPORT const char
NSGetSizeAndAlignment(const char typePtr, NSUIntegersizep, NSUInteger *alignp);

FOUNDATION_EXPORT void NSLog(NSString *format, …) NS_FORMAT_FUNCTION(1,2);
FOUNDATION_EXPORT void NSLogv(NSString *format, va_list args) NS_FORMAT_FUNCTION(1,0);


#13

did you rename FacebookManager.mm file into FacebookManager.cpp file?


#14

Hi,
to make your .cpp file an objective-c*+ file you need to click the .cpp file and in the “Identity and type” window on Xcode , choose Objective C*+ source as the type.


#15

plz tell me how you use FacebookManger in cocos2d-x? for example how u login on fb by using this class?


#16
bool isLogin;
isLogin = FacebookBridge::FacebookManager::login();
if(!isLogin){
//do something
}

#17

i am sorry i m taking your more time…I was already doing same what u did for login…but it causing crash at this line " int retVal = UIApplicationMain(argc, argv, nil, @“AppController”);".:frowning:


#18

What do you have in the call stack?


#19

This is in my Log…

“[AppController getSharedInstance]: unrecognized selector sent to class 0x1760b4’
* First throw call stack:
(0x344e82a3 0x353a697f 0x344ebca3 0x344ea531 0x34441f68 0xb8e27 0xb8f39 0xb733d 0x10474f 0x1039a7 0x1039d9 0x14785b 0x147c67 0x147c8d 0x110999 0x119879 0x3bca95f1 0x3bc96801 0x3bc9611b 0x3c22d5a3 0x3c22d1d3 0x344bd173 0x344bd117 0x344bbf99 0x3442eebd 0x3442ed49 0x3c22c2eb 0x3bcea2f9 0x93edf 0x93e90)
libc++abi.dylib: terminate called throwing an exception”

I think the problem is with sharedInstance of appcontroller…


#20

Yes, you need to set sharedInstance = self; in

  • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions function.