Unity Facebook SDK FB.Feed not posting - ios

I'm using the Unity Facebook SDK for my iOS game but FB.Feed isn't working. Using Unity 4.2.2 and Facebook SDK 4.2.4
Here's what happens:
Upon Game Start, FB init is called
void Awake () {
enabled = false;
FB.Init(SetInit, OnHideUnity);
}
private void SetInit()
{
enabled = true; // "enabled" is a magic global
FB.GetAuthResponse(LoginCallback);
}
private void OnHideUnity(bool isGameShown)
{
if (!isGameShown)
{
Time.timeScale = 0;
}
else
{
Time.timeScale = 1;
}
}
void LoginCallback(FBResult result)
{
Debug.Log("call login: " + FB.UserId);
FbDebug.Log("call login: " + FB.UserId);
Debug.Log("login result: " + result.Text);
FbDebug.Log("login result: " + result.Text);
if (result.Error != null)
{
Debug.LogError(result.Error);
return;
}
}
When I click the button for sharing on facebook, the following function is called:
public void FBShare() {
if(!FB.IsLoggedIn)
FB.Login("email,publish_actions", LoginCallback);
FB.Feed(
linkName: "My Game",
linkDescription: "Just played My Game. It's awesome!",
linkCaption: "I just smashed 4" + " friends! Can you beat it?",
picture: "http://www.friendsmash.com/images/logo_large.jpg",
callback: LogCallback
);
}
If I'm not logged in, then I get a login prompt on facebook (switching to the FB app)
If I haven't authorized the app, then I get a prompt for that as well.
And then the Facebook Share Feed appears with all the specified information I put in the function, all the previous steps working properly.
The problem starts once I touch the post button. The app starts uploading my post but then abruptly switches back to the game.
Tearing my hair out for the past 3 days. Can't find anything to help. Logs from the callback functions are return empty responses.

Login is an asynchronous function. Once you call it it will multitask out of your app and try to authenticate. You are immediately calling Feed after calling login. Feed will also try to multitask out of your app. You make a custom login callback for this case and call feed from inside of it.

I finally figured it out. The problem was an incorrect bundle ID on the Facebook app online, the changes took some time to propagate to all FB servers so it wasn't immediately apparent what was the problem.

Related

How do I implement Facebook login with SFAuthenticationSession or SFSafariViewController in React Native?

What's the de-facto way to implement Facebook login with React Native? I'm looking for a way that Apple accepts (doesn't get rejected).
Apparently react-native-fbsdk doesn't use SFSafariViewController (it just opens a safari webview) and this isn't acceptable by Apple... they've rejected my app because of this.
My current code. Opens Safari webview.
LoginManager.setLoginBehavior('browser')
class FBLogin extends Component {
handleFacebookLogin = async () => {
try {
const result = await LoginManager.logInWithReadPermissions([
'public_profile',
'email',
'user_friends',
])
if (result.isCancelled) {
alert('Login cancelled')
} else {
const token = await AccessToken.getCurrentAccessToken()
this.props.login(token)
}
} catch (error) {
alert(`login error: ${error}`)
}
}
render() {
return (
<LoginButton
type={'primary'}
block
onPress={() => this.handleFacebookLogin()}
>
Login with Facebook
</LoginButton>
)
}
}
Rejected by Apple due to
We noticed that the user is taken to Safari to sign in or register for an account, which provides a poor user experience.
You can try using "react-native-app-auth" library. It has implemented SFAuthenticationSession with SFSafariViewController (Apple way of authenticating users for iOS 11 & up).
They have a pretty neat documentation: http://npm.taobao.org/package/react-native-app-auth

Xamarin forms geolocator plugin working intermittently

We are trying to use the plugin "Xam.Plugin.Geolocator" in our Xamarin Forms project. The project is currently IOS only.
Our app returns a list of business based on the device users current location. We hit an API to return our JSON formatted list data and the API is functioning correctly.
We would like the list to update whenever the user pulls down, changes tab and when the page initially loads but currently this is only working once or twice in around 100 attempts. I've not found a pattern yet to why it's failing, or indeed when it works.
We set App Properties when the page loads, the tab is selected and the user refreshes like this -
public async void GetLocation()
{
try
{
locator = CrossGeolocator.Current;
if (locator.IsGeolocationAvailable && locator.IsGeolocationEnabled)
{
var position = await locator.GetPositionAsync();
App.Current.Properties["Longitude"] = position.Longitude.ToString();
App.Current.Properties["Latitude"] = position.Latitude.ToString();
}
else
{
await DisplayAlert("Location Error", "Unable to retrieve location at this time", "Cancel");
}
}catch(Exception e)
{
await DisplayAlert("Location Error", "Unable to retrieve location at this time","Cancel");
}
}
We call the above method in the three areas
1) when the page is loaded
public NearbyPage()
{
InitializeComponent();
GetLocation();
SetNearbyBusinesses();
NearbyBusinesses = new List<NearbyBusiness>();
SetViewData();
SetViewVisibility();
}
2) when the tab is clicked
protected override void OnAppearing()
{
base.OnAppearing();
GetLocation();
SetNearbyBusinesses();
NearbyLocationsView.ItemsSource = NearbyBusinesses;
NoLocationsView.ItemsSource = UserMessages;
SetViewVisibility();
}
3) when the user pulls down to refresh
public void RefreshData()
{
if (!CrossConnectivity.Current.IsConnected)
{
NoInternetMessage.IsVisible = true;
return;
}
GetLocation();
NoInternetMessage.IsVisible = false;
SetNearbyBusinesses();
NearbyLocationsView.ItemsSource = NearbyBusinesses;
NoLocationsView.ItemsSource = UserMessages;
SetViewVisibility();
_analyticsService.RecordEvent("Refresh Event: Refresh nearby businesses", AnalyticsEventCategory.UserAction);
}
Can anyone shed some light on what we're doing wrong or have experience with this plugin that can help us resolve this issue?
Thank you
EDIT
By "work", i mean that we'd like it to hit our API with the users current location data and return new results from the API every time the user pulls down to refresh, the page is loaded initially or when they press on a specific tab. Currently it works occasionally, very occasionally.
We can't debug with a phone connected to a macbook, as since we installed the geolocator plugin the app always crashes when connected. The app seems to work ok when deployed to a device, apart from the location stuff. We're currently deploying to test devices via Microsofts Mobile Centre.
Ok, so with the debugger always crashing and being unable to see any stack trace etc we took a few shots in the dark.
We've managed to get this working by adding async to our method signatures down through our code stack. This has resolved the issue and the geo location and refresh is working perfectly.
For example when we changed the above method 3. to refresh the data, it worked perfectly.
public async Task RefreshData()
{
if (!CrossConnectivity.Current.IsConnected)
{
NoInternetMessage.IsVisible = true;
return;
}
GetLocation();
NoInternetMessage.IsVisible = false;
SetNearbyBusinesses();
NearbyLocationsView.ItemsSource = NearbyBusinesses;
NoLocationsView.ItemsSource = UserMessages;
SetViewVisibility();
_analyticsService.RecordEvent("Refresh Event: Refresh nearby businesses", AnalyticsEventCategory.UserAction);
}
We refactored more of that code but adding async was what got it working.
I hope this helps someone else save some time.

