しっぽを追いかけて

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

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

Xamarin.Forms で複数の画像を添付して Twitter に投稿したい

とりあえず Twitter 投稿ができたので、今度は画像つきを試してみようと思います

意外にも画像つきで Twitter 投稿する Xamarin.Forms のコードで紹介されていないんですよね・・・

とはいっても CoreTweet のおかげでそんなに大変じゃないです

/// <summary>
/// つぶやきサービス
/// </summary>
public class TweetService
{
    ~ 中略 ~

    /// <summary>
    /// 複数画像を添付してつぶやく
    /// </summary>
    /// <param name="message">つぶやく内容</param>
    /// <param name="images">添付する画像の Stream コレクション</param>
    /// <param name="cancellation">中断トークン</param>
    /// <returns></returns>
    public async Task TweetAsync(string message, IList<Stream> images, CancellationToken cancellation)
    {
        var tokens = Tokens.Create(ApiKey, ApiSecret, AccessToken, AccessTokenSecret);
        var uploadResults = await Task.WhenAll((from image in images
                                                select tokens.Media.UploadAsync(media => image)).ToList());
            
        var result = await tokens.Statuses.UpdateAsync(
            new { status = message, media_ids = uploadResults.Select(upload => upload.MediaId) },
            cancellation);
    }

    /// <summary>
    /// 複数画像を添付してつぶやく
    /// </summary>
    /// <param name="message">つぶやく内容</param>
    /// <param name="images">添付する画像の Stream コレクション</param>
    /// <returns></returns>
    public Task TweetAsync(string message, IList<Stream> images)
    {
        return this.TweetAsync(message, images, new CancellationTokenSource().Token);
    }
}

画像データを Stream のコレクションで受け取ったら、それを CoreTweet の Media.UploadAsync でアップロードして、そのあとに以前やったように投稿するだけ

投稿するときにアップロード時の返却値の MediaId をコレクションで media_ids のパラメータにつけてあげるだけでオッケーみたいです

おためし実行・・・

f:id:matatabi_ux:20150628215721p:plain

ちゃんとできました!

画像をアップロードしてから1時間以内に投稿しないと無効になるらしいですが、とてもかんたんですね

var files = new List<Stream>();
var token = new CancellationTokenSource().Token;
foreach (var image in images)
{
    var stream = await ((StreamImageSource)ImageSource.FromResource(image)).Stream.Invoke(token);
    files.Add(stream);
}
await this.service.TweetAsync(this.message, files);

今回は埋め込みリソースの画像ファイルから Stream 化しましたが、下記の記事で紹介しているように Windows ランタイムアプリの場合上記のように記述できないので注意ください

matatabi-ux.hateblo.jp

・・・たぶん Windows ランタイムアプリの場合はプラットフォームごとにコードを分岐させる必要があると思います;