さてGoogle+に対してのOAuthアクセスは作成しましたが、
アクセストークン等のアプリケーションデータを保存しよーと思ったら、
WindowsPhone的なIsolatedStorageFileStreamがない事に気付きました。
そう言われるとデータベースとか、スマートフォン系の特殊なアクセスばっかりで
「設定ファイル」何かを作ってデータを永続化してないなぁと思ったので
設定ファイルを作ってみる事にした。
シリアライズ可能なオブジェクト
シリアライズ可能なクラスを作成します。
private static Settings _settings;
public static Settings Settings {
get { return _settings; }
}
私はAppにstaticなメンバを作成しておきました。
この中にアクセストークンのデータを残すようにしておきます。
※アクセストークン(string)、リフレッシュトークン(string)、有効期限(現在時刻から足し込んだDateTime)
データの保存
データの保存は以下の通りで行いました。
async static private Task<StorageFile> GetSettingFile()
{
var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
StorageFile file = await folder.CreateFileAsync("settings.xml",CreationCollisionOption.OpenIfExists);
return file;
}
async static public void SaveSetting()
{
var file = await GetSettingFile();
var serial = new XmlSerializer(typeof(Settings));
using ( var tWriter = new StringWriter() ) {
serial.Serialize(tWriter, _settings);
using (var stream = await file.OpenAsync(FileAccessMode.ReadWriteUnsafe))
{
var outputStream = stream.GetOutputStreamAt(0);
using (var writer = new DataWriter(outputStream))
{
writer.WriteString(tWriter.ToString());
await writer.StoreAsync();
}
}
}
}
「Windows.ApplicationModel.Package.Current.InstalledLocation」で
インストールしたディレクトリを取得する事ができます。
他にドキュメント内とかでも保存できるのですが、
他の場所に保存する場合は、パーミッション(Package.appxmanifest)が必要になるようです。
※また機会あったら書きます。
CreateFileAsync()を使用していますが、
同期的に取得するのでawaitで呼び出しています。
第2引数の「CreationCollisionOption.OpenIfExists」は存在しない場合作成してくれます。
※これを付けないとsettings(2).xmlとかをモリモリ作ります。
あとはSettingsオブジェクトをシリアライズして保存しています。
データの取得
async private void LoadSetting()
{
var file = await GetSettingFile();
using (var stream = await file.OpenAsync(FileAccessMode.Read))
{
var inputStream = stream.GetInputStreamAt(0);
using (var reader = new DataReader(inputStream))
{
uint size = (uint)stream.Size;
await reader.LoadAsync(size);っd
string data = reader.ReadString(size);
if (!data.Equals(""))
{
using (var textReader = new StringReader(data))
{
XmlSerializer serial = new XmlSerializer(typeof(Settings));
_settings = (Settings)serial.Deserialize(textReader);
}
}
else
{
_settings = new Settings();
}
}
}
}
後は同様に読み込むだけですね。
保存したデータ
<?xml version="1.0" encoding="utf-16"?>
<Settings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<AccessToken>
<accessToken>ya29.AHES6ZQ0-H7cotFnLdVAcZ5CVz280mBarXy4tUn7-_Bs-AE</accessToken>
<refreshToken>1/x8SHm9FaHD299fdZSNNyme2m3X2Up_Ki90pcUc2Y2Iw</refreshToken>
<expiresIn>2012-04-28T21:48:28.55985+09:00</expiresIn>
</AccessToken>
</Settings>
こんな感じで残ってました。
※AccessTokenクラスで保存しています。
開発中は、
「C:\Users\(ユーザ名)\Documents\Visual Studio 11\Projects\GooglePlus\GooglePlus\bin\Debug\AppX」
って位置にありました。
リリースすると
「C:\Users\(ユーザ名)\AppxLayouts\(アプリのID)」
のようです。
感想
保存方法がかなりWindowsPhoneと違いました。
現状開発中で気になっているのは
Suspendingのイベントに対して、保存処理を行ったんですけど、
開発中だからか、動作せずにStaticで他の画面から呼び出している状態になってしまいました。
何か間違ってるのかな?
await async知らなかったので呼び出した時のエラー原因がわからなかったです。
1 件のコメント:
GetSettingFile()を関数化してましたけど、
Setting.xmlが変更になった時とかに保存するとこのコードだと上書きがおかしいですね。
保存の時はCreationCollisionOption.ReplaceExisting
とかを指定した方が良いですね。
コメントを投稿