読者です 読者をやめる 読者になる 読者になる

しっぽを追いかけて

ぐるぐるしながら考えています

Unity と猫の話題が中心   掲載内容は個人の私見であり、所属組織の見解ではありません

Xamarin.Forms で Facebook に写真をアップロードしてみる

Android C# Windows ランタイムアプリ Xamarin Facebook

前回 ウォール投稿ができたので、今度は写真のアップロードを試します

といっても C# ライブラリパワーがあればかんたんです

/// <summary>
/// Page appearing event handler
/// </summary>
protected override void OnAppearing()
{
    base.OnAppearing();

    // Navigate to facebook authorize page
    this.webView.Source = string.Format(@"https://m.facebook.com/dialog/oauth?client_id={0}&redirect_uri={1}&response_type=code,token&scope=publish_actions",
        AppId,
        WebUtility.UrlEncode(@"http://www.facebook.com/connect/login_success.html"));

    this.webView.Navigating += this.OnNavigating;
}

/// <summary>
/// WebView navigating event handler
/// </summary>
/// <param name="sender">event sender</param>
/// <param name="e">event arguments</param>
private async void OnNavigating(object sender, WebNavigatingEventArgs e)
{
    if (e.Url.StartsWith(@"http://www.facebook.com/connect/login_success.html"))
    {
        this.webView.Navigating -= this.OnNavigating;

        var uri = new Uri(e.Url);
        if (!string.IsNullOrEmpty(uri.Fragment) && uri.Fragment.StartsWith("#access_token"))
        {
            var token = uri.Fragment.Split('&').First().Split('=').LastOrDefault();
            var cancel = new CancellationTokenSource();

            using (var client = new HttpClient())
            {
                // Content-type: multipart/form-data
                using (var data = new MultipartFormDataContent())
                {

                    var parameters = new Dictionary<string, string>
                    {
                        {"caption", @"これは facebook アプリ写真アップロードのテストです"},
                        {"no_story", @"true" },
                        {"privacy", @"{""value"":""SELF""}"},
                    };
                    foreach (var param in parameters)
                    {
                        data.Add(new StringContent(param.Value), param.Key);
                    }

                    // Add photo binary stream data
                    var image = (StreamImageSource)ImageSource.FromResource("XamarinFacebook.Assets.cat.jpg");
                    data.Add(new StreamContent(await image.Stream.Invoke(cancel.Token)), "image", @"cat.jpg");


                    var result = await client.PostAsync(
                        string.Format(@"https://graph.facebook.com/me/photos?access_token={0}", token), data, cancel.Token);

                    var json = await result.Content.ReadAsStringAsync();

                    var response = JsonConvert.DeserializeObject(json);
                    Debug.WriteLine(response);

                    await DisplayAlert("XamarinFacebook", string.Format("facebook 写真アップロードに成功しました, response={0}", response), "OK");
                }
            }
        }
        else
        {
            // Login failed
            await DisplayAlert("XamarinFacebook", "OAuth 認証に失敗しました", "OK");
        }
    }
}

前回のコードから変更したのは次の箇所

            var cancel = new CancellationTokenSource();

            using (var client = new HttpClient())
            {
                // Content-type: multipart/form-data
                using (var data = new MultipartFormDataContent())
                {

                    var parameters = new Dictionary<string, string>
                    {
                        {"caption", @"これは facebook アプリ写真アップロードのテストです"},
                        {"no_story", @"true" },
                        {"privacy", @"{""value"":""SELF""}"},
                    };
                    foreach (var param in parameters)
                    {
                        data.Add(new StringContent(param.Value), param.Key);
                    }

                    // Add photo binary stream data
                    var image = (StreamImageSource)ImageSource.FromResource("XamarinFacebook.Assets.cat.jpg");
                    data.Add(new StreamContent(await image.Stream.Invoke(cancel.Token)), "image", @"cat.jpg");


                    var result = await client.PostAsync(
                        string.Format(@"https://graph.facebook.com/me/photos?access_token={0}", token), data, cancel.Token);

                    var json = await result.Content.ReadAsStringAsync();

                    var response = JsonConvert.DeserializeObject(json);
                    Debug.WriteLine(response);

                    await DisplayAlert("XamarinFacebook", string.Format("facebook 写真アップロードに成功しました, response={0}", response), "OK");
                }
            }

MultipartFormDataContent を HttpClient に渡すようにして、画像データは StreamContent で埋め込みます

さっそくおためし実行

f:id:matatabi_ux:20150712214132g:plain

ID が戻ってきました

facebook を開いてみると

f:id:matatabi_ux:20150712214214p:plain

アップされてますね!