Using Xamarin.Auth.OAuth2Authenticator with async/await
Introduction
Xamarin.Auth is a component/library for Xamarin.Android and Xamarin.IOS that allows to use OAuth and OAuth2.0 authentication in apps developed using Xamarin.
This is very useful but there is one point it could be better, when we use it to authenticate the method used to do the call not allow to use async/await and is a fundamental in C# (or for example in Windows Phone and Windows Store apps).
For how that uses Xamarin.Auth.OAuth2Authenticator for authentication here is a solution for each target:
Code
For Xamarin.Android
public async Task<Account> LoginAsync(Activity activity, bool allowCancel)
{
var auth = new OAuth2Authenticator(
clientId: "<scopes here>",
scope: "<scopes here>",
authorizeUrl: new Uri("<url here>"),
redirectUrl: new Uri("<url here>"))
{
AllowCancel = allowCancel
};
// If authorization succeeds or is canceled, .Completed will be fired.
var tcs1 = new TaskCompletionSource<AuthenticatorCompletedEventArgs>();
EventHandler<AuthenticatorCompletedEventArgs> d1 =
(o, e) =>
{
try
{
tcs1.TrySetResult(e);
}
catch (Exception ex)
{
tcs1.TrySetResult(new AuthenticatorCompletedEventArgs(null));
}
};
try
{
auth.Completed += d1;
var intent = auth.GetUI(activity);
activity.StartActivity(intent);
var result= await tcs1.Task;
return result.Account;
}
catch (Exception)
{
// todo you should handle the exception
return null;
}
finally
{
auth.Completed -= d1;
}
}
And then we need to call it this way:
var authService = new AuthService();
var result = await authService.LoginAsync(this, allowCancel);
For Xamarin.IOS
public async Task<Account> LoginAsync(DialogViewController dialog, bool allowCancel)
{
var auth = new OAuth2Authenticator(
clientId: "<scopes here>",
scope: "<scopes here>",
authorizeUrl: new Uri("<url here>"),
redirectUrl: new Uri("<url here>"))
{
AllowCancel = allowCancel
};
// If authorization succeeds or is canceled, .Completed will be fired.
var tcs1 = new TaskCompletionSource<AuthenticatorCompletedEventArgs>();
EventHandler<AuthenticatorCompletedEventArgs> d1 =
(o, e) =>
{
try
{
tcs1.TrySetResult(e);
}
catch (Exception ex)
{
tcs1.TrySetResult(new AuthenticatorCompletedEventArgs(null));
}
};
try
{
auth.Completed += d1;
var vc = auth.GetUI();
dialog.PresentViewController(vc, true, null);
var result= await tcs1.Task;
return result.Account;
}
catch (Exception)
{
// todo handle the exception
return null;
}
finally
{
auth.Completed -= d1;
}
}
And then we need to call it this way:
var authService = new AuthService();
var result = await authService.LoginAsync(dialog, allowCancel);
In conclusion, I think it is very simple to use and I think it should be added to the Xamarin.Auth library.
Code Samples
See Also