StoreKit:应用内购买全解析
1. StoreKit 简介
StoreKit 是一项集成于软件中的应用内购买功能,它是 3.0 SDK 的新特性。借助 StoreKit,终端用户在从 App Store 购买并安装应用程序后,能够使用他们的 iTunes 凭证在应用内购买功能、订阅服务或消耗性资产。
使用 StoreKit 的好处众多,当应用需要比“一次性购买,永久使用”更复杂的购买模式时,它能为开发者提供在应用内销售额外产品的途径,通过 iTunes 支付创造额外的收入流。例如支持订阅模式、按需提供额外游戏关卡或引入其他可解锁功能。不过,目前不能使用应用内购买来销售“实物”资产(如 T 恤)、中间货币(如网站的商店积分),也禁止进行真实的赌博活动,所有通过应用内购买销售的商品必须能够以数字形式交付到应用中。
2. StoreKit 开发流程
StoreKit 的开发存在一个矛盾点:在将应用提交到 iTunes 之前,无法全面开发和测试应用内购买功能;而在开发未完成时,又不能完整地将应用提交到 iTunes。为解决这个问题,可按以下流程操作:
graph LR
A[开发应用骨架] --> B[上传骨架到 iTunes Connect]
B --> C[在 iTunes Connect 创建应用内产品]
C --> D[提交购买 GUI 截图]
D --> E[开发者批准]
E --> F[上传最终版应用到 iTunes Connect]
A --> G[继续开发应用]
G --> H[测试应用购买]
具体步骤如下:
1.
上传应用骨架
:将一个基本可用但尚未完全功能化的应用骨架上传到 iTunes Connect,同时要清楚后续会拒绝该二进制文件并替换它。上传骨架的原因是,开发 StoreKit 应用和产品需要一个处于审核中的应用,没有“活跃”的应用,就无法在 iTunes Connect 创建新的应用内购买项目,也不能使用 StoreKit 的沙盒版本测试这些购买。
-
注意事项
:提交骨架应用进行测试时,在 iTunes Connect 定价标签中回滚可用日期,防止未准备好的应用在 App Store 上意外出售,准备上线时再重置该日期。自 2009 年 10 月起,StoreKit 应用可以免费,不再局限于付费应用。
2.
全面开发和测试
:提交应用并创建至少一个应用内购买项目后,可使用 StoreKit 的沙盒版本和测试用户账户来购买新物品,而无需使用真实信用卡付费。沙盒 StoreKit 能让你在付款前后测试应用功能。
3.
提交最终版本
:开发完成后,要完成 StoreKit 在 iTunes Connect 的开发流程,包括上传显示应用购买 GUI 的截图、明确批准每个应用内购买项目、拒绝骨架应用并上传完整可用的应用版本。
3. 创建测试账户
测试账户在 StoreKit 开发中起着关键作用,在开发支持 StoreKit 的新应用前,需创建一个或多个新用户账户,用于在不使用真实资金的情况下测试应用付款。创建新用户的步骤如下:
1. 登录 iTunes Connect,选择“管理用户”>“应用内购买测试用户”。
2. 点击“添加新用户”,填写表单时需注意以下几点:
-
电子邮件地址
:必须唯一,但不要求是真实的,只要不与系统中的其他地址冲突即可。
-
姓名和生日
:无需是真实的,可采用简单的命名系统,如“a Sadun”“b Sadun”等,生日都设为 1 月 1 日。
-
密码
:至少六位字符,若需多次输入,建议使用小写字母,避免处理 iPhone 上的大写锁定键或切换键盘样式,所有测试账户可使用同一个易记的临时密码。
-
秘密问题/答案
:虽在这种情况下无实际意义,但不能为空,且两个字段不能输入相同字符串,每个字段至少六位字符,可使用如“aaaaaa”和“bbbbbb”这样的组合简化账户创建。
-
选择 iTunes 商店
:这会设置测试区域,若计划为不同商店提供多语言支持,需在每个受影响的区域创建测试账户。
-
账户管理
:可随时删除和添加用户账户,若没有未购买物品的用户,可按需创建新用户。
-
登录方式
:不要在“设置”应用中登录“账户”,否则 iPhone 会强制你同意标准用户协议并尝试获取有效信用卡信息,可使用“设置”应用注销账户,但避免用其登录。
4. 创建新的应用内购买项目
每个应用内购买项目都必须在 iTunes Connect 注册,创建新购买项目的步骤如下:
1. 登录 iTunes Connect,导航到“管理你的应用内购买”,点击“创建新项”,从列表中选择应用(列表包含已在 App Store 或正在审核的所有应用),点击应用图标进行选择。
2.
填写定价部分
:
-
参考名称
:任意填写,用于 iTunes Connect 的搜索结果和应用在 App Store 的“热门应用内购买”部分,应输入有意义的名称,如“解锁第 3 级购买”。
-
产品标识符
:是一个唯一标识符,类似于应用的标识符,通常可在应用 ID 后附加购买名称,如 com.sadun.scanner.optionalDisclosure。该标识符用于查询商店并获取购买详情,规则与应用 ID 相同,一旦注册,不可重复使用或“移除”。
-
购买类型
:有以下三种类型可供选择,选择并保存后不可更改,若选错需使用新的产品 ID 创建新项目。
| 购买类型 | 说明 | 示例 |
| ---- | ---- | ---- |
| 非消耗性 | 用户只需购买一次,之后可免费多次重新下载,适用于用户可解锁的功能,如额外游戏关卡 | 解锁游戏新关卡 |
| 订阅 | 用户在应用生命周期内可多次购买,可检查账户是否已购买,但再次下载需付费,用于提供对受控数据的付费访问,如付费报纸文章和医疗数据库搜索 | 订阅新闻资讯 |
| 消耗性 | 每次下载都需付费,可多次购买,如额外生命值或主服务器上的额外 CPU 时间,可在无关联时间段内“消耗” | 游戏中的道具 |
-
销售许可
:勾选“销售许可”复选框,确保开发和分发的应用都能以编程方式访问该购买项目。
3.
添加项目详情
:
- 每个可购买项目需向应用描述自身信息,包括在定价部分设置的价格、显示名称(所购买产品的名称)和描述(向用户解释购买内容和用途),后两者需针对特定语言进行本地化。目前支持的语言有英语(包括澳大利亚英语、加拿大英语、英国英语)、荷兰语、法语(包括加拿大法语)、德语、意大利语、日语、西班牙语(包括墨西哥西班牙语)和简体中文。
-
注意事项
:至少定义一种语言的数据,对于面向美国商店的开发者,单个英语条目通常就足够;若应用在全球销售,应与应用描述和应用内功能的现有本地化保持一致;输入数据时,要考虑应用是这些信息的消费者,文本会用于创建应用向用户展示的购买 GUI,用户的语言设置会选择本地化内容;描述应清晰传达购买行为和用户可获得的内容。
4.
提交购买 GUI 截图
:在完成应用开发和调试后,在项目表单底部的“审核”部分上传截图,截图必须展示应用内购买的实际情况,突出自定义的 GUI。有效图片尺寸为 320x480、480x320、320x460 或 480x300 像素(后两种尺寸是去除 20 像素状态栏的截图)。
5.
开发者批准
:完成沙盒测试且确信应用和应用内购买功能准备好接受苹果审核后,需亲自批准应用。前往 iTunes Connect > 管理应用内购买,选择任何购买项目,点击绿色“批准”按钮,然后选择提交方式:
-
随二进制文件提交
:适用于刚刚添加应用内购买功能的应用,将购买项目与下一次二进制文件上传一起提交。
-
立即提交
:用于已通过审核的 3.x 或更高版本应用,可向现有测试过的产品添加新的购买项目。
6.
提交应用
:批准应用后,它将进入审核队列。若选择“随二进制文件提交”,需提交新的二进制文件副本,否则购买项目和应用将不会一起审核。提交新二进制文件时,拒绝当前版本,之后无法再使用沙盒购买服务器测试应用,需有处于审核或已接受状态的应用才能使用这些服务。重新上传二进制文件后,iTunes Connect 会提示提交应用内购买项目,勾选要使用的应用内项目并保存更改,购买项目和应用将一起审核,解决“先有鸡还是先有蛋”的矛盾。
5. 构建 GUI
Apple 的 StoreKit 框架未提供用于请求用户购买的内置 GUI,需要开发者自行创建。可通过创建 SKProductsRequest 实例从 App Store 检索本地化价格和描述,具体代码如下:
// Create the product request and start it
SKProductsRequest *preq = [[SKProductsRequest alloc]
initWithProductIdentifiers:[NSSet setWithObject:PRODUCT_ID]];
preq.delegate = self;
[preq start];
使用产品请求时,委托必须声明并实现 SKProductsRequestDelegate 协议,该协议包含三个简单的回调方法,示例代码如下:
- (void)request:(SKRequest *)request
didFailWithError:(NSError *)error
{
[self doLog:
@"Error: Could not contact App Store properly, %@",
[error localizedDescription]];
}
- (void)requestDidFinish:(SKRequest *)request
{
// Release the request
[request release];
[self doLog:@"Request finished."];
}
- (void)productsRequest:(SKProductsRequest *)request
didReceiveResponse:(SKProductsResponse *)response
{
// Find a product
SKProduct *product = [[response products] lastObject];
if (!product)
{
[self doLog:@"Error Could not find matching products"];
return;
}
当收到响应时,代码会查找产品并检索其本地化价格和描述,然后使用描述作为警报文本和两个按钮(价格和“不,谢谢”)构建一个简单的警报,该警报可作为基本的购买 GUI。同时要注意,StoreKit 在未连接网络的情况下无法工作。
StoreKit:应用内购买全解析
6. 购买请求与处理
在构建好 GUI 并获取到产品信息后,就可以向用户发起购买请求并处理后续流程。以下是详细步骤:
6.1 发起购买请求
当用户点击购买按钮时,需要创建一个
SKPayment
对象,并将其添加到
SKPaymentQueue
中,示例代码如下:
SKProduct *product = ...; // 从之前的请求中获取到的产品对象
SKPayment *payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
在上述代码中,首先创建了一个
SKPayment
对象,该对象代表了用户的购买请求。然后通过
[SKPaymentQueue defaultQueue]
获取默认的支付队列,并将支付请求添加到队列中。
6.2 处理购买结果
为了处理购买结果,需要实现
SKPaymentTransactionObserver
协议。该协议包含了多个回调方法,用于处理不同的交易状态,示例代码如下:
@interface MyViewController () <SKPaymentTransactionObserver>
@end
@implementation MyViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions {
for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
break;
case SKPaymentTransactionStatePurchasing:
// 购买正在进行中
break;
default:
break;
}
}
}
- (void)completeTransaction:(SKPaymentTransaction *)transaction {
// 处理购买成功的逻辑,例如解锁功能、提供内容等
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
- (void)failedTransaction:(SKPaymentTransaction *)transaction {
if (transaction.error.code != SKErrorPaymentCancelled) {
// 处理购买失败的逻辑,例如显示错误信息
}
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
// 处理恢复购买的逻辑,例如重新解锁之前购买的功能
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
- (void)dealloc {
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}
@end
在上述代码中,首先在
viewDidLoad
方法中添加了当前视图控制器作为交易观察者。然后在
paymentQueue:updatedTransactions:
方法中,根据不同的交易状态调用相应的处理方法。在每个处理方法中,完成相应的业务逻辑后,需要调用
[[SKPaymentQueue defaultQueue] finishTransaction:transaction]
来标记交易已完成。
7. 恢复购买功能
为了提供更好的用户体验,通常需要实现恢复购买功能,让用户可以重新获取之前购买过的非消耗性产品或订阅。以下是实现恢复购买功能的步骤:
7.1 发起恢复请求
当用户点击恢复购买按钮时,调用
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions]
方法发起恢复请求,示例代码如下:
- (IBAction)restorePurchases:(id)sender {
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
7.2 处理恢复结果
同样,在
SKPaymentTransactionObserver
的回调方法中处理恢复购买的结果,示例代码如下:
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue {
// 处理恢复购买成功的逻辑,例如重新解锁之前购买的功能
}
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error {
// 处理恢复购买失败的逻辑,例如显示错误信息
}
在上述代码中,
paymentQueueRestoreCompletedTransactionsFinished:
方法在恢复购买成功时被调用,
paymentQueue:restoreCompletedTransactionsFailedWithError:
方法在恢复购买失败时被调用。
8. 常见问题与解决方案
在使用 StoreKit 进行应用内购买开发时,可能会遇到一些常见问题,以下是一些常见问题及解决方案:
| 问题 | 解决方案 |
|---|---|
| 无法连接到 App Store | 检查网络连接是否正常,确保设备可以访问 App Store;检查应用是否已正确配置,包括应用 ID、产品 ID 等。 |
| 购买失败 |
检查错误代码,根据不同的错误代码进行相应的处理,例如
SKErrorPaymentCancelled
表示用户取消了购买,
SKErrorPaymentNotAllowed
表示设备不允许进行购买等。
|
| 恢复购买失败 | 检查错误代码,确保用户之前确实有购买记录;检查应用是否正确处理了恢复购买的逻辑。 |
| 产品信息获取失败 | 检查产品 ID 是否正确,确保产品已在 iTunes Connect 中正确注册;检查网络连接是否正常。 |
9. 总结
通过本文的介绍,我们详细了解了 StoreKit 应用内购买的开发流程,包括创建测试账户、创建应用内购买项目、构建 GUI、发起购买请求、处理购买结果、恢复购买功能以及常见问题的解决方案。在开发过程中,需要严格按照苹果的规定进行操作,确保应用的安全性和稳定性。同时,要注重用户体验,提供清晰的购买流程和恢复购买功能,让用户能够方便地进行应用内购买。
希望本文能够帮助开发者更好地掌握 StoreKit 应用内购买的开发技巧,为应用带来更多的收入和用户满意度。
StoreKit应用内购买详解
超级会员免费看
1220

被折叠的 条评论
为什么被折叠?