Air for IOS Webview - apple app review says every tab and/or button launches mobile Safari.?

I pulling my hair out trying to figure out where I have gone wrong.
I created a very simple app for ios that uses webView to load certain webpages within app. from my knowledge and every ios air webView reference I have found online I have coded everything correctly. Runs beautifully on android.
apple app review says every tab and/or button launches mobile Safari.?
I don't see how this is possible because they even said my button that only has gotoAndPlay(2); apparently that navigates to Safari also. ?
here's the code I used for webView:
QMBTN.addEventListener(MouseEvent.CLICK, QMB);
function QMB(event:MouseEvent):void
{
webView.viewPort = new Rectangle( 0, 135, stage.stageWidth, 600 );
webView.stage = this.stage;
webView.loadURL( "http://mywebpageeurl.com.au" );
whiteBOX.gotoAndStop(2);
}
and this is the code for my internal frame nav.
Menu_BTN2.addEventListener(MouseEvent.CLICK, GoMenuSRC);
function GoMenuSRC(event:MouseEvent):void
{
webView.stage = null;
whiteBOX.gotoAndStop(1);
}
Am I missing something or ????
The only other thing I could think could be the culprit might be my error handler to handle errors when I click tel: or mailto: links on my webpages.
The code for the tel: / mailto: error handling.
// Error handle
var openLinksInDefaultBrowser = false;
//Check tel: func
function cdCTfunc():void
{
var NEWtelLNK = webView.location.substr(0,4);
if (NEWtelLNK=='tel:')
{
openLinksInDefaultBrowser = true;
}else{openLinksInDefaultBrowser = false;}
}
webView.addEventListener(LocationChangeEvent.LOCATION_CHANGING, function (ev:LocationChangeEvent):void
{
cdCTfunc();
if(openLinksInDefaultBrowser == false)
{
ev.preventDefault();
webView.loadURL(ev.location); //'ev.url' changed to 'ev.location'started with prerelease build - [07/20/10]
}
if (openLinksInDefaultBrowser == true)
{
trace('page loaded in default browser');
var phStr:String=ev.location;
var callPH:URLRequest= new URLRequest(phStr);
navigateToURL(callPH);
}
});
webView.addEventListener(LocationChangeEvent.LOCATION_CHANGE, function (ev:LocationChangeEvent):void
{
if (webView.location.indexOf('authentication_complete') != -1)
{
trace('auth token is: ' + webView.location.substr(webView.location.indexOf('token=') + 6));
}
trace('the new location is: ' + webView.location);
trace(webView.location.substr(0,4));
});
webView.addEventListener('complete', function(ev:Event):void
{
trace('complete event');
});
webView.addEventListener('error', function(ev:ErrorEvent):void
{
var phStr:String=webView.location;
var callPH:URLRequest= new URLRequest(phStr);
navigateToURL(callPH);
webView.isHistoryBackEnabled;
webView.historyBack();
trace('SOME Bloody Error Loading The Page: ' + ev.text);
trace(openLinksInDefaultBrowser);
});
but I still don't see how this could cause a gotoAndStop(); to launch safari.
I am absolutely stumped.
Please Help?
Thank you in advance.
Before submitting your app for review you should run it through Testflight.
This allows you to test an 'AppStore' build of your binary so you will see exactly what the reviewer will see.
http://www.yeahbutisitflash.com/?p=7608

