游戏中心 & 内购
游戏中心 & 内购
技术博客http://www.cnblogs.com/ChenYilong/
新浪微博http://weibo.com/luohanchenyilong
游戏中心 & 内购
• 游戏中心允许用户与其他玩家比较分数的服务被 称为排行榜
• 游戏中心允许用户达成某些目标的服务被称为成 就。成就由每个游戏定义,其目的在于激励用户 持续游戏
• 要使用游戏中心,首先需要在iTune Connect中启 用游戏中心
启用游戏中心的步骤
技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong
设置应用程序辅助信息
• 应用分类及子分类
• 描述信息
• 搜索关键字
• 开发者支持网站
• 测试账号的用户名及密码
• 图标图片(1024*1024png)
• 3.5英寸iPhone截图(1~5张640*960png)
• 4英寸iPhone截图(1~5张640*1136png)
• iPad截图(1~5张2048*2048png)
• 提示:仅上传某一设备的图片,表示该应用程序仅在对应 的设备上可用。
新建的应用程序首页
为应用程序添加游戏中心支持
技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong
添加代码初始化本地游戏用户
• 之所以使用本地游戏用户,是因为如果用户不登录游戏中 心,则在本地建立一个临时用户,保证用户仍然继续游戏
[[GKLocalPlayer localPlayer]setAuthenticateHandler:^(UIViewController*controller, NSError *error) {
if ([GKLocalPlayerlocalPlayer].isAuthenticated) { NSLog(@"已经授权”);
} else if (controller) {
[self presentViewController:controller
animated:YES completion:nil]; } else {
NSLog(@"不支持游戏中心”); }
}];
进入游戏时,自动弹出游戏中心登录窗口
GKScore *score = [[GKScorealloc]initWithCategory:category]; score.value = highScores;
[scorereportScoreWithCompletionHandler:^(NSError*error) {
if (error = nil) {
NSLog(@"%@", error.localizedDescription);
} }];
技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong
在应用中显示排行榜视图控制器
// 1) 实例化排行榜视图控制器GKLeaderboardViewController*leaderController =
[[GKLeaderboardViewControlleralloc]init];
// 2) 设置排行榜分类 [leaderControllersetCategory:kHighScoreCategory]; // 3) 设置代理 [leaderControllersetLeaderboardDelegate:self];
// 4) 显示排行榜视图控制器
[selfpresentViewController:leaderControlleranimated:YES completion:nil];
报告成就
GKAchievement *achievement = [[GKAchievementalloc]initWithIdentifier:identifier];
// 设置成就完成度
achievement.percentComplete = 100.0;
[achievementreportAchievementWithCompletionHandler:^(NSError*error) {
if (error = nil) {
NSLog(@"%@", error.localizedDescription);
} }];
技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong
在应用中显示成就视图控制器
// 1) 实例化成就视图控制器GKAchievementViewController*achievementController =
[[GKAchievementViewControlleralloc]init];
// 2) 设置代理 [achievementControllersetAchievementDelegate:self];
// 3) 显示成就视图控制器
[selfpresentViewController:achievementControlleranimated:YES completion:nil];
显示条幅
• 在提交排行榜成绩时,如果- 提交的分数低于服务器的分数,则不会被记录 - 提交的分数高于服务器的分数,则会被记录
• 在向服务器提交成绩或者成就时,如果网络不可用,则成 绩或者成就会被缓存,待到网络可用时再提交至服务器, 从而保证用户的成果不会丢失
• 关于内置的游戏中心控制器在iOS7做了进一步整合
内购--应用内购买
• 非消耗品(Nonconsumable)- 指的是在游戏中一次性购买并拥有永久访问权的物品或服务。非消耗品
物品可以被用户再次下载,并且能够在用户的所有设备上使用 • 消耗品(Consumable)
- 专为支持可消耗的物品或服务设计的,消耗品购买不可被再次下载,根 据其特点,消耗品不能在用户的设备之间跨设备使用,除非自定义服务 在用户的账号之间共享这些信息
• 以下三种类别在iBooks中使用,目前iBooks不支持大陆市场 - 免费订阅(Free subscriptions) - 自动续费订阅(Auto-renewing subscriptions) - 非自动续费订阅(Nonrenewing subscriptions)
技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong
准备工作
消耗品定义
语言及测试用户信息
定义的商品
修改应用程序信息
内购流程
• 请求有效的产品代号集合• 购买指定产品• 验证购买• 恢复购买(针对非消耗品)
技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong
请求有效产品集合
// 1) 实例化产品请求 SKProductsRequest *request = [[SKProductsRequest
alloc]initWithProductIdentifiers:identifiers]; // 2) 设置代理 [request setDelegate:self];
// 3) 启动请求
[request start];
提示:
1. 实例化请求时,必须指定有效的identifiers集合,之所以如此处理,主要是为了确 保提交的内购商品真的通过了苹果的审批,处于可用状态
2. 要想获取到准确的可用产品集合,需要通过代理方法实现
- (void)productsRequest:(SKProductsRequest*)request
didReceiveResponse:(SKProductsResponse*)response 3. 越狱用户无法测试内购,但是可以购买
购买产品
1. 内购的交易过程是通过SKPaymentTransactionObserver监控的,因此需 要为IAPHelper添加交易观察者:
// 添加交易观察者对象
[[SKPaymentQueuedefaultQueue]addTransactionObserver:sharedInstance];
2. 由于发起交易需要使用SKProduct对象,因此需要使用字典记录所有
可用的商品
NSMutableDictionary *_productsDict;
交易队列回调方法
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions: (NSArray *)transactions
{
for (SKPaymentTransaction *transaction intransactions) {
// 购买完成 if (transaction.transactionState ==
SKPaymentTransactionStatePurchased) { NSLog(@"购买完成 %@",
transaction.payment.productIdentifier);
[queue finishTransaction:transaction]; } else if (transaction.transactionState ==
SKPaymentTransactionStateFailed) {
if (transaction.error.code =SKErrorPaymentCancelled) {
NSLog(@"交易失败: %@", transaction.error.localizedDescription);
} }
} }
技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong
恢复购买
#define ITMS_PROD_VERIFY_RECEIPT_URL @"https://buy.itunes.apple.com/verifyReceipt"
#define ITMS_SANDBOX_VERIFY_RECEIPT_URL @"https://sandbox.itunes.apple.com/verifyReceipt”
验证购买iOS7(部分)
// 1. 从Bundle中获取到购买凭据
NSURL *receiptUrl = [[NSBundle mainBundle]appStoreReceiptURL];
NSData *receiptData = [NSDatadataWithContentsOfURL:receiptUrl];
// 2. 对交易凭据进行Base64编码
NSString *encodeStr = [receiptDatabase64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
// 3. 将凭据发送给苹果的服务器验证购买
NSURL *url = [NSURLURLWithString:ITMS_SANDBOX_VERIFY_RECEIPT_URL];
NSMutableURLRequest *request = [NSMutableURLRequestrequestWithURL:urlcachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0f];
request.HTTPMethod = @"POST”;
NSString *payload = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@ \"}", encodeStr];
NSData *payloadData = [payloaddataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody = payloadData;
验证购买iOS6(1)
// 3. 发送同步请求 NSURLResponse *response =nil;
NSData *data = [NSURLConnectionsendSynchronousRequest:requestreturningResponse:&response error:nil];
// 4. 使用JSON解析返回数据
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:dataoptions:NSJSONReadingAllowFragments error:nil];
[jsonDict writeToFile:@"/users/…/Desktop/123.plist" atomically:YES];
if ([jsonDict[@"status"]integerValue] == 0) {
NSLog(@"验证通过”); }
购买数据记录问题--系统偏好
[[NSUserDefaults standardUserDefaults]setBool:isPurchased
forKey:productId];
[[NSUserDefaults standardUserDefaults]synchronize];
游戏中心简介
• 游戏中心允许用户与其他玩家比较分数的服务被 称为排行榜
• 游戏中心允许用户达成某些目标的服务被称为成 就。成就由每个游戏定义,其目的在于激励用户 持续游戏
• 要使用游戏中心,首先需要在iTune Connect中启 用游戏中心
启用游戏中心的步骤
技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong
设置应用程序辅助信息
• 应用分类及子分类
• 描述信息
• 搜索关键字
• 开发者支持网站
• 测试账号的用户名及密码
• 图标图片(1024*1024png)
• 3.5英寸iPhone截图(1~5张640*960png)
• 4英寸iPhone截图(1~5张640*1136png)
• iPad截图(1~5张2048*2048png)
• 提示:仅上传某一设备的图片,表示该应用程序仅在对应 的设备上可用。
新建的应用程序首页
为应用程序添加游戏中心支持
技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong
添加代码初始化本地游戏用户
• 之所以使用本地游戏用户,是因为如果用户不登录游戏中 心,则在本地建立一个临时用户,保证用户仍然继续游戏
[[GKLocalPlayer localPlayer]setAuthenticateHandler:^(UIViewController*controller, NSError *error) {
if ([GKLocalPlayerlocalPlayer].isAuthenticated) { NSLog(@"已经授权”);
} else if (controller) {
[self presentViewController:controller
animated:YES completion:nil]; } else {
NSLog(@"不支持游戏中心”); }
}];
进入游戏时,自动弹出游戏中心登录窗口
GKScore *score = [[GKScorealloc]initWithCategory:category]; score.value = highScores;
[scorereportScoreWithCompletionHandler:^(NSError*error) {
if (error = nil) {
NSLog(@"%@", error.localizedDescription);
} }];
技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong
在应用中显示排行榜视图控制器
// 1) 实例化排行榜视图控制器GKLeaderboardViewController*leaderController =
[[GKLeaderboardViewControlleralloc]init];
// 2) 设置排行榜分类 [leaderControllersetCategory:kHighScoreCategory]; // 3) 设置代理 [leaderControllersetLeaderboardDelegate:self];
// 4) 显示排行榜视图控制器
[selfpresentViewController:leaderControlleranimated:YES completion:nil];
报告成就
GKAchievement *achievement = [[GKAchievementalloc]initWithIdentifier:identifier];
// 设置成就完成度
achievement.percentComplete = 100.0;
[achievementreportAchievementWithCompletionHandler:^(NSError*error) {
if (error = nil) {
NSLog(@"%@", error.localizedDescription);
} }];
技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong
在应用中显示成就视图控制器
// 1) 实例化成就视图控制器GKAchievementViewController*achievementController =
[[GKAchievementViewControlleralloc]init];
// 2) 设置代理 [achievementControllersetAchievementDelegate:self];
// 3) 显示成就视图控制器
[selfpresentViewController:achievementControlleranimated:YES completion:nil];
显示条幅
• 在提交排行榜成绩时,如果- 提交的分数低于服务器的分数,则不会被记录 - 提交的分数高于服务器的分数,则会被记录
• 在向服务器提交成绩或者成就时,如果网络不可用,则成 绩或者成就会被缓存,待到网络可用时再提交至服务器, 从而保证用户的成果不会丢失
• 关于内置的游戏中心控制器在iOS7做了进一步整合
内购--应用内购买
• 非消耗品(Nonconsumable)- 指的是在游戏中一次性购买并拥有永久访问权的物品或服务。非消耗品
物品可以被用户再次下载,并且能够在用户的所有设备上使用 • 消耗品(Consumable)
- 专为支持可消耗的物品或服务设计的,消耗品购买不可被再次下载,根 据其特点,消耗品不能在用户的设备之间跨设备使用,除非自定义服务 在用户的账号之间共享这些信息
• 以下三种类别在iBooks中使用,目前iBooks不支持大陆市场 - 免费订阅(Free subscriptions) - 自动续费订阅(Auto-renewing subscriptions) - 非自动续费订阅(Nonrenewing subscriptions)
技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong
准备工作
消耗品定义
语言及测试用户信息
定义的商品
修改应用程序信息
内购流程
添加StoreKit框架
• 请求有效的产品代号集合• 购买指定产品• 验证购买• 恢复购买(针对非消耗品)
技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong
请求有效产品集合
// 1) 实例化产品请求 SKProductsRequest *request = [[SKProductsRequest
alloc]initWithProductIdentifiers:identifiers]; // 2) 设置代理 [request setDelegate:self];
// 3) 启动请求
[request start];
提示:
1. 实例化请求时,必须指定有效的identifiers集合,之所以如此处理,主要是为了确 保提交的内购商品真的通过了苹果的审批,处于可用状态
2. 要想获取到准确的可用产品集合,需要通过代理方法实现
- (void)productsRequest:(SKProductsRequest*)request
didReceiveResponse:(SKProductsResponse*)response 3. 越狱用户无法测试内购,但是可以购买
购买产品
1. 内购的交易过程是通过SKPaymentTransactionObserver监控的,因此需 要为IAPHelper添加交易观察者:
// 添加交易观察者对象
[[SKPaymentQueuedefaultQueue]addTransactionObserver:sharedInstance];
2. 由于发起交易需要使用SKProduct对象,因此需要使用字典记录所有
可用的商品
NSMutableDictionary *_productsDict;
交易队列回调方法
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions: (NSArray *)transactions
{
for (SKPaymentTransaction *transaction intransactions) {
// 购买完成 if (transaction.transactionState ==
SKPaymentTransactionStatePurchased) { NSLog(@"购买完成 %@",
transaction.payment.productIdentifier);
[queue finishTransaction:transaction]; } else if (transaction.transactionState ==
SKPaymentTransactionStateFailed) {
if (transaction.error.code =SKErrorPaymentCancelled) {
NSLog(@"交易失败: %@", transaction.error.localizedDescription);
} }
} }
技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong
恢复购买
#define ITMS_PROD_VERIFY_RECEIPT_URL @"https://buy.itunes.apple.com/verifyReceipt"
#define ITMS_SANDBOX_VERIFY_RECEIPT_URL @"https://sandbox.itunes.apple.com/verifyReceipt”
验证购买iOS7(部分)
// 1. 从Bundle中获取到购买凭据
NSURL *receiptUrl = [[NSBundle mainBundle]appStoreReceiptURL];
NSData *receiptData = [NSDatadataWithContentsOfURL:receiptUrl];
// 2. 对交易凭据进行Base64编码
NSString *encodeStr = [receiptDatabase64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
// 3. 将凭据发送给苹果的服务器验证购买
NSURL *url = [NSURLURLWithString:ITMS_SANDBOX_VERIFY_RECEIPT_URL];
NSMutableURLRequest *request = [NSMutableURLRequestrequestWithURL:urlcachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0f];
request.HTTPMethod = @"POST”;
NSString *payload = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@ \"}", encodeStr];
NSData *payloadData = [payloaddataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody = payloadData;
验证购买iOS6(1)
// 1. 使用base64加密交易凭据
NSString *encodeStr = [transction.transactionReceiptbase64EncodedString];
// 2. 建立验证请求
// 1) URL
NSURL *url = [NSURLURLWithString:ITMS_SANDBOX_VERIFY_RECEIPT_URL];
// 2) 建立请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:urlcachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:5.0f];
// 1> 请求数据体 NSString *payload = [NSStringstringWithFormat:@"{\"receipt-data\" :
\"%@\"}", encodeStr];
NSData *payloadData = [payload
dataUsingEncoding:NSUTF8StringEncoding]; // 2>设置数据体 [request setHTTPBody:payloadData]; [request setHTTPMethod:@"POST"];
技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong
验证购买iOS6(2)
NSString *encodeStr = [transction.transactionReceiptbase64EncodedString];
// 2. 建立验证请求
// 1) URL
NSURL *url = [NSURLURLWithString:ITMS_SANDBOX_VERIFY_RECEIPT_URL];
// 2) 建立请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:urlcachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:5.0f];
// 1> 请求数据体 NSString *payload = [NSStringstringWithFormat:@"{\"receipt-data\" :
\"%@\"}", encodeStr];
NSData *payloadData = [payload
dataUsingEncoding:NSUTF8StringEncoding]; // 2>设置数据体 [request setHTTPBody:payloadData]; [request setHTTPMethod:@"POST"];
技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong
验证购买iOS6(2)
// 3. 发送同步请求 NSURLResponse *response =nil;
NSData *data = [NSURLConnectionsendSynchronousRequest:requestreturningResponse:&response error:nil];
// 4. 使用JSON解析返回数据
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:dataoptions:NSJSONReadingAllowFragments error:nil];
[jsonDict writeToFile:@"/users/…/Desktop/123.plist" atomically:YES];
if ([jsonDict[@"status"]integerValue] == 0) {
NSLog(@"验证通过”); }
购买数据记录问题--系统偏好
[[NSUserDefaults standardUserDefaults]setBool:isPurchased
forKey:productId];
[[NSUserDefaults standardUserDefaults]synchronize];
http://www.cnblogs.com/ChenYilong/p/3561142.html
Thanks Q & A
技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong© chenyilong. Powered by Postach.io
作者:
出处:http://www.cnblogs.com/ChenYilong/(点击RSS订阅)
本文版权归作者和博客园共有,欢迎转载,
但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。