实现应用内购买功能:从零开始创建一个简单的商店
1. 引言
随着移动应用市场的迅速发展,应用内购买(In-App Purchase, IAP)已经成为开发者提高收入的重要途径之一。通过应用内购买,用户可以在应用中购买虚拟商品、服务甚至订阅。本文将详细介绍如何使用 Store Kit 框架为 iOS 应用添加应用内购买功能,包括设置沙盒测试环境、创建简单的商店界面以及实现购买逻辑。
2. 设置沙盒测试环境
在将应用内购买功能集成到应用之前,必须先在 iTunes Connect 中设置产品和测试环境,以模拟支付处理过程而不实际收费。这有助于开发者测试购买流程,确保一切正常运作。
2.1 注册 iTunes Connect
首先,登录 iTunes Connect ,并按照以下步骤创建测试用户和产品:
-
创建测试用户 :
- 导航到 iTunes Connect 的“用户与权限”部分。
- 选择“测试用户”选项卡,点击“添加新用户”按钮。
- 填写必要信息,确保使用不同于现有 iTunes 账户的邮箱地址(例如使用 Gmail 的别名功能)。
- 创建的测试用户仅用于沙盒环境,不会对真实账户产生影响。 -
添加应用内购买产品 :
- 从 iTunes Connect 主页选择“我的应用”,然后选择要添加应用内购买的应用。
- 点击“功能”选项卡下的“应用内购买”,再点击“创建新应用内购买”。
- 根据需要选择产品类型(消耗型、非消耗型或订阅型),并填写相关信息。
- 提交产品以供苹果审核,但无需上传二进制文件。
2.2 产品类型
| 产品类型 | 描述 |
|---|---|
| 可消耗品 | 用户每次需要时购买的产品,如游戏中的增强道具。 |
| 非消耗品 | 用户只购买一次并永久拥有的产品,如可下载的歌曲或图像。 |
| 订阅 | 用户根据需要频繁续订的产品,可以是消耗型或非消耗型。 |
3. 创建简单的商店界面
接下来,我们将创建一个简单的商店界面,允许用户浏览和购买 iPhone 背景。商店将使用基于导航的应用程序模板,并在 UITableView 中显示产品列表。
3.1 添加 Store Kit 框架
- 打开 Xcode,创建一个新的基于导航的项目,命名为
WPStore。 - 右键点击
Frameworks文件夹,选择“添加现有框架”,然后添加StoreKit.framework。
3.2 实现 RootViewController
在 RootViewController.h 中声明必要的属性和方法:
#import <StoreKit/StoreKit.h>
@interface RootViewController : UITableViewController <SKProductsRequestDelegate, SKPaymentTransactionObserver> {
NSMutableArray *products;
NSMutableArray *transactionHistory;
}
@property (nonatomic, retain) NSMutableArray *transactionHistory;
- (void)requestProductData;
- (void)completeTransaction:(SKPaymentTransaction *)transaction;
- (void)restoreTransaction:(SKPaymentTransaction *)transaction;
- (void)failedTransaction:(SKPaymentTransaction *)transaction;
- (void)recordTransaction:(SKPaymentTransaction *)transaction;
- (void)provideContent:(NSString *)productIdentifier;
@end
3.3 实现 RootViewController.m
在 RootViewController.m 中实现以下方法:
#import "RootViewController.h"
@implementation RootViewController
@synthesize transactionHistory;
- (void)viewDidLoad {
[super viewDidLoad];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
products = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"history.plist"];
self.transactionHistory = [NSMutableArray arrayWithContentsOfFile:path];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
SKProduct *product = [products objectAtIndex:indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:@"$%.2f %@", product.price.doubleValue, product.localizedTitle];
cell.detailTextLabel.text = product.localizedDescription;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
3.4 实现产品选择逻辑
当用户点击表格中的一行时,显示墙纸预览界面。为此,我们需要实现 UITableView 的 didSelectRowAtIndexPath 方法:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
SKProduct *product = [products objectAtIndex:indexPath.row];
WallpaperViewController *wpViewController = [[WallpaperViewController alloc] initWithNibName:@"WallpaperViewController" bundle:[NSBundle mainBundle]];
wpViewController.product = product;
[self.navigationController pushViewController:wpViewController animated:YES];
[wpViewController release];
}
4. 创建 WallPaperViewController
为了显示墙纸预览界面,我们需要创建一个新的 WallpaperViewController 类,并为其添加相应的视图和逻辑。
4.1 创建 WallPaperViewController.h
在 WallpaperViewController.h 中声明必要的属性和方法:
#import <UIKit/UIKit.h>
#import <StoreKit/StoreKit.h>
@interface WallpaperViewController : UIViewController {
IBOutlet UIImageView *imageView;
SKProduct *product;
}
@property (nonatomic, retain) IBOutlet UIImageView *imageView;
@property (nonatomic, retain) SKProduct *product;
- (IBAction)buttonClicked:(id)sender;
@end
4.2 实现 WallPaperViewController.m
在 WallpaperViewController.m 中实现以下方法:
#import "WallpaperViewController.h"
@implementation WallpaperViewController
@synthesize imageView, product;
- (void)viewDidLoad {
[super viewDidLoad];
// 设置墙纸图像
imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@.jpeg", product.productIdentifier]];
}
- (IBAction)buttonClicked:(id)sender {
// 实现购买逻辑
SKPayment *payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
@end
以上内容介绍了如何设置沙盒测试环境和创建简单的商店界面。接下来,我们将深入探讨如何实现购买逻辑、处理交易以及提供购买内容。通过这些步骤,您可以为您的应用添加完整且功能强大的应用内购买系统。
5. 实现购买逻辑
为了确保应用内购买流程的顺利进行,我们需要实现购买逻辑、处理交易以及提供购买内容。以下是具体的实现步骤。
5.1 请求产品数据
首先,我们需要请求产品数据,以便在商店界面上显示可用的产品。这可以通过实现 requestProductData 方法来完成:
- (void)requestProductData {
NSSet *productIdentifiers = [NSSet setWithObjects:@"com.rightsprite.wallpaper.01", @"com.rightsprite.wallpaper.02", @"com.rightsprite.wallpaper.03", nil];
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
request.delegate = self;
[request start];
}
5.2 处理产品请求响应
当产品请求完成时, SKProductsRequestDelegate 协议会调用 productsRequest:didReceiveResponse: 方法。我们需要在此方法中处理响应并更新产品列表:
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
products = [response.products mutableCopy];
[self.tableView reloadData];
}
5.3 处理购买交易
当用户点击购买按钮时,我们会调用 SKPaymentQueue 来发起购买请求。接下来,我们需要实现 SKPaymentTransactionObserver 协议中的方法来处理交易结果。
5.3.1 完成交易
当购买成功时,调用 completeTransaction 方法来记录交易并向用户提供内容:
- (void)completeTransaction:(SKPaymentTransaction *)transaction {
[self recordTransaction:transaction];
[self provideContent:transaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
5.3.2 恢复交易
当用户恢复之前购买的产品时,调用 restoreTransaction 方法来处理恢复逻辑:
- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
[self completeTransaction:transaction];
}
5.3.3 处理失败交易
如果交易失败,我们需要通知用户并记录错误:
- (void)failedTransaction:(SKPaymentTransaction *)transaction {
if (transaction.error.code != SKErrorPaymentCancelled) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"购买失败"
message:transaction.error.localizedDescription
delegate:nil
cancelButtonTitle:@"确定"
otherButtonTitles:nil];
[alert show];
[alert release];
}
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
5.4 记录交易
为了记录用户的购买历史,我们可以在磁盘上保存一个属性列表文件,其中包含每个购买的产品标识符:
- (void)recordTransaction:(SKPaymentTransaction *)transaction {
if ([self.transactionHistory containsObject:transaction.payment.productIdentifier]) {
return;
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"history.plist"];
[self.transactionHistory addObject:transaction.payment.productIdentifier];
[self.transactionHistory writeToFile:path atomically:YES];
}
5.5 提供购买内容
当用户成功购买某个产品时,我们需要将内容提供给用户。例如,如果是壁纸,则将其保存到用户的相机胶卷中:
- (void)provideContent:(NSString *)productIdentifier {
UIImageWriteToSavedPhotosAlbum([UIImage imageNamed:[NSString stringWithFormat:@"%@.jpeg", productIdentifier]], self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"购买完成"
message:@"壁纸已保存到您的相机胶卷。"
delegate:nil
cancelButtonTitle:@"确定"
otherButtonTitles:nil];
[alert show];
[alert release];
}
6. 优化和注意事项
6.1 优化用户体验
确保商店界面简洁明了,用户可以轻松浏览和购买产品。同时,提供详细的购买确认信息,以增强用户的信任感。
6.2 注意事项
- 开发时间 :在向应用添加商店时,始终考虑它将如何影响开发时间。确保在考虑应用内购买产品准备好后立即提交,以免审核过程拖慢部署进度。
- 功能性 :不要让应用完全依赖于应用内购买。确保为那些下载应用但选择不购买产品的用户提供一定的价值。
- 安全性 :确保所有交易通过 iTunes 安全处理,避免在应用中直接处理支付信息。
7. 结论
通过上述步骤,您可以为 iOS 应用添加一个完整且功能强大的应用内购买系统。从设置沙盒测试环境到实现购买逻辑,再到提供购买内容,每个环节都至关重要。希望本文能帮助您更好地理解和实现应用内购买功能,从而为您的应用带来更多收入。
表格:应用内购买产品类型对比
| 产品类型 | 描述 |
|---|---|
| 可消耗品 | 用户每次需要时购买的产品,如游戏中的增强道具。 |
| 非消耗品 | 用户只购买一次并永久拥有的产品,如可下载的歌曲或图像。 |
| 订阅 | 用户根据需要频繁续订的产品,可以是消耗型或非消耗型。 |
mermaid 流程图:应用内购买流程
graph TD;
A[启动应用] --> B[请求产品数据];
B --> C{产品请求完成?};
C -- 是 --> D[更新产品列表];
D --> E[用户选择产品];
E --> F[发起购买请求];
F --> G{交易成功?};
G -- 是 --> H[记录交易];
H --> I[提供购买内容];
G -- 否 --> J{用户取消?};
J -- 是 --> K[结束交易];
J -- 否 --> L[显示错误信息];
L --> K;
通过以上步骤,您可以为 iOS 应用添加一个完整且功能强大的应用内购买系统。希望本文能帮助您更好地理解和实现应用内购买功能,从而为您的应用带来更多收入。

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



