Facebook module, iOS. Login, scores etc.

Monkey Targets Forums/iOS/Facebook module, iOS. Login, scores etc.

Alex(Posted 2014) [#1]
Hello!

Check out the Facebook module I created.
I'm not a good programmer, but for now, for me it works :)
I think there's many unnecessary in the code, so I post it here.

I will appreciate any fixes and additions.

Here it is.
https://dl.dropboxusercontent.com/u/71223199/fbMonkey.zip


Example/how to use:
Strict

Import fbMonkey

Global friendsNames:String[]
Global friendsIDs:String[]
Global friendsScore:Int[]
Global friendsIDsOld:String[]

Global fbYourPlace:Int, loginFlowInProgress:Bool, loadingFBLeaderboardData:Bool, isLeaderboardFetched:Bool
Global bestResult:Int, lastPosted:Int

Global monkeyFB := New MonkeyFacebook

Class MonkeyFacebook Implements IOnFBLoginComplete, IOnFBFetchComplete, IOnFBFetchFriendsComplete, IOnFBOpenNewSessionComplete, IOnFBSendScoreComplete, IOnFBShareComplete
	
	Field openNewSession:MonkeyOpenNewSessionFB
	Field login:MonkeyLoginFB
	Field fetch:MonkeyFetchFB
	Field fetchFriends:MonkeyFetchFriendsFB
	Field share:MonkeyShareFB
	Field sendScore:MonkeySendScoreFB

	'Do at OnCreate, checks if user is already logged in'
	Method OpenNewSession:Void()
		openNewSession = New MonkeyOpenNewSessionFB
		openNewSession.FBOpenNewSessionAcync(Self)
	End

	Method Login:Void()
		login = New MonkeyLoginFB
		login.FBLoginAsync(Self)
		loginFlowInProgress = True
	End

	'fetches your data'
	Method Fetch:Void()
		fetch = New MonkeyFetchFB
		fetch.FBFetchAsync(Self)
	End

	'fetches friends data and score'
	Method FetchFriends:Void()
		fetchFriends = New MonkeyFetchFriendsFB
		fetchFriends.FBFetchFriendsAsync(Self)
		isLeaderboardFetched = False
	End

	Method SendScore:Void(theScore:Int)
		sendScore = New MonkeySendScoreFB
		sendScore.FBSendScoreAsync(Self, theScore)
		sendingScoreFlow = True
		isLeaderboardFetched = False
	End

	Method Share:Void(theScore:Int, theName:String, theCaption:String, theLink:String, thePicLink:String, thePhrase1:String, thePhrase2:String)
		share = New MonkeyShareFB
		share.FBShareAsync(Self, theScore, theName, theCaption, theLink, thePicLink, thePhrase1, thePhrase2)
	End

	Method OnFBOpenNewSessionComplete:Void( result:Int )
		Print "OnFBOpenNewSessionComplete, result=" + result

		If result<>0 
			Print "Failed to Open New Session"
			login=Null
			loginFlowInProgress = False
		Endif

		If result = 1
			loginFlowInProgress = False
			Print "New Session Failed To Open"
		End

		'success'
		If result = 0
			'fetching your data if login was successful'
			Self.Fetch()
		End
	End

	Method OnFBLoginComplete:Void( result:Int )
		Print "FBLoginComplete, result=" + result

		If result<>0 
			Print "Failed to Login or Canceled"
			login=Null
			loginFlowInProgress = False
		Endif

		If result = 1
			Print "Login Cancelled"
			loginFlowInProgress = False
		End

		'success'
		If result = 0
			'fetching your data if login was successful'
			Self.Fetch()
		End
	End

	Method OnFBFetchComplete:Void( result:Int )
		Print "FBFetchComplete, result=" + result

		If result<>0 
			Print "Failed to Fetch"
			fetch=Null
			loginFlowInProgress = False
		Endif

		If result = 1
			Print "Fetch Cancelled"
			loginFlowInProgress = False
		End

		'success'
		If result = 0
			Print fbUserName
			Print fbUserID
			'fetching friends' data if fetching your data was successful'
			Self.FetchFriends()
		End
	End

	Method OnFBFetchFriendsComplete:Void( result:Int )
		Print "FBFetchFriendsComplete, result=" + result

		If result<>0 
			Print "Failed to FetchFriends"
			fetchFriends=Null
		Endif

		If result = 1
			Print "FetchFriends Cancelled"
		End

		If result = 0
			Print "Friends Fetched"

			'resizing all arrays to your friends count'
			friendsNames = friendsNames.Resize(friendsCount)
			friendsIDs = friendsIDs.Resize(friendsCount)
			friendsScore = friendsScore.Resize(friendsCount)
			friendsPics = friendsPics.Resize(friendsCount)
			friendsIDsOld = friendsIDsOld.Resize(friendsCount)

			For Local fr:Int = 0 Until friendsCount
				friendsNames[fr] = GetFriendName(fr)

				'OPTIONAL, getting only Name without a last name'
				For Local frn$=Eachin friendsNames[fr].Split( " " )
					friendsNames[fr] = frn
					Exit
				Next

				'OPTIONAL, shorting the name if it's too long'
				Local neededNameLenght:Int = 13
				If friendsNames[fr].Length() > neededNameLenght
					friendsNames[fr] = friendsNames[fr][..(neededNameLenght - 1)] + "..."
				End

				friendsIDs[fr] = GetFriendID(fr)
				friendsScore[fr] = GetFriendScore(fr)

				Print friendsIDs[fr]
				Print friendsNames[fr] + " has a score of:" + friendsScore[fr]

				'Check if we need to update ava picture from the last time'
				If friendsIDsOld[fr] <> friendsIDs[fr]

					'LOADING THE AVATAR'

					'!!!Please, use the LoadImageAcync, because you'll have a lot of trouble
						'when the picture will be loaded from a device with Cellular internet.
						'The game will freeze until all your friends' images are loaded!!!

					'You'll fing my own Method below, use it if it feets your needs
					imageLoad.LoadFBPicAsync(fr)

					Print "Image is updating..."
				Else
					Print "No need to load a new image"
				End

				friendsIDsOld[fr] = friendsIDs[fr]

				'Assigning your place in the leaderboard
				'Updating the best result from the leaderboard to current device (if you are logged in on your other device)'
				'And also, if your result on the device is higher, later we will post it on Facebook (here, I use the variable lastPosted to
					post it on Facebook later, in my code flow; you can update the score your way)'
				If friendsIDs[fr] = fbUserID
					fbYourPlace = fr
					If friendsScore[fr] > bestResult
						bestResult = friendsScore[fr]
					Else
						lastPosted = friendsScore[fr]
					End
				End
			End
		End

		isLeaderboardFetched = True
		loginFlowInProgress = False

	End

	Method OnFBSendScoreComplete:Void( result:Int )
		Print "FBSendScoreComplete, result=" + result

		If result<>0 
			Print "Failed to Send Score"
			sendScore=Null
		Endif

		If result = 1
			Print "SendScore Cancelled"
		End

		If result = 0
			Print "Score sent" + sendScore.scoreSent
			lastPosted = sendScore.scoreSent
			Print "the last posted: " + lastPosted
			sendingScoreFlow = False
			UpdateLeaderBoardData()
		End

	End

	Method OnFBShareComplete:Void( result:Int )
		Print "FBShareComplete, result=" + result

		If result<>0 
			Print "Failed to Share"
			sendScore=Null
		Endif

		If result = 1
			Print "Share Cancelled"
		End

		If result = 0
			Print "Shared!"
		End

	End

