はじめに
【Unity】SocialWorkerでLINEにテキスト投稿ができない問題の対応【SocialWorker】 の記事でも紹介してますが、SocialWorker はUnityからSNSに手軽にシェアを行うことができる素晴らしいアセットです。
ただ、UniRx 使いとしてコールバックを受け取るようなメソッドは使いたくなかったのでRxの世界で使いやすいようにIObservable<Unit>
を返すラッパークラスを書いてみました。
ソースコード
LINEへの投稿については 【Unity】SocialWorkerでLINEにテキスト投稿ができない問題の対応【SocialWorker】 の記事で解説している問題への対応を含めています。
2017/7/6 追記
実装が色々まずかったので修正しました。
- 各メソッド名の最後に"Async"をつけた
-
Subscribe()
されないと実行されないようにした - マルチスレッド対応(できてるか不安...)
- 専用のエラークラス実装
ObservableSocialWorker.cs
using SWorker;
using UniRx;
namespace Jagapippi.Social
{
public static class ObservableSocialWorker
{
public static IObservable<Unit> PostTwitterAsync(string message, string url, string imagePath)
{
return Observable.Create<Unit>(observer =>
{
var gate = new object();
var isDisposed = false;
SocialWorker.PostTwitter(message, url, imagePath, result =>
{
lock (gate)
{
if (isDisposed) return;
if (result == SocialWorkerResult.Success)
{
observer.OnNext(Unit.Default);
observer.OnCompleted();
}
else
{
observer.OnError(new SocialWorkerException(result));
}
}
});
return Disposable.Create(() =>
{
lock (gate)
{
isDisposed = true;
}
});
});
}
public static IObservable<Unit> PostFacebookAsync(string imagePath)
{
return Observable.Create<Unit>(observer =>
{
var gate = new object();
var isDisposed = false;
SocialWorker.PostFacebook(imagePath, result =>
{
lock (gate)
{
if (isDisposed) return;
if (result == SocialWorkerResult.Success)
{
observer.OnNext(Unit.Default);
observer.OnCompleted();
}
else
{
observer.OnError(new SocialWorkerException(result));
}
}
});
return Disposable.Create(() =>
{
lock (gate)
{
isDisposed = true;
}
});
});
}
public static IObservable<Unit> PostLineAsync(string message, string imagePath)
{
return Observable.Create<Unit>(observer =>
{
var gate = new object();
var isDisposed = false;
SocialWorker.PostLine(System.Uri.EscapeUriString(message), imagePath, result =>
{
lock (gate)
{
if (isDisposed) return;
if (result == SocialWorkerResult.Success)
{
observer.OnNext(Unit.Default);
observer.OnCompleted();
}
else
{
observer.OnError(new SocialWorkerException(result));
}
}
});
return Disposable.Create(() =>
{
lock (gate)
{
isDisposed = true;
}
});
});
}
public static IObservable<Unit> PostInstagramAsync(string imagePath)
{
return Observable.Create<Unit>(observer =>
{
var gate = new object();
var isDisposed = false;
SocialWorker.PostInstagram(imagePath, result =>
{
lock (gate)
{
if (isDisposed) return;
if (result == SocialWorkerResult.Success)
{
observer.OnNext(Unit.Default);
observer.OnCompleted();
}
else
{
observer.OnError(new SocialWorkerException(result));
}
}
});
return Disposable.Create(() =>
{
lock (gate)
{
isDisposed = true;
}
});
});
}
public static IObservable<Unit> PostMailAsync(
string[] to,
string[] cc,
string[] bcc,
string subject,
string message,
string imagePath)
{
return Observable.Create<Unit>(observer =>
{
var gate = new object();
var isDisposed = false;
SocialWorker.PostMail(to, cc, bcc, subject, message, imagePath, result =>
{
lock (gate)
{
if (isDisposed) return;
if (result == SocialWorkerResult.Success)
{
observer.OnNext(Unit.Default);
observer.OnCompleted();
}
else
{
observer.OnError(new SocialWorkerException(result));
}
}
});
return Disposable.Create(() =>
{
lock (gate)
{
isDisposed = true;
}
});
});
}
public static IObservable<Unit> CreateChooserAsync(string message, string imagePath)
{
return Observable.Create<Unit>(observer =>
{
var gate = new object();
var isDisposed = false;
SocialWorker.CreateChooser(message, imagePath, result =>
{
lock (gate)
{
if (isDisposed) return;
if (result == SocialWorkerResult.Success)
{
observer.OnNext(Unit.Default);
observer.OnCompleted();
}
else
{
observer.OnError(new SocialWorkerException(result));
}
}
});
return Disposable.Create(() =>
{
lock (gate)
{
isDisposed = true;
}
});
});
}
}
public class SocialWorkerException : System.Exception
{
private readonly SocialWorkerResult _result;
public SocialWorkerResult error
{
get { return _result; }
}
public SocialWorkerException(SocialWorkerResult result)
{
_result = result;
}
}
}
雑感
だいぶRx使いこなせるようになったけど
- メソッド名に"Async"とか"AsObservable"とつけるべきか
単発でOnCompletedも一緒にでる奴はAsync、ストリーム長が複数~無限な奴はAsObservableにするといいです
— とりすーぷ (@toRisouP) 2017年7月6日
@toRisouP さんに教えていただきました!ありがとうございます!
↑ 2017/7/6 追記
- こういうラッパーは
Subscribe()
されない限り処理を行わないべきか- ↑のコードはメソッド呼び出し時に
SocialWorker
のメソッドを呼ぶようになってる - ↑他のストリームと組み合わせたときに待たないと困る(2017/7/6 追記)
- ↑のコードはメソッド呼び出し時に
がよくわかりません。主に慣習的な部分?
「一般的にはこうです」というのを知ってる方がいたら是非教えてください。