美文网首页
App内购买 - 代码集成篇

App内购买 - 代码集成篇

作者: 代号工程师 | 来源:发表于2018-09-24 18:47 被阅读0次

在上一篇文章中,我对“App内购买”进行了一些介绍,如果你已经看过,那么相信你已经对它有了一定的了解,接下来要怎么把这一技术手段用(mai)在(le)实(huan)际(qian)中呢?

如果你是一名iOS开发工程狮,你将会在这篇文章中得到对于这个问题的解答,如果你不是,那么你也可以来围观下我们的开发日常~

本文的结构

一、要使用什么API

你要使用到的API主要会有两个:StoreKit、NSURLSession

  • StoreKit

    这款“商店工具包”里,已经包括了“App内购买”各个阶段中你需要的“扳手”、“钳子”,通过使用它们,你就可以在你的App里打造出一个小商店,出售你的产品。

  • NSURLSession

    如果你的产品是交给Apple在App Store中进行托管的,那么你就需要在App内把用户购买的产品相关的信息下载下来,在下载这些信息时,你需要使用NSURLSession,并在后台完成下载。

    不要使用NSURLConnect,因为苹果对它进行了限制。

二、购买过程的各个阶段

你可以先通过下面这张图对购买过程有一个初步了解:


购买过程的各个阶段
  1. 检索产品信息
    在上一篇文章中,我已经讲过如何创建一个App内购买项目,当你已经创建好项目,你就可以使用产品标识符从App Store检索产品信息,这些信息包括产品价格、产品名称等。
    关于产品标识符:
    a.产品标识符是创建App内购买项目时,由你来设置的。
    b.要注意这个产品标识符必须是唯一的,而且只能是大写英文字母(A-Z)、小写英文字母(a-z)、下划线( _ )或点号( . )的组合。
    c.Apple建议我们使用反域名的方式进行命名,比如“com.companyname.application.productid”。
    d.没错,产品标识符看起来跟App ID和Bundle ID非常像,不过它们不是一回事,记住不要弄混了。
    在对产品标识符进行管理时,苹果没有提供任何方式支持你从App Store直接获取产品标识符,你需要自己记下所有的产品标识符,然后提供给你的App来使用,有两种策略可选:
    a. 将产品标识符列表放在App的bundle中
    当你的产品标识符是固定不变的,你可以使用这种策略,然后从本地读取产品标识符列表。
    b.将产品标识符列表放在服务器端
    当你的产品标识符在App不更新的情况下也是会变化的,你可以使用这种策略,然后从服务器端读取产品标识符列表。
    在从服务器端获取产品标识符列表时,要注意制定缓存策略和保证可靠性。

当你已经在App内获取到产品标识符后,你就可以通过他们来向App Store请求产品对象,以及这些产品的可用性。这个时候就轮到我们在文章开头提到的大宝贝StoreKit出场了:实例化StoreKit中的 SKProductsRequest 类,用你的产品标识符列表对它进行实例化,然后发起请求:

// Custom method
- (void)validateProductIdentifiers:(NSArray *)productIdentifiers
{
    SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithArray:productIdentifiers]];

    // Keep a strong reference to the request.
    self.request = productsRequest;
    productsRequest.delegate = self;
    [productsRequest start];
}

App Store收到你的请求并处理完成后,SKProductsRequestDelegate 中的代理方法将会被回调,回调的结果中会包括:一个有效的产品标识符列表和一个无效的产品标识符列表。你可以在这个方法里处理你的产标识符列表,比如把无效的产品标识符删除掉。

// SKProductsRequestDelegate protocol method
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    self.products = response.products;
    
    for (NSString *invalidIdentifier in response.invalidProductIdentifiers) {
        // Handle any invalid product identifiers.
    }

    [self displayStoreUI]; // Custom method
}

现在你可以向用户展示你的销售界面了,在展示产品价格时,可以使用NSNumberFormatter来格式化成本地价格:

NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[numberFormatter setLocale:product.priceLocale];
NSString *formattedPrice = [numberFormatter stringFromNumber:product.price];
  1. 请求付款

