Xamarin Forms Deep Linking - xamarin

I have tried getting Xamarin Forms deep linking to work by following the example in https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/deep-linking.
It tells me I must have a version of my app live on Google Play, and I must also have a companion website registered with Google.
How am I supposed to test, develop, and debug my app if it has to already be published for this to work?
Note that I don't want app indexing, I just want deep linking. This all seems a bit involved - why do I even need a website?
All I basically want to do is authenticate the user to Strava via OAuth and handle the redirect URI.
Is there a simple example of how to get just deep linking to work, in such a way as it could handle the redirect URI from Strava?

I seem to have discovered a solution that works which is to simply put an IntentFilter on the MainActivity of my app:
[IntentFilter(
new[] { Intent.ActionView },
Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
DataSchemes = new[] { "<my package name>" },
DataHosts = new[] { "redirect.authorize.strava.<my package name>" }
)]
When I do this, it successfully calls OnAppLinkRequestReceived when strava fires the redirect URL with the deep link.
Wouldn't have known that from any docs though....

Related

What is the correct way add a protocol to the macOS info.plist using electron-builder?

I need to be able to launch my Electron app from the the browser (like sign in to Slack does). I know that I can add my protocol name to my Electron app using app.setAsDefaultProtocolClient(protocol[, path, args]) in Electron.
Then in electron-builder, I can use the package.json config build.mac with the extendInfo property to define "The extra entries for Info.plist". This however is the only instructions the docs give on how to use it.
What is the correct way add a protocol to the macOS info.plist using electron and electron-builder config build.mac.extendInfo and be able to use it as described?
(Posted a solution on behalf of the question author to move it to the answer space).
It now works with the following - I have added this to my Electron package.json:
"protocols": {
"name": "my-app",
"schemes": [
"my-app"
]
},
"mac": {
"target": "dmg",
"extendInfo": "my-app"
},
I have this in the electron.js:
app.setAsDefaultProtocolClient('my-app');
And this in my React browser client app code to launch the application from the browser:
document.location = 'my-app://open?url='
This question relates to how custom schemes are used to receive OAuth responses, as in my code sample which you can run locally, then use deep linking etc:
Code
Blog Post
Points of interest:
An interstitial web page returns control to the browser app - see this page
My package.json exposes the scheme for Electron deployment
This should give you something to compare against. Here is the key code:
INTERSTITIAL WEB PAGE INVOKING APP
window.addEventListener('DOMContentLoaded', function() {
var redirectUri = 'x-mycompany-desktopapp:/callback';
if (window.location.search) {
redirectUri += window.location.search;
}
document.getElementById('continueButton').onclick = function() {
window.location.href = redirectUri;
};
}
REGISTERING THE SCHEME
This gets picked up by Electron packager and included in platform specific binaries, resulting in OS specific registration:
"build": {
"protocols": {
"name": "finaldesktopapp",
"schemes": [
"x-mycompany-desktopapp"
]
}
},
RECEIVING NOTIFICATIONS
This enables the following code to work in the main side of the app, as specified in the main.ts file:
app.setAsDefaultProtocolClient(this._configuration.oauth.privateSchemeName);
Finally you register a callback that can parse the URL and take whatever is the appropriate action - completing a login in my case.
private _receiveNotificationInRunningInstance(privateSchemeUrl: string) {
}
The mechanics are a little tricky and the notification is received differently on macOS to Windows / Linux. See this source file and its comments which explain the details.

Forgot password workflow in Xamarin forms [duplicate]

Guys, I need to implement Applink (Universal Link) step by step both android and iOS, please any to help achieve this. I tried the following code in my android project
I followed this URL to write this https://devblogs.microsoft.com/xamarin/connect-with-your-users-with-google-search-and-app-indexing/
Note I no need to indexing concept just want to open the app from Clicking of any URL
First I Installed Xamarin.Forms.AppLinks NuGet
Below code MainActivity
[IntentFilter(new[] { Android.Content.Intent.ActionView },
Categories = new[]
{
Android.Content.Intent.CategoryDefault,
Android.Content.Intent.CategoryBrowsable
},
DataScheme = "http",
DataPathPrefix = "/",
DataHost = "test.com")]
Then write bellow code in OnCreate Method
AndroidAppLinks.Init(this);
Then I try to call deeplink URL "test://DeeplinkingSample" from Deep Link Tester
Its saying No Activity found to handle the intent
4.Then I try to call deeplink url "test://DeeplinkingSample" from Deep Link Tester
Its saying No Activity found to handle intent
You are trying to call the URL test://DeeplinkSample, which has the following parts
Scheme is test
Host is DeeplinkSample
No data path
However, you did not register your activity for that URL, but for the scheme http, with the host test.com and the data path prefix / (i.e. presumably all data paths that start with /). Hence the app should open when you are trying to open
http://test.com/...

Xamarin.forms OnAppLinkRequestReceived

I'm trying to use https://developer.xamarin.com/api/member/Xamarin.Forms.Application.OnAppLinkRequestReceived/p/System.Uri/ but can't seem to get it to be called in any way.
Did anyone ever tried to implement this new method?
I've tried several ways to implement different deeplinks, all of them open the app fine so they're correctly configured but that method never gets called.
Thanks.
This is how I set it up in Android.
Put this above your MainActivity.cs
[IntentFilter(new[] { Android.Content.Intent.ActionView },
Categories = new[]
{
Android.Content.Intent.CategoryDefault,
Android.Content.Intent.CategoryBrowsable
},
DataScheme = "http",
DataPathPrefix = "/tesla/",
DataHost = "exrin.net")]
This registers the activity when the app is installed. Change the URL to your desired URL.
For Android only (no need to do this with iOS) you need to also install the Nuget Xamarin Forms AppLinks
In your OnCreate make sure you do this after your Xamarin Forms Init
AndroidAppLinks.Init(this);
Then when you load the URL in a browser (in my example http://exrin.net/tesla) you will get this:
Then if you open the app it will enter here with the full URL as the URI parameter. This is in the App.cs (Xamarin.Forms.Application)
protected override void OnAppLinkRequestReceived(Uri uri)
{
base.OnAppLinkRequestReceived(uri);
}
You can then decode the URI as you see fit to move to the specific page in your app that the URL relates to/
More details at Xamarin Forms AppLinks
Also, your MainActivity must be derived from FormsAppCompatActivity for it to work. Once I changed it to that from FormsApplicationActivity, it started working.

Google Drive SDK 1.8.1 RedirectURL

Is there any way to provide RedirectURL then using GoogleWebAuthorizationBroker?
Here is the sample code in C#:
Task<UserCredential> credential = GoogleWebAuthorizationBroker.AuthorizeAsync(secrets, scopes, GoogleDataStore.User, cancellationToken, dataStore);
Or we have to use different approach?
I have an "installed application" that runs on a user's desktop, not a website. By default, when I create an "installed application" project in the API console, the redirect URI seems to be set to local host by default.
What ends up happening is that after the authentication sequence the user gets redirected to localhost and receives a browser error. I would like to prevent this from happening by providing my own redirect URI: urn:ietf:wg:oauth:2.0:oob:auto
This seems to be possible using Python version of the Google Client API, but I find it difficult to find any reference to this with .NET.
Take a look in the implementation of PromptCodeReceiver, as you can see it contains the redirect uri.
You can implement your own ICodeReceiver with your prefer redirect uri, and call it from a WebBroker which should be similar to GoogleWebAuthorizationBroker.
I think it would be great to understand why can't you just use PrompotCodeReceiver or LocalServerCodeReceiver.
And be aware that we just released a new library last week, so you should update it to 1.9.0.
UPDATE (more details, Nov 25th 2014):
You can create your own ICodeReceiver. You will have to do the following:
* The code was never tested... sorry.
public class MyNewCodeReceiver : ICodeReceiver
{
public string RedirectUri
{
get { return YOU_REDIRECT_URI; }
}
public Task<AuthorizationCodeResponseUrl> ReceiveCodeAsync(
AuthorizationCodeRequestUrl url,
CancellationToken taskCancellationToken)
{
// YOUR CODE HERE FOR RECEIVING CODE FROM THE URL.
// TAKE A LOOK AT THE FOLLOWING:
// PromptCodeReceiver AND LocalServerCodeReceiver
// FOR EXAMPLES.
}
}
PromptCodeReceiver
and LocalServerCodeReceiver.
Then you will have to do the following
(instead of using the GoogleWebAuthorizationBroker.AuthorizeAsync method):
var initializer = new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = secrets,
Scopes = scopes,
DataStore = new FileDataStore("Google.Apis.Auth");
};
await new AuthorizationCodeInstalledApp(
new GoogleAuthorizationCodeFlow(initializer),
new MyNewCodeReceiver())
.AuthorizeAsync(user, taskCancellationToken);
In addition:
I'll be happy to understand further why you need to set a different redirect uri, so we will be able to improve the library accordingly.
When I create an installed application the current PromptCodeReceiver and LocalServerCodeReceiver work for me, so I'm not sure what's the problem with your code.

Windows Phone: Navigate between apps

I have an app that needs to include a links to a second app in the same phone.
If the app is not installed the link should point to the windows store to install it (that part is working fine).
But if the app is already installed the link should go straight to the app and open it. How can I do that?
The app has two versions one form WP7 and other from WP8. if the solution is different for them please point the difference.
Thanks for the help...
I believe a URI Association is what you want. You should be able to create a different association in your WP7 app and in your WP8 app, and handle them accordingly.
A URI association allows your app to automatically launch when another app launches a special URI.
Also note:
If you are interested only in launching your own apps, consider using
APIs from the Windows.Phone.Management.Deployment namespace. You can
use this API to check for other apps that you’ve published, and then
launch them if they’re installed.
You basically just need to update the WMAppManifest.xml file to include the URI Association and then listen for that URI. Example:
<Extensions>
<Protocol Name="contoso" NavUriFragment="encodedLaunchUri=%s" TaskID="_default" />
</Extensions>
Then you can use a custom URI Mapper to handle your association (full example in top link above):
public override Uri MapUri(Uri uri)
{
tempUri = System.Net.HttpUtility.UrlDecode(uri.ToString());
// URI association launch for contoso.
if (tempUri.Contains("contoso:ShowProducts?CategoryID="))
{
// Get the category ID (after "CategoryID=").
int categoryIdIndex = tempUri.IndexOf("CategoryID=") + 11;
string categoryId = tempUri.Substring(categoryIdIndex);
// Map the show products request to ShowProducts.xaml
return new Uri("/ShowProducts.xaml?CategoryID=" + categoryId, UriKind.Relative);
}
// Otherwise perform normal launch.
return uri;
}
Hope this helps!
Is the secondary app one that you have created? If so, do something like this:
IEnumerable<Package> packages = InstallationManager.FindPackagesForCurrentPublisher();
foreach (Package package in packages)
{
if (package.Id.ProductId.ToString().ToLower() == "product id of secondary app")
{
//Launch the app
package.Launch();
}
}
Make sure that your publisher ids match in the WMAppManifest for both apps.
If this secondary app was published by someone else, you'll need to use a custom Uri schema. The app needs to have this feature added by the developer, you can't just launch any app.

Resources