I am writing a Xamarin iOS app and having difficulty integrating Facebook SSO, though I don't think my problem is necessarily Xamarin-specific, just a lack of understanding of how to integrate Facebook SSO without the benefit of the Facebook iOS SDK.
I have followed the various guides and have done the following:
1) Have a Facebook App set up:
a) iOS Platform added with bundle id matching my app's bundle id
b) Single sign on enabled
2) Set up my info.plist as follows:
raw text:
<key>CFBundleDisplayName</key>
<string>[company]</string>
<key>CFBundleIdentifier</key>
<string>com.[company].ios.app</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fb123490xxx</string>
</array>
<key>CFBundleURLName</key>
<string>com.[company].ios.app</string>
</dict>
</array>
<key>FacebookAppID</key>
<string>123490xxx</string>
<key>FacebookDisplayName</key>
<string>[company] Staging</string>
3) Implemented the following code in my app:
FacebookLoginButton.TouchUpInside += (sender, e) =>
{
var urlWithAppProtocol = new NSUrl("fb123490xxx://");
UIApplication.SharedApplication.OpenUrl(urlWithAppProtocol);
};
I have not overriden AppDelegates methods (OpenUrl and HandleOpenUrl) yet because as far as I can see those handle incoming redirects to my app; I will get that working next.
To be clear, what I'm expecting to see is the FB iOS App equivalent of this screen (from Mobile Safari)
However, if I redirect to:
"fb://[appid]" I get redirected to the FB app but just to the news feed page (or whatever screen I was on last when I was using the FB app)
"fb[appid]://" I get nothing happening, .OpenUrl() does nothing;
"fb://profile/[appid]" as an experiment, I get the following (notice the "app isn't available for your phone"); this could be because you're supposed to use the PageID with /profile.
What am I missing here?
Ok, in the end it was simply using fbauth://authorize in conjunction with the normal query string parameters in the oauth url. The redirect url needs to be fbconnect://success
I found this by reading the source code of the FB iOS SDK:
https://github.com/keithpitt/DKSocial/blob/72cd77bc15ca1a307b92aff8382f2c71a97da7de/External/FBConnect/Facebook.m
There might be a lesson here to use the Xamarin bindings of the official Facebook iOS SDK, which offers this functionality. I've ended up going down the manual route because I started with the Facebook .NET SDK, which doesn't seem to offer this App-based SSO functionality.
Related
The Problem:
I am building an app that uses PayPal for payments, and I set up universal links so that the user gets redirected into the app after the user has confirmed the payment at PayPal's site.
Universal links are working in general. But here is what I have discovered:
The following scenario works:
App opens the nextActionUrl from PayPal using SFSafariViewController.
User has to log in and presses the login button.
User presses the confirmation button on the PayPal site.
PayPal redirects to the return_url that was provided when creating the payment intent.
The browser closes, and the user gets redirected into the app.
Now when the user has just recently logged into PayPal then PayPal does not show the login page, instead the user has to only press one button. This scenario fails:
App opens the nextActionUrl from PayPal using SFSafariViewController.
User does not have to log in and presses the confirmation button on PayPal site.
PayPal redirects to the return_url that was provided when creating the payment intent.
The browser opens the website behind the universal link instead of redirecting to the app.
This scenario also works:
App opens the nextActionUrl from PayPal using SFSafariViewController.
User does not have to log in, but actively logs out.
User has to log in and presses the login button.
User presses the confirmation button on the PayPal site.
PayPal redirects to the return_url that was provided when creating the payment intent.
The browser closes, and the user gets redirected into the app.
This happens consistently and reproducible.
Some additional details:
I am developing the App using Flutter
I set up the Runner.entitlements as follows:
...
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:sub.example.com</string>
</array>
...
I set up the Info.plist as follows for deep links with different schema:
...
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>sub.example.com</string>
<key>CFBundleURLSchemes</key>
<array>
<string>web+example</string>
</array>
</dict>
</array>
...
I set up the apple-app-site-association file on the website at https://sub.example.com/.well-known/apple-app-site-association as follows:
{
"activitycontinuation": {},
"webcredentials": {},
"applinks": {
"apps": [],
"details": [
{
"appID": "XXXXXXXXXX.com.example.example",
"paths": [ "/*" ]
}
]
}
}
To open the urls from Flutter I am using the package url_launcher and simply call await launchUrl(nextActionUrl)
What I've tried and what I've learned:
I tried many things, before I discovered this consistent behavior. For example:
I connected my device to the mac and opened the console for it in xcode to see how the logs look like when it works and how it looks like when it does not work. I found out that when it works there is a log entry that requests the switch to my App from the SpringBoard-process: [Received trusted open application request for <applicationId> from <FBProcess: ...], but in the cases where it does not work there isn't a rejected request or anything. The SafariViewController does not even seem to try to go the universal link route and instead opens the link as a website directly.
For even more logs, I pressed and hold the volume buttons and clicked the lock screen button until a haptic feedback occurred. After that, I extracted the syslogs that were generated from the settings/privacy section via AirDrop on to the mac. I took a look at the swcutil_show.txt file and the universal link is definitely set up correctly there. I also skimmed around in the other logs, but I couldn't find anything helpful.
I have inspected the url_launcher package to see how it works for iOS and if there may be something wrong, but I didn't really find a problem. I only discovered that the package is using the SFSafariViewController and after some googling I've read the WKWebView would be more suitable, but it didn't seem to be the problem.
I googled a lot and found many problems related with setting up universal links correctly, but no topics about universal links sometimes working and sometimes not. The only thing close I found was that a universal link won't redirect you to your app if you type it into safari directly but if you click it for example from an email.
The workaround that works...
After I confirmed that it consistently works after logging in first, my theory was that it needs at least one navigation between opening the PayPal site in the browser and PayPal redirecting to the universal link.
To confirm my theory I created an intermediate page that redirects the user immediately after the load event to the PayPal site and I was disappointed. It didn't change anything.
Then I thought: Maybe it's the User-Interaction that is needed, and I change the intermediate page to only redirect if the user presses a button. And from there on, redirecting to the App using a universal link always worked.
But this isn't a nice solution - at max, this is an ugly workaround that may help someone.
My question(s)
Now I am not sure if this is a bug on Apple's side since I didn't find anything on the web or maybe even something strange on PayPal's side?
Am I doing something wrong?
Did someone experience the same thing and has a solution?
Thank you for your time and hopefully for your input on this!
I have an application in IOS in which there is a Facebook Login Button.
when ever user clicks this Facebook login button My app redirects the user to the Facebook App installed in my device. So I want to logout the user from the application as soon as he leaves the facebook app and comes to my app.
i redirect the user to the facebook app using
NSUrl url = NSUrl.FromString("fb://profile/<id>");
UIApplication.SharedApplication.OpenUrl(url);
I found the Facebook login documentation. As the documentation described, I think you have added the CFBundleURLTypes, like this:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fb[APP_ID]</string>
</array>
</dict>
</array>
It means that Facebook will trigger the openURL to return back to your app via the URLScheme you have set here.
So, you can override OpenUrl(UIApplication app, NSUrl url, NSDictionary options) in AppDelegate.cs, and the parameters url or options contain the information related to Facebook. So, you can identify the resource.
public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
{
Console.WriteLine(url);
Console.WriteLine(options);
return true;
}
According to this, you can do the action you want when return back from Facebook.
Are you using the Xamarin Facebook SDK? If yes you can do this to log out:
new LoginManager().LogOut();
This is a fairly straightforward one: to date, can an iOS app deep link or in any way launch Amazon Music to play a specific song/load an artist or album? How much of this can be done?
If you're feeling really generous, could you describe how to find the URLs to deep link to third party apps like AM, Facebook, Twitter and Spotify?
So I opened up the "Amazon Music" .ipa file (it's basically just a .zip file you can unzip) and in the app's Info.plist file I see a URL scheme that the app answers to:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.amazon.mp3</string>
<key>CFBundleURLSchemes</key>
<array>
<string>amznmp3</string>
</array>
</dict>
</array>
Unfortunately, this is not a public scheme. That is, there's no documentation available for it that can be googled (or I would have expected to have found it on a page like this).
This means you will probably have do additional research to figure out what kind of parameter to pass along with the scheme. For example, on this page I see a potential parameter of "fb164734381262". Perhaps it's a mp3 file identifier?
My application is a little different, but may be helpful. I am using the Workflow app to automate several things. I can interact with the Amazon Music app through the URL below.
https://music.amazon.com/playlists/B0797C4SN9?do=play
When the URL is opened in Workflow, it causes the Amazon Music app to open. A specific playlist is opened, then it starts playing.
You can create others by opening the app, sharing the playlist to notes. Deleting all of the information after the ? from the URL. Then add do=play to the end of the URL.
I think this would apply to songs and albums as well.
I would really like to know how to get the shuffle playlist from URL, so if somebody figures that out, let me know.
The answer by #Kyle365 works with iOS Shortcuts as well, was able to play a private and public playlist by copying the playlist’s url (share > copy) and changed the url to include ?do=play at the end. I created a shortcut that opens this url and Shortcuts recognizes the url as an Amazon Music url and opens it directly in the Amazon Music app and starts playing it.
Example of Url:
https://music.amazon.com/user-playlists/somePlaylistId?do=play
I am currently having problems using a WebView with this API to login to my app. I feel like I've set up something wrong somewhere, but can't put my finger on it.
Here's the error I'm getting :
Given URL is not allowed by the Application configuration code:191
I've set up my application descriptor like this (the x's are my app id)
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fbxxxxxxxxxxxxxxx</string>
</array>
</dict>
</array>
<key>CFBundleURLName</key>
<string>xxxxxxxxxxxxx</string>
I don't know if I need to add a setting in my facebook app page, but I've enabled embedded browser login and that's it.
Am I forgetting something here ?
Thanks for the help !
The problem can be caused by many things. I've used this and it helped me a lot:
http://afterisk.wordpress.com/2013/02/26/first-free-facebook-single-sign-on-sso-adobe-air-native-extension-for-android/
It important to follow almost every step as there are multiple properties in Facebook that you must set.
Second, check this SO: Facebook API error code 191
I don't know what's the url that you open - it's best to get it as login url from FB.
I hope that helps and will solve your problem :)
I'm currently work on a iOS/Phonegap app, I want to have it respond to a custom URL scheme, so that when a person clicks on a link in the regular browser it will open the app to a specific page, where said page is actually an external page. The app thus far essentially acts as a web browser where external (web) content is displayed in ChildBrowser.
I am 95% certain I need to use the following method in AppDelegate.
- (BOOL) execute:(InvokedUrlCommand*)command{}
And I know I need to use the following to create my command.
+ (InvokedUrlCommand*) newFromUrl:(NSURL*)url;
My problem is that I've been unable to find any examples online of doing this. I know the url passed to newFromUrl needs to be in the format of yourscheme://<sessionKey>#<Class>.<command>/[<arguments>][?<dictionary>] But in this case, my [<arguments>] would be a regular url of the form "http://www.google.com".
Can some one give a concrete real-world example?
This is implemented in current versions of PhoneGap so that all you need to do is add you custom URL to the App-info.plist file. Here is a sample of the XML:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.cams.myapp</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myApp</string>
</array>
</dict>
</array>
You should use the Property editor to edit this file and get the format correct.