End



Global imageLoad := New ImageLoadClass

Class ImageLoadClass Implements IOnLoadImageComplete

	Method LoadFBPicAsync:Void(num:Int)
		Local neededPicSize:Int = 50
		LoadImageAsync(	"https://graph.facebook.com/" + friendsIDs[num] + "/picture?width=" + neededPicSize + "&height=" + neededPicSize, 
						1, 
						Image.MidHandle, 
						Self)
	End
	
	Method OnLoadImageComplete:Void( img:Image, path:String, source:IAsyncEventSource )
		If img
			Print "Image Loaded!"

			'Checking the appropriate friend for loaded pic =)'
			For Local fr:Int = 0 Until friendsCount
				If path.Contains(friendsIDs[fr])
					friendsPics[fr] = img
				End
			End
		Else
			Print "Error loading image async"
		End
	End
End



erebel55(Posted 2014) [#2]
Thanks Alex, I will have a look :)


Alex(Posted 2014) [#3]
Great! Thanks!

Forgot to mention, I tested it with bad connection and no connection at all.
Everything worked so far.

I implemented it in one of my games. Now it's waiting for review in Apple App Store.
I will post here if it's accepted or rejected by Apple =)


Alex(Posted 2014) [#4]
Found a bug.
Link updated.
https://dl.dropboxusercontent.com/u/71223199/fbMonkey.zip

Had some problems with userID.
However, now there's some problems during validation (

If Apple founds a variable in your code that you use as non-public and they use as public, validation says:
The app references non-public selectors in Payload/MonkeyGame.app/MonkeyGame : id


I don't know how this will affect the approval.

I tried to change Facebook's "id" for fbUserID, doesn't work (I don't know, if it's appropriate to change the SDK code, or maybe forgot to change in every place)

Trying to get the approval, will post here the result =)


Alex(Posted 2014) [#5]
Fixed )
Updated link:
https://dl.dropboxusercontent.com/u/71223199/fbMonkey.zip

http://stackoverflow.com/questions/14448056/the-app-references-non-public-selector-in-id-facebook-sdk-ios

The workaround for the moment is to use these:

[user objectForKey:@"id"]
[friend objectForKey:@"id"]
instead of user.id and friend.id as shown in the different Facebook samples.


Now there's no problems during validation.


erebel55(Posted 2014) [#6]
Are you planning on supporting android as well?


rIKmAN(Posted 2014) [#7]
This looks great Alex, thanks for sharing.

Did your app that uses this module get approved on the app store yet?


Alex(Posted 2014) [#8]
erebel55, sorry, not yet. I have zero android experience at the moment (
Maybe I'll have some time to try to port one of my apps on android this summer.

rIKmAN, thanks! ;) Due to the bug I found, I had to resubmit my app April 27th, so it may go live (or rejected) on May ~4th. I'll post here the result!


Alex(Posted 2014) [#9]
Great news!
My app has been approved! )


Alex(Posted 2014) [#10]
Little tutorial based on my tests or "Where and when to do something to integrate Facebook in your game."

Firstly, we have to check the internet connection.
I tried different ways to do that. But this module I've created from one of the StackOverflow topics:
https://dl.dropboxusercontent.com/u/71223199/checkConnection.zip
It's the fastest I ever used.

So this function checks the internet.
Global connectionSuccessful:Bool

Function CheckConnection:Void()
	connectionSuccessful = isConnected()
	If connectionSuccessful Print "Internet connected" Else Print "No internet"
End


1. OnCreate Method:
CheckConnection()

#If TARGET="ios"
	monkeyFB.OpenNewSession()
#End


That's it. We don't need to cancel session opening if there's no internet.

2. Login
#If TARGET="ios"
	If fbLoginBtn.Pressed()
		If Not isLoggedIn And connectionSuccessful
			monkeyFB.Login()
		End

		If Not connectionSuccessful
			//tell player that there's no internet
		End
	End
#End


3. OnResume Method
It's good time to update the leaderboard when the player suspends the app.
CheckConnection()

If connectionSuccessful And isLoggedIn And LoginFlowActive = False
	monkeyFB.FetchFriends()
End

FBAtResume()


4. Posting the score.
Global currentResult:Int, isResultUpgraded:Bool

'checking if the score is best, then post
If currentResult > bestResult
	bestResult = currentResult
	isResultUpgraded = True
	Print "New record!"
End

scoreToPost = currentResult

If isLoggedIn And connectionSuccessful
	If isResultUpgraded
		monkeyFB.SendScore( scoreToPost )
	End
End

Note: you have to reset the isResultUpgraded var to False before posting the score

5. OnUpdate Method

'Important!!!
UpdateAsyncEvents()

#If TARGET = "ios"

'freezing the update if login is in progress (I suggest you to draw something like "Connecting..." on the screen while this is happening)
If LoginFlowActive
	Return
End

'checking if the best score is higher than has ever been posted on this device.
If lastPosted < bestResult
	If isLoggedIn And connectionSuccessful And LoginFlowActive = False And isLeaderboardFetched = True And sendingScoreFlow = False
		Print "score is old, updating from: " + lastPosted
		monkeyFB.SendScore( bestResult )
	End
End

#End


6. Logout is simple ) Just don't forget not to draw Facebook leaderboard after logout
FBLogout()


7. Sharing
If fbShareBtn.Pressed()

	If isResultUpgraded

		'the last two phrases are actually one, the var scoreToPost is inserted between those phrases, so you may include your score into your post.
		monkeyFB.Share(	scoreToPost,
						theNameOfApp,
						smallCaption,
						iTunesURL,
						iconURL,
						anyText "I've got a score of ",
						anyTextContinue "! Can you score more?")
						'the whole text will look like "I've got a score of 125! Can you score more?"

	End

End


And some pseudo code for drawing the leaderboard.
I know, it's obvious, but, I hope, will save you some time.
If isLeaderboardFetched
	For Local fr:Int = 0 Until friendsCount
		'draw fb pics
		
		'highlighting YOU with yellow
		If fr = 'your place
			SetColor(255,205,0)	
		End

		'draw friends' names and score

		SetColor(255,255,255)
	End
Else
	'Draw something like "Updating leaderboard data..."
End


Hope, I didn't forget anything )
Waiting for your comments, notes and corrections!


Alex(Posted 2014) [#11]
sorry, double post


Raul(Posted 2014) [#12]
does this require Facebook SDK for IOS and must create an id for your app?


Alex(Posted 2014) [#13]
Yes, it does. I'm planning to drop a few lines in this thread about iOS Facebook SDK integration into xCode project.
If I have some free time, I will try do it this week.


Raul(Posted 2014) [#14]
if someone still using this, any idea why I receive this message when I try to compile?
1 error generated.

** BUILD FAILED **


The following build commands failed:
TRANS FAILED: Error executing 'xcodebuild -configuration Debug -sdk iphonesimulator', return code=16640
	CompileC build/MonkeyGame.build/Debug-iphonesimulator/MonkeyGame.build/Objects-normal/i386/main.o main.mm normal i386 objective-c++ com.apple.compilers.llvm.clang.1_0.compiler
(1 failure)



Alex(Posted 2014) [#15]
Raul,

I did not get compile error. However, sdk has updated and my old apps stopped working.

My steps:
Delete FacebookSDK.framework from project.
Update SDK on my Mac.
Drag FacebookSDK.framework to my project (Copy to project option UNCHECKED! Don't know if this is important.)

Made some changes with getting friends score and login.
https://dl.dropboxusercontent.com/u/71223199/fbMonkey.zip

Share doesn't work though.
I use URL. Works perfectly for me!
Local varAppName:String = "My great game!"
Local varCaption:String = "Greatest adventure ever!"
Local varMessage:String = "blah-blah My score is %%. Can you do better?"

varMessage = varMessage.Replace( "%%", bestResult )

Local URL:String = "https://www.facebook.com/dialog/feed?app_id="+fbAppID+"&link="+fbAppURL+"&picture="+fbAppLogo+"&name="+ varAppName + "&caption="+varCaption+"&description="+varMessage+"&redirect_uri="+ fbAppURL+"&display=popup"

URL = URL.Replace(" ", "%20")

OpenUrl(URL)

* fbAppLogo. You have to upload the pic to your site. Can't get fb standard pic to work =(


Alex(Posted 2014) [#16]
1. Login permissions changed. (You have to do it 2 times in the code, be careful.)
NSArray *permissions = [[NSArray alloc] initWithObjects:
                            @"email",
                            @"public_profile",
                            @"user_friends",
                            nil];


2. Function mFBFetchFriendsAsync:
Replaced hardcoded variable theAppID.
Changed the way the function get friends count.
void mFBFetchFriendsAsync(String theAppID){
    
    isFetchFriendsRunning = YES;
    fetchFriendsResult = -1;
    
    [FBRequestConnection startForMyFriendsWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError   *error) {
     
     NSArray* fetchedFriendData;
     
     if (!error && result)
     {
     
     fetchedFriendData = [[NSArray alloc] initWithArray:[result objectForKey:@"data"]];
     
     NSLog(@"Total friends: %i",fetchedFriendData.count);
     //friendsCount = fetchedFriendData.count;
     
     
     
     NSMutableDictionary* params =   [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                      [NSString stringWithFormat:@"%d", 100], @"score",
                                      nil];
     
     
     // NSString *appID = @"1385349258404782";
     NSString *appID = theAppID.ToNSString();
     
     [FBRequestConnection startWithGraphPath:[NSString stringWithFormat:@"%@/scores", appID] parameters:params HTTPMethod:@"GET" completionHandler:^(FBRequestConnection *connection, id result, NSError *error){
      
      friendNum = 0;
      
      isFetchFriendsRunning = NO;
      fetchFriendsResult = 0;
      
      int frCnt = [[result objectForKey:@"data"] count];
      
      for (int i=0;i<frCnt;i++){
      
      NSObject * friendUser = [[[result objectForKey:@"data"] objectAtIndex:i] objectForKey:@"user" ];
      NSString * friendName = [friendUser valueForKey:@"name"];
      NSString * friendId = [friendUser valueForKey:@"id"];
      
      int friendScore = [[[[result objectForKey:@"data"] objectAtIndex:i] objectForKey:@"score"] integerValue];
      
      //NSLog(@"Score of %c is %i", friendName, friendScore);
      
      friendsNames[friendNum] = friendName;
      friendsIDs[friendNum] = friendId;
      friendsScore[friendNum] = friendScore;
      
      friendNum += 1;
      friendsCount = friendNum;
      
      }
      
      }];
     
     }else{
     
     isFetchFriendsRunning = NO;
     fetchFriendsResult = 1;
     
     }
     
     }];
    
    
}



Raul(Posted 2014) [#17]
Alex,

This is the first time when I try using facebook into my apps so:
- already downloaded the lastest SDK from facebook developer page - DONE
- Drag FacebookSDK.framework to my project (Copy to project option UNCHECKED! Don't know if this is important.) - DONE
- copy the example from your post - DONE

tried to compile, receive the error posted by me.


Alex(Posted 2014) [#18]
Can you please, show the full log?
Where is the error in code?

You can go to your xCode project. And look for the trouble there. Your error will be marked as red there.


Raul(Posted 2014) [#19]
the error is from Ted.

I cannot compile to xcode:

"/MonkeyXPro79e/bin/transcc_macos" -target=iOS_Game -config=Debug "/Users/raulgogescu/Documents/teste/fb.monkey"
TRANS monkey compiler V1.72
Parsing...
Semanting...
Translating...
Building...
Build settings from command line:
    SDKROOT = iphonesimulator8.1

=== BUILD TARGET MonkeyGame OF PROJECT MonkeyGame WITH CONFIGURATION Debug ===

Check dependencies
2014-11-14 17:34:30.778 xcodebuild[3433:40641]  DeveloperPortal: Using pre-existing current store at URL (file:///Users/raulgogescu/Library/Developer/Xcode/DeveloperPortal%206.1.db).

CpResource data build/Debug-iphonesimulator/MonkeyGame.app/data
    cd /Users/raulgogescu/Documents/teste/fb.buildv79e/ios
    export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
    builtin-copy -exclude .DS_Store -exclude CVS -exclude .svn -exclude .git -exclude .hg -resolve-src-symlinks /Users/raulgogescu/Documents/teste/fb.buildv79e/ios/data /Users/raulgogescu/Documents/teste/fb.buildv79e/ios/build/Debug-iphonesimulator/MonkeyGame.app

CompileC build/MonkeyGame.build/Debug-iphonesimulator/MonkeyGame.build/Objects-normal/i386/main.o main.mm normal i386 objective-c++ com.apple.compilers.llvm.clang.1_0.compiler
    cd /Users/raulgogescu/Documents/teste/fb.buildv79e/ios
    export LANG=en_US.US-ASCII
    export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -x objective-c++ -arch i386 -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -Wno-trigraphs -fpascal-strings -O0 -Wno-missing-field-initializers -Wno-missing-prototypes -Wno-implicit-atomic-properties -Wno-receiver-is-weak -Wno-arc-repeated-use-of-weak -Wno-non-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors -Wno-missing-braces -Wparentheses -Wswitch -Wno-unused-function -Wno-unused-label -Wno-unused-parameter -Wunused-variable -Wunused-value -Wno-empty-body -Wno-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wno-constant-conversion -Wno-int-conversion -Wno-bool-conversion -Wno-enum-conversion -Wno-shorten-64-to-32 -Wno-newline-eof -Wno-selector -Wno-strict-selector-match -Wno-undeclared-selector -Wno-deprecated-implementations -Wno-c++11-extensions -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.1.sdk -fexceptions -fasm-blocks -fstrict-aliasing -Wprotocol -Wdeprecated-declarations -Winvalid-offsetof -g -fvisibility=hidden -fvisibility-inlines-hidden -Wno-sign-conversion -fobjc-abi-version=2 -fobjc-legacy-dispatch -mios-simulator-version-min=4.3 -iquote /Users/raulgogescu/Documents/teste/fb.buildv79e/ios/build/MonkeyGame.build/Debug-iphonesimulator/MonkeyGame.build/MonkeyGame-generated-files.hmap -I/Users/raulgogescu/Documents/teste/fb.buildv79e/ios/build/MonkeyGame.build/Debug-iphonesimulator/MonkeyGame.build/MonkeyGame-own-target-headers.hmap -I/Users/raulgogescu/Documents/teste/fb.buildv79e/ios/build/MonkeyGame.build/Debug-iphonesimulator/MonkeyGame.build/MonkeyGame-all-target-headers.hmap -iquote /Users/raulgogescu/Documents/teste/fb.buildv79e/ios/build/MonkeyGame.build/Debug-iphonesimulator/MonkeyGame.build/MonkeyGame-project-headers.hmap -I/Users/raulgogescu/Documents/teste/fb.buildv79e/ios/build/Debug-iphonesimulator/include -Ilibs -I/Users/raulgogescu/Documents/teste/fb.buildv79e/ios/build/MonkeyGame.build/Debug-iphonesimulator/MonkeyGame.build/DerivedSources/i386 -I/Users/raulgogescu/Documents/teste/fb.buildv79e/ios/build/MonkeyGame.build/Debug-iphonesimulator/MonkeyGame.build/DerivedSources -F/Users/raulgogescu/Documents/teste/fb.buildv79e/ios/build/Debug-iphonesimulator -include /var/folders/9h/s149kt_533xcr_hw7_p9nwdc0000gn/C/com.apple.DeveloperTools/6.1-6A1052d/Xcode/SharedPrecompiledHeaders/MonkeyGame_Prefix-ftjxddvuucynplhihsewwuatavwq/MonkeyGame_Prefix.pch -MMD -MT dependencies -MF /Users/raulgogescu/Documents/teste/fb.buildv79e/ios/build/MonkeyGame.build/Debug-iphonesimulator/MonkeyGame.build/Objects-normal/i386/main.d --serialize-diagnostics /Users/raulgogescu/Documents/teste/fb.buildv79e/ios/build/MonkeyGame.build/Debug-iphonesimulator/MonkeyGame.build/Objects-normal/i386/main.dia -c /Users/raulgogescu/Documents/teste/fb.buildv79e/ios/main.mm -o /Users/raulgogescu/Documents/teste/fb.buildv79e/ios/build/MonkeyGame.build/Debug-iphonesimulator/MonkeyGame.build/Objects-normal/i386/main.o
/Users/raulgogescu/Documents/teste/fb.buildv79e/ios/main.mm:4302:9: fatal error: 'FacebookSDK/FacebookSDK.h' file not found
#import <FacebookSDK/FacebookSDK.h>
        ^
1 error generated.

** BUILD FAILED **


The following build commands failed:
TRANS FAILED: Error executing 'xcodebuild -configuration Debug -sdk iphonesimulator', return code=16640
	CompileC build/MonkeyGame.build/Debug-iphonesimulator/MonkeyGame.build/Objects-normal/i386/main.o main.mm normal i386 objective-c++ com.apple.compilers.llvm.clang.1_0.compiler
(1 failure)
Done.



Alex(Posted 2014) [#20]
You can look at your xCode project anyway, even with errors in Ted.
Here's the path to it:
/Users/raulgogescu/Documents/teste/fb.buildv79e/ios/
Open MonkeyGame.xcodeproj there.
Do you see this?


Also, there shouldn't be any *red-marked* frameworks. If so, left-click on it and choose Delete.


Raul(Posted 2014) [#21]
yeah, jsut wanted to wrote it down.

so, i opened the xcode project, and tried now to compile after added the FB SDK. Find this error now in xcode:

/Users/raulgogescu/Desktop/exoRail cu fb/exorail.buildv79e/ios/main.mm:5203:24: Assignment to readonly property

and this is the code:
    params.description = [NSString stringWithFormat:@"%@%i%@ ", gamePhrase1, nScore, gamePhrase2];



Alex(Posted 2014) [#22]
Comment it!
This is not the latest version of fbMonkey.


Raul(Posted 2014) [#23]
I took the version from your dropbox folder.

Anyway, commented that line code, added the appid in the plist and compiled. The app stared and now I receive in the debug: MonkeyGame[3671:49460] Facebook: opening new session.

I am in the emulator right now. I assume the process will work fine on the device.

Question:
You said for sharing you are using:
Local URL:String = "https://www.facebook.com/dialog/feed?app_id="+fbAppID+"&link="+fbAppURL+"&picture="+fbAppLogo+"&name="+ varAppName + "&caption="+varCaption+"&description="+varMessage+"&redirect_uri="+ fbAppURL+"&display=popup"

fbAppLogo should be an image from my site, but fbAppURL must be from FB right? How do I get it?


Raul(Posted 2014) [#24]
tested on a real device:

I tried the login feature:
2014-11-14 19:00:02.007 railcartrace[1158:391493] Login button pressed.
Logging...
2014-11-14 19:00:02.059 railcartrace[1158:391493] Login button pressed.
2014-11-14 19:00:02.102 railcartrace[1158:391493] Facebook: session created.
2014-11-14 19:00:12.127 railcartrace[1158:391493] Getting login result...
1
2
Login is about to finish...
FBLoginComplete, result=1
Failed to Login or Canceled
Login Cancelled


I setup the AppID in developers.facebook.com.
I enabled IOS and Single Sign On

Then I exit my game, opened FB from my telephone, log in and retest the game. I was able to launch it and login from the app.

The only question is now... how do I share something? :D


Alex(Posted 2014) [#25]
Glad it worked! =)

If you mean to share your best score, use OpenURL like I posted earlier.
fbAppURL is the URL of your app on the App Store which is:
https://itunes.apple.com/us/app/idXXXXXXXXX
Where XXXXXXXX - is your Application ID from iTunes Connect.

If you mean to share the score with friends and see their score, please, see my tutorial at #11th post of this topic.
If you will have any questions, write them here!

Good luck!


Raul(Posted 2014) [#26]
No. :))

a lot of issues here:
1. If I am trying to run my app from xcode with the phone connected will always crash when trying to login:
railcartrace[1309:422104] Getting login result...
1
2
Login is about to finish...
FBLoginComplete, result=1
Failed to Login or Canceled
Login Cancelled
Logging...
2014-11-15 02:47:55.041 railcartrace[1309:422104] Login button pressed.
2014-11-15 02:47:55.057 railcartrace[1309:422104] Facebook: session created.
(lldb) 


those are the last lines I receive in debug console. the phone screen turns black and nothing is happening.

int main( int argc,char *argv[] ){

	NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
	
    UIApplicationMain( argc,argv,nil,nil );
    
    [pool release];
	
	return 0;
}


2. If I am running my game from the phone, i was able to login ( as i said earlier) the problem is that when I want to 'share' something using the OpenURL:
The game is switching to FB for a few 1 second, than back to menu. Nothing else is happening.

Any thoughts? Can you please explain more about how to make this work? I mention that I also enabled this: Do you want to make this app and all its live features available to the general public?

THanks,


Alex(Posted 2014) [#27]
2. For OpenUrl issue.
Forgot to mention, you have to make Facebook own the URL.
Go to Facebook dashboard -> Settings -> Add platform -> Web
and paste your fbAppURL to both lines.

1. I spend a lot of time having the same issue =)
Maybe the project is configured wrong.
Maybe you don't create a new session.
Do you use FBAtResume()?


Raul(Posted 2014) [#28]
Alex, I appreciate you are trying to help me. I dont think we are gonna solve this :))

So, lets start from over:
- I made the app on facebook and assigned the Web and iOS app:
- From some reason, during the tests these days the app managed to appears in my FaceBook profile list in Settings -> Apps

In Monkey code, just to for testing I made a button that, when is pressed does this:

If Not isLoggedIn
     Print "no login, trying to login to fb"     

     monkeyFB.Login()
 
     Print "login finished"
End

If isLoggedIn
     Print "trying to share"
     shareOnFB()
     Print "share finished"
Endif


I am running the game from xcode and wathc the debug console.
After the app is started I press the FB button. This is what I receive in xcode debug:
no login, trying to login to fb
Logging...
2014-11-16 03:09:42.003 railcartrace[1485:475727] Login button pressed.
login finished

no login, trying to login to fb
Logging...
2014-11-16 03:09:42.122 railcartrace[1485:475727] Login button pressed.
2014-11-16 03:09:42.148 railcartrace[1485:475727] Facebook: session created.
login finished

2014-11-16 03:09:52.175 railcartrace[1485:475727] Getting login result...
1
2
Login is about to finish...
FBLoginComplete, result=1
Failed to Login or Canceled
Login Cancelled
2014-11-16 03:09:52.176 railcartrace[1485:475727] Getting login result...
1
2
Login is about to finish...
FBLoginComplete, result=1
Failed to Login or Canceled
Login Cancelled

no login, trying to login to fb
Logging...
2014-11-16 03:09:52.177 railcartrace[1485:475727] Login button pressed.
2014-11-16 03:09:52.223 railcartrace[1485:475727] Facebook: session created.
login finished

2014-11-16 03:09:53.008 railcartrace[1485:475727] Getting login result...
1
2
Login is about to finish...
FBLoginComplete, result=1
Failed to Login or Canceled
Login Cancelled

no login, trying to login to fb
Logging...
2014-11-16 03:09:53.008 railcartrace[1485:475727] Login button pressed.
2014-11-16 03:09:53.026 railcartrace[1485:475727] Facebook: session created.
login finished

(lldb) 


and is crashing:
argv	char **	0x16fde79c8	0x000000016fde79c8
argc	int	1	1
pool	NSAutoreleasePool *	0x17405eed0	0x000000017405eed0


it seams that from some reason, it cannot continue and is crashing :(
FBLoginComplete, result=1
Failed to Login or Canceled

But in the log I see that there is a session created message and after that.. another fail..

If I am running the app from the phone (and not from xcode), as I said earlier is just going to FB for a second, than the screen is turning black and comes into the game..

I added the FBAtResume() in OnResume()


Alex(Posted 2014) [#29]
You did not mention monkeyFB.OpenNewSession() in OnCreate() method. You should call it!


Alex(Posted 2014) [#30]
If this was all you did, you should also do this:
https://www.dropbox.com/s/s87koykptzqvjoq/Screenshot%202014-11-16%2018.28.24.png?dl=0

Taken from here:
https://developers.facebook.com/docs/ios/getting-started


Raul(Posted 2014) [#31]
@Alex: regarding monkeyFB.OpenNewSession() I though this is visible from the logs. I call it at the start of OnCreate()

also I update the plist file (mention in a post earlier).


Raul(Posted 2014) [#32]
Alex, do you have a small example that you are 100% sure is working? I could try comparing the code with mine..


Alex(Posted 2014) [#33]
Yes, I should make one! I'll post it here!


Alex(Posted 2014) [#34]
Here's the xCode project.
https://dl.dropboxusercontent.com/u/71223199/temp/ios.zip

See the log.
If you add me as a friend on fb, there will be two of us in the leadearboard and I will know you have succeeded! =)

Here's the full monkey code that works:
Import fbMonkey
Import brl

Global friendsNames:String[]
Global friendsIDs:String[]
Global friendsScore:Int[]
Global friendsAvas:Image[], noAva:Image

Global friendsIDsOld:String[]

Global fbYourPlace:Int, LoginFlowActive:Bool, loadingFBLeaderboardData:Bool

Global isLeaderboardFetched:Bool

Global sendingScoreFlow:Bool, lastPosted:Int, fbAppID:String

'Global isFBLoggedIn:Bool

Global monkeyFB := New MonkeyFacebook

Class MonkeyFacebook Implements IOnFBLoginComplete, IOnFBFetchComplete, IOnFBFetchFriendsComplete, IOnFBOpenNewSessionComplete, IOnFBSendScoreComplete, IOnFBShareComplete
	
	Field openNewSession:MonkeyOpenNewSessionFB
	Field login:MonkeyLoginFB
	Field fetch:MonkeyFetchFB
	Field fetchFriends:MonkeyFetchFriendsFB
	Field share:MonkeyShareFB
	Field sendScore:MonkeySendScoreFB

	Method InitAll:Void()

		#If TARGET = "ios"
			FBStart()
		#End

	End

	Method LoginInit:Void()

	End

	Method OpenNewSession:Void()

		openNewSession = New MonkeyOpenNewSessionFB
		openNewSession.FBOpenNewSessionAcync(Self)
		'OpenFlowActive = True

	End

	Method Login:Void()

		login = New MonkeyLoginFB
		login.FBLoginAsync(Self)
		LoginFlowActive = True

	End

	Method Fetch:Void()

		fetch = New MonkeyFetchFB
		fetch.FBFetchAsync(Self)

	End

	Method FetchFriends:Void()

		fetchFriends = New MonkeyFetchFriendsFB

		fetchFriends.FBFetchFriendsAsync(fbAppID, Self)

		isLeaderboardFetched = False

	End

	Method SendScore:Void(theScore:Int)

		sendScore = New MonkeySendScoreFB
		sendScore.FBSendScoreAsync(Self, theScore)
		sendingScoreFlow = True
		isLeaderboardFetched = False

	End

	Method Share:Void(theScore:Int, theName:String, theCaption:String, theLink:String, thePicLink:String, thePhrase1:String, thePhrase2:String)

		share = New MonkeyShareFB
		share.FBShareAsync(Self, theScore, theName, theCaption, theLink, thePicLink, thePhrase1, thePhrase2)

	End

	Method OnFBOpenNewSessionComplete:Void( result:Int ) '-1 - failed, 0 - success, 1 - cancelled'

		Print "OnFBOpenNewSessionComplete, result=" + result

		If result<>0 
			Print "Failed to Open New Session"
			login=Null
			LoginFlowActive = False
		Endif

		If result = 1

			LoginFlowActive = False
			Print "New Session Failed To Open"

		End

		If result = 0

			Self.Fetch()

		End

	End

	Method OnFBLoginComplete:Void( result:Int ) '-1 - failed, 0 - success, 1 - cancelled'

		Print "FBLoginComplete, result=" + result

		If result<>0 
			Print "Failed to Login or Canceled"
			login=Null
			LoginFlowActive = False
		Endif

		If result = 1

			Print "Login Cancelled"
			Self.LoginInit()
			LoginFlowActive = False

		End

		If result = 0

			Self.Fetch()

		End

	End

	Method OnFBFetchComplete:Void( result:Int ) '-1 - failed, 0 - success, 1 - cancelled'

		Print "FBFetchComplete, result=" + result

		If result<>0 
			Print "Failed to Fetch"
			fetch=Null
			LoginFlowActive = False
		Endif

		If result = 1

			Print "Fetch Cancelled"
			LoginFlowActive = False

		End

		If result = 0

			Print fbUserName
			Print fbUserID

			Self.FetchFriends()

			'ClearLeaderboardData()

		End

	End

	Method OnFBFetchFriendsComplete:Void( result:Int ) '-1 - failed, 0 - success, 1 - cancelled'

		Print "FBFetchFriendsComplete, result=" + result

		If result<>0 
			Print "Failed to FetchFriends"
			fetchFriends=Null
		Endif

		If result = 1

			Print "FetchFriends Cancelled"

		End

		If result = 0

			Print "Friends Fetched"

			friendsNames = friendsNames.Resize(friendsCount)
			friendsIDs = friendsIDs.Resize(friendsCount)
			friendsScore = friendsScore.Resize(friendsCount)

			friendsAvas = friendsAvas.Resize(friendsCount)

			friendsIDsOld = friendsIDsOld.Resize(friendsCount)

			For Local fr:Int = 0 Until friendsCount

				friendsNames[fr] = GetFriendName(fr)

				For Local frn$=Eachin friendsNames[fr].Split( " " )

					friendsNames[fr] = frn
					Exit
					
				Next

				If friendsNames[fr].Length() > 13

					friendsNames[fr] = friendsNames[fr][..10] + "..."

				End

				friendsIDs[fr] = GetFriendID(fr)

				friendsScore[fr] = GetFriendScore(fr)

				Print friendsIDs[fr]
				Print friendsNames[fr] + " score:" + friendsScore[fr]

				If friendsIDsOld[fr] <> friendsIDs[fr] Or friendsAvas[fr].Width() = 48 * Retina 'for noAvaImage'

					friendsAvas[fr] = noAva
					imageLoad.LoadFBAvaAsync(fr)
					Print "Image updating..."
					Print ""

				Else

					Print "No need to load a new image"

				End

				friendsIDsOld[fr] = friendsIDs[fr]

				If friendsIDs[fr] = fbUserID

					fbYourPlace = fr
					If friendsScore[fr] > bestResult
						bestResult = friendsScore[fr]
					Else
						lastPosted = friendsScore[fr]
					End

				End

			End

		End

		isLeaderboardFetched = True

		LoginFlowActive = False

	End

	Method OnFBSendScoreComplete:Void( result:Int ) '-1 - failed, 0 - success, 1 - cancelled'

		Print "FBSendScoreComplete, result=" + result

		If result<>0 
			Print "Failed to Send Score"
			sendScore=Null
		Endif

		If result = 1

			Print "SendScore Cancelled"

		End

		If result = 0

			Print "Score sent" + sendScore.scoreSent
			lastPosted = sendScore.scoreSent
			'SaveGame()
			Print "the last posted: " + lastPosted
			sendingScoreFlow = False
			monkeyFB.FetchFriends()

		End

	End

	Method OnFBShareComplete:Void( result:Int ) '-1 - failed, 0 - success, 1 - cancelled'

		Print "FBShareComplete, result=" + result

		If result<>0 
			Print "Failed to Share"
			sendScore=Null
		Endif

		If result = 1

			Print "Share Cancelled"

		End

		If result = 0

			Print "Shared!"

			'window.Init(["menu/yes"], text[71], text[72])

		End

	End

	Method Deinit:Void()



	End

End

Global imageLoad := New ImageLoadClass

Class ImageLoadClass Implements IOnLoadImageComplete

	Method LoadFBAvaAsync:Void(num:Int)
		Local avasize:Int = 50 * Retina
		LoadImageAsync(	"https://graph.facebook.com/" + friendsIDs[num] + "/picture?width=" + avasize + "&height=" + avasize, 
						1, 
						Image.MidHandle, 
						Self)
	End
	
	Method OnLoadImageComplete:Void( img:Image, path:String, source:IAsyncEventSource )
		If img
			Print "Image Loaded!"
			For Local fr:Int = 0 Until friendsCount
				If path.Contains(friendsIDs[fr])
					friendsAvas[fr] = img
				End
			End
		Else
			Print "Error loading image async"
		End
	End
End

'END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART'
'END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART'
'END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART'
'END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART'
'END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART'
'END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART'
'END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART'
'END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART'
'END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART'
'END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART'
'END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART'
'END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART'
'END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART'
'END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART''END FB PART'

Global Retina, bestResult:Int

Class GameGW Extends App
	
	Method OnCreate()
	
		monkeyFB.OpenNewSession()

		Retina = 2 'calculate as you always do
		bestResult = Rnd(100)' your score you will post to leaderboard

		noAva = LoadImage("noAva.png") 'must be 48px for update code to work'

		fbAppID = "552474708216230"

	End
	
	Method OnUpdate()

		UpdateAsyncEvents()

		If LoginFlowActive
			Return
		End

		If TouchHit() And TouchX() < DeviceWidth() * .2 And TouchY() < DeviceHeight() * .2

			If isIntenetConnected
				If isLoggedIn
					monkeyFB.SendScore( bestResult )
					bestResult += 1
				Else
					monkeyFB.Login()
				End
			End

		End

		
	End
	
	Method OnRender()

		DrawRect(0,0, DeviceWidth() * .2, DeviceHeight() * .2)
		If Not isLoggedIn
			DrawText("Login", 10, 10)
		Else
			DrawText("Share" + bestResult + " points", 10, 10)
		End

		For Local fr := 0 Until friendsCount

			DrawImage(friendsAvas[fr], DeviceWidth() * .21, DeviceHeight() * .3 + 20 * fr, 0, .4, .4)
			DrawText(friendsNames[fr], DeviceWidth() * .3, DeviceHeight() * .3 + 20 * fr)
			DrawText(friendsScore[fr], DeviceWidth() * .5, DeviceHeight() * .3 + 20 * fr)

		End

	End

	Method OnSuspend()

		isIntenetConnected()

	End

	Method OnResume()

		isIntenetConnected()
		FBAtResume()

	End

End

Function Main:Int()
        New GameGW
End

'This Is Fake, see my first posts on this'
Function isIntenetConnected:Bool()
	Return True
End



Raul(Posted 2014) [#35]
with the help of Alex I managed to achieve what I wanted. thank you again man.

this is one module which is a must for every mobile game these days.