第11回 アプリに広告を出す(前編:基礎知識編):連載:Windowsストア・アプリ開発入門(2/5 ページ)
Windowsストアアプリの機能が完成したら、実際にストアで公開する前に、アプリをお金に換えるための機能を実装しよう。今回はマネタイズの仕組みを解説する。
アプリの対応
冒頭で「アプリ側では何もしなくてもよい」と書いたが、有限の試用期間を設定する場合には、アプリを購入するためのUIを出すようにした方がよいだろう。前述したように、試用期間が終わってしまうとアプリは起動しなくなり、エンドユーザーはWindowsストアでもう一度そのアプリを探して購入するという手間を掛けねばならない。その手間が面倒で購入してもらえないこともあるだろう。それを避けるために、試用期間の残りが短くなってきたら、アプリを購入するためのUIをアプリで表示するとよい。また、無期限の試用期間*5を設定しておいて、そのアプリを購入したかどうかでアプリの機能を変化させたい場合にも、アプリ側での実装が必要だ。
*5 無期限の試用期間を設定しても、Windowsストアには有償のアプリとして掲載されてしまう。ストア上では無料の試用期間があるのは分かるのだが、それが無期限だとは表示されない(2014年2月現在)。そのため、「試用期間は無制限です」といった内容をアプリの説明に記述しておく必要があるし、その説明を読む前にエンドユーザーが有償アプリだと思い込んで諦めてしまう可能性もある。購入したかどうかでアプリの機能を変化させたい場合には、無料のアプリとして、後で説明するアプリ内販売を実装した方がよいだろう。なお、有限の試用期間を設定した場合は、Windowsストアでは価格の下に試用期間が表示される。
そのような処理を実装するには、Windows.ApplicationModel.Store名前空間のCurrentAppクラスとCurrentAppSimulatorクラスを使って、次のようなコードを記述する。ここでは、試用期間の残りが7日未満になったら、アプリの起動直後に購入のUIを出すようにしてみた。また、購入済みの場合にアプリの動作を変えるための判定も行っている。
protected override async void OnLaunched(LaunchActivatedEventArgs e)
{
// ……省略……
var licenseInfo = LicenseInformation;
bool アプリは試用期間中 = licenseInfo.IsTrial && licenseInfo.IsActive;
double アプリの試用期間の残り日数 = licenseInfo.ExpirationDate
.Subtract(DateTimeOffset.Now)
.TotalDays;
if (アプリは試用期間中 && アプリの試用期間の残り日数 < 7.0)
{
// 試用期間の残りが7日未満になったら、起動時に購入のUIを出す
await RequestAppPurchaseAsync();
// エンドユーザーが購入してくれたら、この時点で
// licenseInfo.IsTrial == false
// に変わっている
}
bool アプリは購入済み = !licenseInfo.IsTrial && licenseInfo.IsActive;
if (アプリは購入済み)
{
// 購入済みの場合に機能を有効にするための処理(フラグを立てるなど)
}
}
private Windows.ApplicationModel.Store.LicenseInformation LicenseInformation
{
get
{
#if DEBUG
// デバッグビルド時はテスト用に用意されているCurrentAppSimulatorクラスを使う
return Windows.ApplicationModel.Store.CurrentAppSimulator.LicenseInformation;
#else
// リリースビルド時は本番用のCurrentAppクラスを使う
return Windows.ApplicationModel.Store.CurrentApp.LicenseInformation;
#endif
}
}
private async System.Threading.Tasks.Task<string> RequestAppPurchaseAsync()
{
#if DEBUG
try
{
return await Windows.ApplicationModel.Store.CurrentAppSimulator.RequestAppPurchaseAsync(true);
}
catch
{
// 購入シミュレートUIでエラーを発生させた
return string.Empty;
}
#else
try
{
return await Windows.ApplicationModel.Store.CurrentApp.RequestAppPurchaseAsync(false);
}
catch
{
// 通信エラーや、Windowsストア側のエラーなどが発生した
return string.Empty;
}
#endif
}
ここでは「App.xaml.cs」ファイルのOnLaunchedメソッドの末尾に記述して、アプリの起動直後に購入のUIが表示されるようにした。実際には、いろいろな表示タイミングが考えられるだろう。
なお、購入済みの場合に機能を変えるタイミングが、このコードではアプリの起動時だけだ。LicenseInformationクラス(Windows.ApplicationModel.Store名前空間)のLicenseChangedイベントを使えば、Windowsストアでエンドユーザーが購入したときでも、アプリの実行中に機能を変更できる。エンドユーザーがアプリを実行中にWindowsストアに切り替えて購入したようなときでも、(若干のタイムラグはあるだろうが)アプリの機能を変えられるのだ。
上のコードは、デバッグビルド時にはCurrentAppSimulatorクラスを使い、そうでないとき(=リリースビルド時)にはCurrentAppクラスを使うようになっている。リリースビルド時に使っているCurrentAppクラスが「本物」であり、実際にWindowsストアと交信する。デバッグビルド時に使っているCurrentAppSimulatorクラスはテスト用のもので、Windowsストアとは交信せず、代わりにローカルに置かれたテスト用のXMLファイルに基づいて応答を返す。
そのテスト用のXMLファイルは「WindowsStoreProxy.xml」という名前で、次のフォルダーに作成される。
C:\Users\{ユーザー名}\AppData\Local\Packages\{パッケージ名}\LocalState\Microsoft\Windows Store\ApiData
ここで、「{パッケージ名}」は、「Package.appxmanifest」ファイルに記載された「パッケージ名」だ。また、このファイルが作成されるタイミングは、上のコードではCurrentAppSimulatorクラスのLicenseInformationプロパティを初めて読み出したときだ。なお、このファイルは一度作成された後は自動的に書き換えられることはない。開発者が必要に応じて書き換えてテストを行う。
「WindowsStoreProxy.xml」ファイルは既定では試用期間中だが無期限という設定になっている。そのため上のコードを実行しても、購入のUIは表示されない。次のようにファイルに試用期限を追記してから実行すると、購入のUIをシミュレートするダイアログが表示される。
<?xml version="1.0" encoding="utf-16" ?>
<CurrentApp>
<ListingInformation>
<App>
<AppId>00000000-0000-0000-0000-000000000000</AppId>
<LinkUri></LinkUri>
<CurrentMarket>en-US</CurrentMarket>
<AgeRating>3</AgeRating>
<MarketData xml:lang="en-us">
<Name>AppName</Name>
<Description>AppDescription</Description>
<Price>1.00</Price>
<CurrencySymbol>$</CurrencySymbol>
<CurrencyCode>USD</CurrencyCode>
</MarketData>
</App>
<Product ProductId="1" LicenseDuration="0" ProductType="Durable">
<MarketData xml:lang="en-us">
<Name>Product1Name</Name>
<Price>1.00</Price>
<CurrencySymbol>$</CurrencySymbol>
<CurrencyCode>USD</CurrencyCode>
</MarketData>
</Product>
<Product ProductId="2" LicenseDuration="0" ProductType="Consumable">
<MarketData xml:lang="en-us">
<Name>Product2Name</Name>
<Price>1.00</Price>
<CurrencySymbol>$</CurrencySymbol>
<CurrencyCode>USD</CurrencyCode>
</MarketData>
</Product>
</ListingInformation>
<LicenseInformation>
<App>
<IsActive>true</IsActive>
<IsTrial>true</IsTrial>
<!-- 試用期間の終了日時を追加 -->
<ExpirationDate>2014-02-14T00:00:00.00Z</ExpirationDate>
</App>
<Product ProductId="1">
<IsActive>true</IsActive>
</Product>
</LicenseInformation>
<ConsumableInformation>
<Product ProductId="2" TransactionId="00000000-0000-0000-0000-000000000000" Status="Active" />
</ConsumableInformation>
</CurrentApp>
自動生成された「WindowsStoreProxy.xml」ファイルに、太字の部分を追加した。
この例では試用期限を2月14日としているが、テストに適した日付を設定してほしい(このサンプルでは、試用期間の残りが7日未満になると購入用のUIを出すことを思い出そう)。
なお、購入済みの状態でテストするには、その直上の<IsTrial>要素をtrueからfalseに手動で書き換える。購入UIをシミュレートするダイアログを操作しても、ファイルには反映されないので注意してほしい。
この「WindowsStoreProxy.xml」ファイルの記述方法について、詳しくはMSDNの「CurrentAppSimulator Class」を参照してほしい。
参考までに、以上のコードを実行したときの画像を次に掲載しておく。
CurrentAppSimulatorクラスを使った時の購入UI(テスト用)
ダイアログに表示されている「AppName」は、「WindowsStoreProxy.xml」ファイルの<App>‐<MarketData>‐<Name>タグに設定してあるもの。 このダイアログで[返すエラーコード]を[S_OK]のままにして[続行]ボタンをタップすると、購入したことになる。[キャンセル]ボタンをタップすると、購入しなかったことになる。
CurrentAppクラスを使った時の購入UI(本番)
本番のアプリでは、Windowsストアと交信して、アプリの購入情報が取得される(上の画像)。 取得した情報に基づき「購入を確認してください」というダイアログに変わる(中)。 そこで[購入]ボタンをタップすると、Windowsストアにログインするためのアカウントを確認するダイアログになる(下)。いちいち面倒なだけとも思えるが、こうなっているおかげで、普段はWindowsをローカルアカウントで利用していてもストアから購入できるのだ。 そこでアカウントのパスワードを入力して[OK]ボタンをタップすれば、購入完了だ。ただし、Windowsストアにクレジットカードをまだ登録していない場合は、引き続いてカードの登録手続きになる。 なお、中と下の画像は、他のアプリのものである(中の画像の[説明]のところにはアプリ名が表示されている)。本アプリはまだWindowsストアに登録していないので、上の画像の直後にエラーを表示するダイアログに変わってしまう。
試用期間を利用した実装については、MSDNの「アプリの試用版の作成」も参照してもらいたい。
Copyright© Digital Advantage Corp. All Rights Reserved.