在用户选择了一个产品进行购买后,你就可以创建一个支付请求了,创建时要填入在上一步检索产品信息时获取到的相应的产品对象,如果需要的话,再填入产品购买数量。

SKProduct *product = <# Product returned by a products request #>;
SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
payment.quantity = 2;

然后将支付请求加入到支付队列中:

[[SKPaymentQueue defaultQueue] addPayment:payment];
  1. 交付产品

在提交了支付请求后,需要等待App Store对交易进行处理,这里需要首先注册对于App Store处理过程的监听:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    /* ... */

    [[SKPaymentQueue defaultQueue] addTransactionObserver:observer];
}

然后就是实现 SKPaymentTransactionObserver 中的回调方法:

- (void)paymentQueue:(SKPaymentQueue *)queue
 updatedTransactions:(NSArray *)transactions
{
    for (SKPaymentTransaction *transaction in transactions) {
        switch (transaction.transactionState) {
            // Call the appropriate custom method for the transaction state.
            case SKPaymentTransactionStatePurchasing:
                [self showTransactionAsInProgress:transaction deferred:NO];
                break;
            case SKPaymentTransactionStateDeferred:
                [self showTransactionAsInProgress:transaction deferred:YES];
                break;
            case SKPaymentTransactionStateFailed:
                [self failedTransaction:transaction];
                break;
            case SKPaymentTransactionStatePurchased:
                [self completeTransaction:transaction];
                break;
            case SKPaymentTransactionStateRestored:
                [self restoreTransaction:transaction];
                break;
            default:
                // For debugging
                NSLog(@"Unexpected transaction state %@", @(transaction.transactionState));
                break;
        }
    }
}

下一步就是根据App Store给你的用户的支付收据,向用户交付产品。获取支付收据可以采用下面的方式:

NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];

在交易完成后,记得主动关闭当前交易:

SKPaymentTransaction *transaction = <# The current payment #>;
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];

参考:

In-App Purchase:https://developer.apple.com/in-app-purchase/

相关文章

  • App内购买 - 代码集成篇

    在上一篇文章中,我对“App内购买”进行了一些介绍,如果你已经看过,那么相信你已经对它有了一定的了解,接下来要怎么...

  • App内购买 - 测试与发布篇

    在上一篇文章里,我讲解了如何在代码中集成App内购买,如果你已经按照里面的方式做了集成,那么现在就万事俱备只欠发布...

  • 苹果内购

    内购前准备 APP内集成IAP代码之前需要先去开发账号的ITunes Connect进行以下三步操作: 1,后台填...

  • 2016年最新版iOS App内购买详细指南

    摘要: 本文讲述了如何创建App内购买项目? 如何添加沙盒App内购买测试帐号? 如何封装一个内购买的管理类? 如...

  • iOS内购全面实战

    内购是啥 App 内购买项目允许顾客通过访问 App Store 购买您 App 中的内容、功能或服务,并安全处理...

  • iOS内购看我就够了(含代码)

    内购是啥 App 内购买项目允许顾客通过访问 App Store 购买您 App 中的内容、功能或服务,并安全处理...

  • ios-内购(IAP)

    StoreKit 框架内购:在ios中专指苹果内购,在app内购买商品时使用苹果的支付方式进行购买;如果在app内...

  • iOS开发之内购-AppStore

    所谓内购就是在App内购买商品,如在游戏App中的购买道具、皮肤等;在电商App中的购买衣食住行的各种商品,如淘宝...

  • iOS 内购流程整理

    最近项目因为集成了支付宝,上架时被APP审核拒掉了,无奈只能接入内购。 参考文章: App内购通关:(一)非代码准...

  • App提交审核被拒 Guideline 3.1.1 - Busi

    注:3.1.1条例被拒绝,一般原因是由于App有内购买项目,代码勾选了“In-App Purchase”项,而审核...

网友评论

      本文标题:App内购买 - 代码集成篇

      本文链接:https://www.haomeiwen.com/subject/waocoftx.html