版本记录
版本号 | 时间 |
---|---|
V1.0 | 2018.07.24 |
前言
大家都知道,ios虚拟商品如宝石、金币等都需要走内购,和苹果三七分成,如果这类商品不走内购那么上不去架或者上架以后被发现而被下架。最近有一个项目需要增加内购支付功能,所以最近又重新集成并整理了下,希望对大家有所帮助。感兴趣的可以参考上面几篇。
1. iOS内购IAP(一) —— 基础配置篇(一)
2. iOS内购IAP(二) —— 工程实践(一)
3. iOS内购IAP(三) —— 编程指南之关于内购(一)
4. iOS内购IAP(四) —— 编程指南之设计您的应用程序的产品(一)
Retrieving Product Information - 检索产品信息
在购买过程的第一部分,您的应用程序从App Store检索有关其产品的信息,向用户显示其商店UI,然后让用户选择产品,如图2-1所示。
Getting a List of Product Identifiers - 获取产品标识符列表
您在应用中销售的每件商品都有唯一的商品标识码product identifier
。 您的应用使用这些产品标识符从App Store获取有关产品的信息,例如定价,并在用户购买这些产品时提交付款请求。 您的应用可以从其应用包中的文件中读取其产品标识符列表,也可以从服务器中获取它们。 表2-1总结了两种方法之间的差异
Table 2-1 Comparison of approaches for obtaining product identifiers
如果您的应用具有固定的产品列表,例如应用内购买以移除广告或启用功能,请将列表嵌入应用包中。 如果产品标识符列表可以更改而不需要更新您的应用程序(例如支持其他级别或字符的游戏),请让您的应用从服务器获取列表。
没有运行时机制来获取特定应用程序在App Store Connect中配置的所有产品的列表。 您负责管理应用的产品列表并将该信息提供给您的应用。 如果您需要管理大量产品,请考虑使用App Store Connect中的批量XML上载/下载功能。
1. Embedding Product IDs in the App Bundle - 在App Bundle中嵌入产品ID
在您的应用包中包含一个属性列表文件,其中包含一系列产品标识符,例如:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<string>com.example.level1</string>
<string>com.example.level2</string>
<string>com.example.rocket_car</string>
</array>
</plist>
要从属性列表中获取产品标识符,请在应用程序包中找到该文件并进行读取。
NSURL *url = [[NSBundle mainBundle] URLForResource:@"product_ids"
withExtension:@"plist"];
NSArray *productIdentifiers = [NSArray arrayWithContentsOfURL:url];
2. Fetching Product IDs from Your Server - 从服务器获取产品ID
在服务器上托管带有产品标识符的JSON文件。 例如:
[
"com.example.level1",
"com.example.level2",
"com.example.rocket_car"
]
要从服务器获取产品标识符,请获取并读取JSON文件,如Listing 2-1
所示。 考虑对JSON文件进行版本控制,以便应用的未来版本可以更改其结构,而不会破坏应用的旧版本。 例如,您可以命名使用旧结构products_v1.json
的文件和使用新结构products_v2.json
的文件。 如果您的JSON文件比示例中的简单数组更复杂,这将特别有用。
// Listing 2-1 Fetching product identifiers from your server
- (void)fetchProductIdentifiersFromURL:(NSURL *)url delegate:(id)delegate
{
dispatch_queue_t global_queue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(global_queue, ^{
NSError *err;
NSData *jsonData = [NSData dataWithContentsOfURL:url
options:NULL
error:&err];
if (!jsonData) { /* Handle the error */ }
NSArray *productIdentifiers = [NSJSONSerialization
JSONObjectWithData:jsonData options:NULL error:&err];
if (!productIdentifiers) { /* Handle the error */ }
dispatch_queue_t main_queue = dispatch_get_main_queue();
dispatch_async(main_queue, ^{
[delegate displayProducts:productIdentifiers]; // Custom method
});
});
}
有关使用NSURLConnection
(苹果已弃用)下载文件的信息,请参阅URL Loading System Programming Guide
中的Using NSURLConnection
。
要确保您的应用程序保持响应,请使用后台线程下载JSON文件并提取产品标识符列表。 要最小化传输的数据,请使用标准HTTP缓存机制,例如Last-Modified
和If-Modified-Since
标头header。
Retrieving Product Information - 检索产品信息
要确保您的用户只能看到实际可供购买的产品,请在显示应用商店用户界面之前查询App Store。
使用产品请求对象查询App Store。 首先,创建SKProductsRequest的实例,并使用产品标识符列表对其进行初始化。 一定要保持对请求对象的强引用; 否则,系统可能会在请求完成之前解除分配请求。
产品请求检索有关有效产品的信息以及无效产品标识符的列表,然后调用其委托来处理结果。 委托必须实现SKProductsRequestDelegate协议来处理来自App Store的响应。 Listing 2-2显示了两段代码的简单实现。
// Listing 2-2 Retrieving product information
// 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];
}
// 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
}
当用户购买产品时,您需要相应的产品对象来创建付款请求,因此请保留对返回给委托的产品对象数组的引用。如果您的应用程序销售的产品列表可能会更改,您可能需要创建一个自定义类,其中包含对产品对象的引用以及其他信息(例如,从服务器获取的图片或说明文本)。付款请求将在Requesting Payment中讨论。
作为无效返回的产品标识符通常表示应用程序的产品标识符列表中存在错误,但这可能意味着该产品尚未在App Store Connect中正确配置。良好的日志记录和良好的用户界面可以帮助您更轻松地解决此类问题。在生产版本中,您的应用需要优雅地失败 - 通常,这意味着显示应用商店UI的其余部分并省略无效产品。在开发版本中,显示错误以引起对问题的注意。在生产和开发构建中,使用NSLog将消息写入控制台,以便记录无效标识符。如果您的应用程序从服务器获取列表,您还可以定义一种日志记录机制,让您的应用程序将无效标识符列表发送回您的服务器。
Presenting Your App’s Store UI - 展示您应用商店UI
由于您应用商店的设计会对您的应用内销售产生重要影响,因此值得投入时间和精力来做到正确。为商店UI设计用户界面,使其与应用程序的其余部分集成。 StoreKit无法为您提供商店UI。只有您足够了解您的应用及其内容,才能以最佳方式展示您的产品并与应用的其余部分无缝匹配,从而设计您的商店用户界面。
在设计和实现应用商店UI时,请考虑以下准则。
Display a store only if the user can make payments - 仅在用户可以付款时才显示商店。要确定用户是否可以付款,请调用SKPaymentQueue类的canMakePayments类方法。如果用户无法进行付款(例如,由于父母的限制),则显示指示商店不可用的UI或完全省略UI的商店部分。
Present products naturally in the flow of your app - 在您的应用程序流程中自然呈现产品。在UI中找到最佳位置以显示应用的商店UI。在用户可以使用它们时在上下文中呈现产品 - 例如,让用户在尝试使用该高级功能时解锁功能。特别注意用户第一次浏览应用时的体验。
Organize products so that exploration is easy and enjoyable - 组织产品,使探索变得轻松愉快。如果您的应用具有足够少的产品,您可以在一个屏幕上显示所有内容;否则,对产品进行分组或分类,使其易于导航。具有大量产品的应用程序(例如漫画书阅读器或具有许多问题的杂志)尤其受益于使用户能够轻松发现他们想要购买的新项目的界面。通过为产品提供不同的名称和视觉效果来明确产品之间的差异 - 如有必要,请包括明确的比较。
Communicate the value of your products to your users - 向用户传达产品的价值。用户想要确切地知道他们将要购买什么。将App Store中的信息(例如产品价格和说明)与来自服务器或应用程序包的其他数据(例如产品的图像或演示)相结合。在购买产品之前,让用户以有限的方式与产品互动。例如,给用户提供购买新赛车选项的游戏可以允许用户使用新车进行测试。同样,一个允许用户购买额外画笔的绘图应用程序可以让用户有机会在小便笺簿上使用新画笔进行绘制,并查看画笔之间的区别。这种设计为用户提供了体验产品的机会,并确信他们想要购买产品。
Display prices clearly, using the locale and currency returned by the App Store - 使用App Store返回的区域设置和货币清楚地显示价格。确保产品价格易于查找且易于阅读。即使用户的区域设置和价格的区域设置不同,也不要尝试将价格转换为UI中的其他货币。例如,考虑一下美国用户更喜欢英国语言环境的单位和日期格式。您的应用程序根据英国语言环境显示其UI,但仍需要在App Store指定的语言环境中显示产品信息。将价格转换为英镑,以试图匹配界面其余部分的英国区域,将是不正确的。用户在美国拥有App Store帐户并以美元付款,因此价格将以美元提供给您的应用程序。同样,您的应用会以美元显示其价格。
Listing 2-3
显示了如何使用产品的区域设置信息正确格式化价格
// Listing 2-3 Formatting a product’s price
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[numberFormatter setLocale:product.priceLocale];
NSString *formattedPrice = [numberFormatter stringFromNumber:product.price];
用户选择要购买的产品后,您的应用会连接到App Store以请求为产品付款。
Suggested Testing Steps - 建议的测试步骤
测试代码的每个部分以验证您是否已正确实现它。
1. Sign In to the App Store with Your Test Account - 使用您的测试帐户登录App Store
在App Store Connect
中创建测试用户帐户。
在开发iOS设备上,在“设置”中退出App Store。 然后从Xcode构建并运行您的应用程序。
在开发macOS设备上,退出Mac App Store。 然后在Xcode中构建您的应用程序并从Finder启动它。
使用您的应用进行应用内购买。 系统提示您登录App Store时,请使用您的测试帐户。 请注意,文本[Environment:Sandbox]
显示为提示的一部分,表示您已连接到测试环境。
如果未显示文本[Environment:Sandbox]
,则表示您正在使用生产环境。 确保您正在运行应用程序的开发签名版本。 生产签名的构建使用生产环境。
重要:请勿使用您的测试用户帐户登录生产环境。 如果这样做,测试用户帐户将变为无效,无法再使用。
2. Test Fetching the List of Product Identifiers - 测试获取产品标识符列表
如果您的产品标识符嵌入在您的应用程序中,请在加载后在代码中设置断点,并验证NSArray
实例是否包含预期的产品标识符列表。
如果从服务器获取产品标识符,请使用Web浏览器(如Safari
)或命令行实用程序(如curl
)手动获取JSON文件,并验证从服务器返回的数据是否包含预期的产品标识符列表。 还要验证服务器是否正确实现了标准HTTP缓存机制。
3. Test Handling of Invalid Product Identifiers - 无效产品标识符的测试处理
故意在应用的产品标识符列表中包含无效的标识符。 (确保在测试后将其删除。)
在生产版本中,验证应用程序是否显示其商店UI的其余部分,用户可以购买其他产品。 在开发版本中,验证应用程序是否会引起您的注意。
检查控制台日志,确认您可以正确识别无效的产品标识符。
4. Test a Products Request - 测试产品请求
使用您测试的产品标识符列表,创建并提交SKProductsRequest实例。 在代码中设置断点,并检查有效和无效产品标识符的列表。 如果产品标识符无效,请在App Store Connect
中查看您的产品并更正您的JSON文件或属性列表。
后记
本篇主要讲述了检索产品信息,感兴趣的给个赞或者关注~~~~