Google Plus iOS GPGManager error "Mismatched Authentication"

I have a Unity app that includes a button to sign into Google Plus. In the iOS version of the app I've had to override the default behaviour of the Google Plus SDK to prevent it switching to Safari to sign in and to use a WebView instead. This is due to Apple's policy of rejecting apps that sign into Google Plus via Safari.
That's all fine and the sign-in process works via the WebView. I've added a "Cancel" button that overlays the WebView so that users can decide not to sign in and return to the app. The code that handles the cancel button is:
- (IBAction)handleCancelClick:(id)sender {
// Cancel the sign-in process
[[GPGManager sharedInstance] signOut];
//Reactivate the sign-in button
UnitySendMessage("Persistent Services", "cancelSignIn", "");
// Hide the webview
[_unityViewController dismissViewControllerAnimated:YES completion:nil];
}
The problem is that subsequent attempts to sign in after using the cancel button fail. I see the following error when debugging in XCode:
2015-04-29 21:33:05.328 [Core] (Error) -[GPGManager finishedWithAuth:error:]:[main]
FAILED LOGGING INTO GOOGLE PLUS GAMES Error Domain=com.google.GooglePlusPlatform
Code=-1 "Mismatched authentication" UserInfo=0x1c163870
{NSLocalizedDescription=Mismatched authentication}
As I say, this only happens after the cancel button has been used. If the sign-in process goes through in a single flow, it works.
The Unity code that's called when the sign-in button is pressed is:
public void logIn () {
Debug.Log ("Attempting to log in");
signingIn = true;
Social.localUser.Authenticate ((bool success) =>
{
if (success) {
...
} else {
Debug.Log ("Failed to Log in to Google Play Services");
}
signingIn = false;
});
}
I'm assuming that the first time Social.localUser.Authenticate() is called, some state is set up that isn't overwritten on subsequent calls. When the sign-in process finishes it then checks the callback auth code against what was set on the first call to Authenticate() and they don't match. But I may be way off the mark.
Can you suggest a way of completely resetting the sign-in process when cancelling or of otherwise resolving this problem?
I got around the problem by making sure Social.localuser.Authenticate() isn't called a second time. Subsequent presses of the 'sign-in' button just cause the WebView to be redisplayed.
To achieve this, I set a flag in the Unity method called from Objective-C code when the 'Cancel' button is pressed.
#if UNITY_IOS
/**
* Currently only called from Native iOS code.
*/
public void cancelSignInFromIos() {
hasCancelledInIos = true;
}
#endif
I then wrap the sign-in code in a conditional statement that checks the value of this flag. If the 'Cancel' button has been pressed, I send a message back to native code to instruct it to display the WebView.
if (!hasCancelledInIos)
Social.localUser.Authenticate ((bool success) =>
{
...
}
} else {
#if UNITY_IOS
hasCancelledInIos = false;
fromUnityshowWebView ();
#endif
}
The native method is defined in Unity-side code like this:
#if UNITY_IOS
System.Runtime.InteropServices.DllImport("__Internal")]
extern static public void fromUnityshowWebView();
#endif
And is implemented in native code like this:
extern "C" {
void fromUnityshowWebView() {
[[NSNotificationCenter defaultCenter] postNotificationName:ApplicationOpenGoogleAuthNotification object:#"blank"];
}
}
The notification fired here is handled by a method that displays the WebView overlay e.g.
- (void) showWebView
{
[unityViewController presentViewController:self.webViewController animated:YES completion:nil];
}
Long-winded, but it works.

Facebook Unity deep linking doesn't work

I sent a request out using FB.AppRequest and I got this on my iPad:
Request Sent {"to":["54742366872XXXX"],"request":"1521526728123676"}
And when I opened the App by tap my Facebook notification on iPod, and called deep linking. I got this:
fb170085486532707://authorize/#target_url=http%3A%2F%2Fm.facebook.com%2Fappcenter%2Fjbislands%3Ffbs%3D1001%26request_ids%3D322759461248823%252C333157203553454%26ref%3Dnotif%26app_request_type%3Duser_to_user
I don't see any connection between those number. And when I run what Facebook example:
void DeepLinkCallback(FBResult response) {
if(response.Text != null) {
var index = (new Uri(response.Text)).Query.IndexOf("request_ids");
if(index != -1) {
// ...have the user interact with the friend who sent the request,
// perhaps by showing them the gift they were given, taking them
// to their turn in the game with that friend, etc.
}
}
I always get -1 for index. Can anyone tell me how to read this deep link thing?

Resources