[iOS]アプリ内課金の金額をあらかじめ表示する

iOSアプリにアプリ内課金を組み込んだ時は、あらかじめ金額を表示しておくとユーザーに親切です。
最近の円安でまた金額改定があるかもしれないですし、表示する金額はApp Storeから取得するのが吉です。

# ユーザーのサインインは不要
金額(アプリの情報)を取得するだけならユーザーがApple IDでサインインしていなくても大丈夫です。
また、ここでは購入処理(addPayment)は行わないので、金額取得するだけならSKPaymentQueueのオブザーバー登録は不要です。

# コード
##以下の要領で取得できます。

```Objective-C:viewController.h
#import <UIKit/UIKit.h>
#import <StoreKit/StoreKit.h>

@interface InAppPurchasesViewController : UIViewController
<
// SKProductsRequestのプロトコロル
SKProductsRequestDelegate
> {
}
// インジケータ表示用の画面を覆うview(backgroundColorを黒とかにしておく)
@property (weak, nonatomic) IBOutlet UIView *indicatorView;
// インジケータ（indicatoerViewに乗せます)
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *indicator;
// 例えばボタンに金額を表示するなら
@property (weak, nonatomic) IBOutlet UIButton *buyButton;

@end
```

```Objective-C:viewController.m
- (void)viewWillAppear:(BOOL)animated
{
    // インジケータ表示
    [self indicator:YES];
    // 購入価格取得開始
    NSSet *set = [NSSet setWithObjects:@"プロダクトID", nil];
    self.skProductsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
    self.skProductsRequest.delegate = self;
    [self.skProductsRequest start];
}
```


```Objective-C:viewController.m
// リクエスト取得完了時のdelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    if (response == nil) {
        NSLog(@"no response");
        // インジケータを止める
        [self indicator:NO];
        return;
    }
    // 無効なアイテムがないかチェック
    if ([response.invalidProductIdentifiers count] > 0) {
        NSLog(@"PRODACTION_ID error. count:%d", [response.invalidProductIdentifiers count]);
        // インジケータを止める
        [self indicator:NO];
        return;
    }
    // 価格取得処理開始
    for (SKProduct *product in response.products) {
        // フォーマット
        NSNumberFormatter *numberFmt = [[NSNumberFormatter alloc] init];
        [numberFmt setFormatterBehavior:NSNumberFormatterBehavior10_4];
        [numberFmt setNumberStyle:NSNumberFormatterCurrencyStyle];
        // PriceLocalを設定(ユーザーの環境に合わせた金額を取得する)
        [numberFmt setLocale:product.priceLocale];
        NSString *str = [numberFmt stringFromNumber:product.price];
        NSString *fmtStr = [NSString stringWithFormat:@"「購入金額は %@ です", str];
        // 例えばボタンに表示
        [self.buyButton setTitle:fmtStr forState:UIControlStateNormal];
        // インジケータを止める
        [self indicator:NO];

        // 他の情報
        //NSLog(@"   id:%@",[product productIdentifier]);
        //NSLog(@"title:%@",product.localizedTitle);
        //NSLog(@" desc:%@",product.localizedDescription);
        //NSLog(@"price:%@",formattedString);
    }
}
```
##おまけ。インジケータ処理。
UIActivityIndicatorViewをviewに貼り付けてIBOutletで接続しておきます。
結構時間がかかることもあるのでインジケータは表示しましょう。

```Objective-C:viewController.m
// indicator
- (void)indicator:(BOOL)start
{
    if (start) {
        // indicator start
        // 全面を覆うviewを表示
        [self.indicatorView setAlpha:0.6];
        // インジケータを回す
        [self.indicator startAnimating];
        // ステータスバーのインジケータも表示
        [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
        // (必要なら)バックボタンを消す
        [self.navigationItem setHidesBackButton:YES animated:YES];
    } else {
        // indicator stop
        // 全面を覆うviewを非表示にする
        [self.indicatorView setAlpha:0.0];
        // インジケータを止める
        [self.indicator stopAnimating];
        // ステータスバーのインジケータも消す
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        // (必要なら)バックボタンを表示する
        [self.navigationItem setHidesBackButton:NO animated:YES];
    }
}
´´´