关于苹果内购的一些心得

根据公司的需求,我们的APP内是有内购的,从最开始开始做,到现在,也经历了好些,我觉得有些地方的注意点还得写写.

内购的代码,网上都有这里简单的copy一下

首先,购买苹果的商品,得确定一下,这个内购商品是否存在

-(void) request_products_list_from_apple:(NSArray *) productIDs{

NSSet *productSet = [NSSet setWithArray:productIDs];

SKProductsRequest *apple_request = [[SKProductsRequest alloc] initWithProductIdentifiers:productSet];

apple_request.delegate = self;

NSLog(@"buy---test");

[apple_request start];

}

这段代码是发起获取商品请求,productIDs,是在iTunes里建立商品的对应的ID ,如果有对应的商品会在下面这个代理回调中返回商品信息

-(void)productsRequest:(SKProductsRequest  *)request didReceiveResponse:(SKProductsResponse *)response{

NSArray *products = [response products];

if (products != nil && [products count]>0) {

for(SKProduct *product in products){

NSLog(@"product info");

NSLog(@"SKProduct 描述信息%@", [product description]);

NSLog(@"产品标题 %@" , product.localizedTitle);

NSLog(@"产品描述信息: %@" , product.localizedDescription);

NSLog(@"价格: %@" , product.price);

NSLog(@"Product id: %@" , product.productIdentifier);

}

}

}

确定商品存在以后就可以发起支付请求了,当然在获取商品之前最好先添加观察者

[[SKPaymentQueue defaultQueue] addTransactionObserver:self];

然后发起支付请求

SKPayment *payment = [SKPayment paymentWithProduct:buy_product];//这个buy_product就是你要购买的商品,从上面代理回调返回的商品中筛选出来的

[[SKPaymentQueue defaultQueue] addPayment:payment];

支付过程中发生的变化,都会在下面回调中出现

-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{

for (SKPaymentTransaction *trans in transactions) {

switch (trans.transactionState) {

case SKPaymentTransactionStateFailed:

{

NSLog(@" trans Failed");

switch(trans.error.code) {

case  SKErrorUnknown:

errorMsg = @"无法连接iTunes Store(如有疑问,可以询问苹果客服)";

break;

case  SKErrorClientInvalid:

errorMsg = @"客户端验证错误";

break;

case SKErrorPaymentCancelled:

errorMsg = @"订单已取消";

break;

case SKErrorPaymentNotAllowed:

errorMsg = @"当前苹果设备无法购买商品(如有疑问,可以询问苹果客服)";

break;

case SKErrorPaymentInvalid:

errorMsg = @"购买商品标识无效";

break;

case SKErrorStoreProductNotAvailable:

errorMsg = @"在目前的商店内产品不可购买";

break;

case SKErrorCloudServicePermissionDenied:

errorMsg = @"用户已不允许访问云服务信息(如有疑问,可以询问苹果客服)";

break;

case SKErrorCloudServiceNetworkConnectionFailed:

errorMsg = @"设备没有联网";

break;

}

[[SKPaymentQueue defaultQueue] finishTransaction:trans];

}

break;

case SKPaymentTransactionStatePurchased:

{

NSLog(@" trans Purchased");

NSData *receiptData;

receiptData = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];

if (receiptData != nil) {

NSDictionary *requestContents = @{

@"receipt-data": [receiptData base64EncodedStringWithOptions:0]

};

}

NSError *error;

NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents

options:0

error:&error];

NSString *base64_receipt = [[NSString alloc] initWithData:requestData encoding:NSUTF8StringEncoding];//这个是最后的验证信息,建议传给服务端去验证(本地建议用keychain保存)

[[SKPaymentQueue defaultQueue] finishTransaction: trans];

}

break;

case SKPaymentTransactionStateDeferred:

{

NSLog(@" trans Deferred");

}

break;

case SKPaymentTransactionStateRestored:

{

NSLog(@"恢复购买");

NSData *receiptData;

receiptData = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];

NSString *receipt = [[NSString alloc] initWithData:receiptData encoding:NSUTF8StringEncoding];

[[SKPaymentQueue defaultQueue] finishTransaction:trans];

}

break;

case SKPaymentTransactionStatePurchasing:

{

NSLog(@" trans Purchasing");

}

break;

default:

{

NSLog(@"");

}

break;

}

}

}

-(void)request:(SKRequest *)request didFailWithError:(NSError *)error{

NSLog(@"request fail");//请求失败

}

-(void)requestDidFinish:(SKRequest *)request{

NSLog(@"request finish");//请求完成

}

上述过程基本就完成了内购的流程,其实也不难,但是,就这短短的流程之间就可能会发生好些问题,

在内购时,要加是否越狱的判断,代码顺便也贴出来吧

#define USER_APP_PATH                @"/User/Applications/"

+(BOOL)isJailBreak{

//判断文件是否存在

NSArray *arr = @[@"/Applications/Cydia.app",

@"/Library/MobileSubstrate/MobileSubstrate.dylib",

@"/bin/bash",

@"/usr/sbin/sshd",

@"/etc/apt"  ];

for (NSString *str in arr) {

if ([[NSFileManager defaultManager] fileExistsAtPath:str]) {

NSLog(@"The device is jail broken! path === %@",str);

return YES;

}

}

//return NO;

//判断cydia应用是否存在

if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://"]]) {

NSLog(@"The device is jail broken!");

return YES;

}

//  return NO;

//不越狱的机器没有这个权限来判定的

if ([[NSFileManager defaultManager] fileExistsAtPath:USER_APP_PATH]) {

NSLog(@"The device is jail broken!");

NSArray *applist = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:USER_APP_PATH error:nil];

NSLog(@"applist = %@", applist);

return YES;

}

//  return NO;

//读取环境变量

//    char *env = getenv("DYLD_INSERT_LIBRARIES");

//    NSLog(@"%s", env);

//    if (env) {

//        NSLog(@"The device is jail broken!");

//        return YES;

//    }

NSLog(@"The device is NOT jail broken!");

return NO;

}

内购完成,苹果返回的验证最好在服务端进行验证,网络不佳的情况下,本地最好保存在钥匙串(keychain)中,保存在沙盒可能删掉app,凭证就没有了,这个凭证是非常重要的,内购的唯一依据,苹果只管这个商品有没有效,不会对购买的商品是否一致验证,有的人可以利用现成有效的凭证刷单的

沙箱测试账号,可以在调试状态下,模拟真实购买流程,基本和正常账号是一样的,不过不能在线上版本使用

给苹果审核商品的时候注意名称,有敏感词汇,会被拒

审核app版本的时候,最好注明哪些不是内购商品,否则容易被误解,导致被拒

就先写这些,以后有在补充...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容

  • - 消耗型项目 就像你玩游戏需要买金币,买钻石等,只要花钱就可以无限次的购买 - 非消耗型项目 就像你在App S...
    tiger2016阅读 561评论 0 1
  • 自己开发的视频直播项目,牵涉到充值金币,用到了苹果公司的内购,趴坑了两天,这里总结下实现苹果内购。 一. 创建测试...
    Leo丶Dicaprio阅读 3,252评论 8 7
  • 不知不觉,来这里已经有11天了,该学的东西还没有完全学会。反而是越来越糊涂。特别是这两天,跟了以前的一款板子,由于...
    遇见敏姑娘阅读 302评论 0 0
  • 也许,很久很久以前我们都是一个个单纯而又天真的精灵。只是在懵懂无知的时候逐渐地接触到了这个满是戴着面具生活的形形色...
    大漠郡主阅读 215评论 0 4