-
-
Save nguyenthanhliemfc/b68f7ffde293e0d325f980b511be9690 to your computer and use it in GitHub Desktop.
Xamarin.Forms DropboxService API v2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Threading.Tasks; | |
using Dropbox.Api; | |
using Dropbox.Api.Files; | |
using HLI.Forms.Services; | |
using Xamarin.Forms; | |
namespace MyApp | |
{ | |
public class DropBoxService | |
{ | |
#region Constants | |
private const string AppKeyDropboxtoken = "MyDropboxToken"; | |
private const string ClientId = "MyDropboxClientId"; | |
private const string RedirectUri = "https://www.anysite.se/"; | |
#endregion | |
#region Fields | |
/// <summary> | |
/// Occurs when the user was authenticated | |
/// </summary> | |
public Action OnAuthenticated; | |
private string oauth2State; | |
#endregion | |
#region Properties | |
private string AccessToken { get; set; } | |
#endregion | |
#region Public Methods and Operators | |
/// <summary> | |
/// <para>Runs the Dropbox OAuth authorization process if not yet authenticated.</para> | |
/// <para>Upon completion <seealso cref="OnAuthenticated"/> is called</para> | |
/// </summary> | |
/// <returns>An asynchronous task.</returns> | |
public async Task Authorize() | |
{ | |
if (string.IsNullOrWhiteSpace(this.AccessToken) == false) | |
{ | |
// Already authorized | |
this.OnAuthenticated?.Invoke(); | |
return; | |
} | |
if (this.GetAccessTokenFromSettings()) | |
{ | |
// Found token and set AccessToken | |
return; | |
} | |
// Run Dropbox authentication | |
this.oauth2State = Guid.NewGuid().ToString("N"); | |
var authorizeUri = DropboxOAuth2Helper.GetAuthorizeUri(OAuthResponseType.Token, ClientId, new Uri(RedirectUri), this.oauth2State); | |
var webView = new WebView { Source = new UrlWebViewSource { Url = authorizeUri.AbsoluteUri } }; | |
webView.Navigating += this.WebViewOnNavigating; | |
var contentPage = new ContentPage { Content = webView }; | |
await Application.Current.MainPage.Navigation.PushModalAsync(contentPage); | |
} | |
public async Task<IList<Metadata>> ListFiles() | |
{ | |
try | |
{ | |
using (var client = this.GetClient()) | |
{ | |
var list = await client.Files.ListFolderAsync(string.Empty); | |
return list?.Entries; | |
} | |
} | |
catch (Exception ex) | |
{ | |
AppService.WriteDebug(ex); | |
return null; | |
} | |
} | |
public async Task<byte[]> ReadFile(string file) | |
{ | |
try | |
{ | |
using (var client = this.GetClient()) | |
{ | |
var response = await client.Files.DownloadAsync(file); | |
var bytes = response?.GetContentAsByteArrayAsync(); | |
return bytes?.Result; | |
} | |
} | |
catch (Exception ex) | |
{ | |
AppService.WriteDebug(ex); | |
return null; | |
} | |
} | |
public async Task<FileMetadata> WriteFile(byte[] fileContent, string filename) | |
{ | |
try | |
{ | |
var commitInfo = new CommitInfo(filename, WriteMode.Overwrite.Instance, false, DateTime.Now); | |
using (var client = this.GetClient()) | |
{ | |
var metadata = await client.Files.UploadAsync(commitInfo, new MemoryStream(fileContent)); | |
return metadata; | |
} | |
} | |
catch (Exception ex) | |
{ | |
AppService.WriteDebug(ex); | |
return null; | |
} | |
} | |
#endregion | |
#region Methods | |
/// <summary> | |
/// Saves the Dropbox token to app settings | |
/// </summary> | |
/// <param name="token">Token received from Dropbox authentication</param> | |
private static async Task SaveDropboxToken(string token) | |
{ | |
if (token == null) | |
{ | |
return; | |
} | |
try | |
{ | |
Application.Current.Properties.Add(AppKeyDropboxtoken, token); | |
await Application.Current.SavePropertiesAsync(); | |
} | |
catch (Exception ex) | |
{ | |
AppService.WriteDebug(ex); | |
} | |
} | |
private DropboxClient GetClient() | |
{ | |
return new DropboxClient(this.AccessToken); | |
} | |
/// <summary> | |
/// Tries to find the Dropbox token in application settings | |
/// </summary> | |
/// <returns>Token as string or <c>null</c></returns> | |
private bool GetAccessTokenFromSettings() | |
{ | |
try | |
{ | |
if (!Application.Current.Properties.ContainsKey(AppKeyDropboxtoken)) | |
{ | |
return false; | |
} | |
this.AccessToken = Application.Current.Properties[AppKeyDropboxtoken]?.ToString(); | |
if (this.AccessToken != null) | |
{ | |
this.OnAuthenticated.Invoke(); | |
return true; | |
} | |
return false; | |
} | |
catch (Exception ex) | |
{ | |
AppService.WriteDebug(ex); | |
return false; | |
} | |
} | |
private async void WebViewOnNavigating(object sender, WebNavigatingEventArgs e) | |
{ | |
if (!e.Url.StartsWith(RedirectUri, StringComparison.OrdinalIgnoreCase)) | |
{ | |
// we need to ignore all navigation that isn't to the redirect uri. | |
return; | |
} | |
try | |
{ | |
var result = DropboxOAuth2Helper.ParseTokenFragment(new Uri(e.Url)); | |
if (result.State != this.oauth2State) | |
{ | |
return; | |
} | |
this.AccessToken = result.AccessToken; | |
await SaveDropboxToken(this.AccessToken); | |
this.OnAuthenticated?.Invoke(); | |
} | |
catch (ArgumentException) | |
{ | |
// There was an error in the URI passed to ParseTokenFragment | |
} | |
finally | |
{ | |
e.Cancel = true; | |
await Application.Current.MainPage.Navigation.PopModalAsync(); | |
} | |
} | |
#endregion | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading.Tasks; | |
using System.Windows.Input; | |
using Xamarin.Forms; | |
namespace HLI.Forms.ViewModels | |
{ | |
/// <summary> | |
/// Implements DropBoxService | |
/// </summary> | |
public class DropBoxViewModel | |
{ | |
#region Fields | |
private readonly DropBoxService dropBoxService = new DropBoxService(); | |
#endregion | |
#region Constructors and Destructors | |
public DropBoxViewModel() | |
{ | |
this.DropBoxGetCommand = new DelegateCommand(this.OnDropboxGet); | |
this.DropBoxSaveCommand = new DelegateCommand(this.OnDropboxSave); | |
} | |
#endregion | |
#region Public Properties | |
public ICommand DropBoxGetCommand { get; } | |
public ICommand DropBoxSaveCommand { get; } | |
public UriImageSource DropboxIcon | |
=> | |
new UriImageSource | |
{ | |
Uri = | |
new Uri( | |
new OnPlatform<string> | |
{ | |
WinPhone = "https://www.dropbox.com/s/affuim5lv2dqcq2/dropbox-windows-8.png?dl=1", | |
iOS = "https://www.dropbox.com/sh/zcxbhhco5x0bwmm/AAD6Nq7vmOBalRfOOe9oIa_va?dl=1", | |
Android = "https://www.dropbox.com/s/0l0fpn9yytzb1t7/dropbox-android.png?dl=1" | |
}) | |
}; | |
#endregion | |
#region Methods | |
private async void LoadDatabase() | |
{ | |
try | |
{ | |
// Read the database from DropBox folder | |
var db = await this.dropBoxService.ReadFile("DropBoxDatabasePath"); | |
// Write the database to storage | |
await this.sqLite.WriteDatabase(db); | |
AppService.WriteDebug("Drobpox", "Loaded database OK!"); | |
// Go back to origin | |
// await this.NavigationService.GoBackAsync(); | |
} | |
catch (Exception ex) | |
{ | |
} | |
} | |
private async void OnDropboxGet() | |
{ | |
// If the user authenticates - loads database to Dropbox | |
this.dropBoxService.OnAuthenticated += this.LoadDatabase; | |
await this.dropBoxService.Authorize(); | |
} | |
private async void OnDropboxSave() | |
{ | |
// If the user authenticates - save database to Dropbox | |
this.dropBoxService.OnAuthenticated += this.SaveDatabase; | |
await this.dropBoxService.Authorize(); | |
} | |
private async void SaveDatabase() | |
{ | |
try | |
{ | |
// Read the database from app storage | |
var db = this.sqLite.ReadDatabase(); | |
// Write the database to DropBox folder | |
await this.dropBoxService.WriteFile(db, "DropBoxDatabasePath"); | |
AppService.WriteDebug("Drobpox", "Saved database OK!"); | |
} | |
catch (Exception ex) | |
{ | |
AppService.WriteDebug(ex); | |
await this.MainPage.DisplayAlert("Dropbox", $"Something went wrong. If the problem persists, please contact us", "OK"); | |
} | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment