当前位置: 首页 > news >正文

iOS开发之内购-AppStore

本文会给大家详细介绍iOS内购,虽然之前网上也有内购的教程,但是还不够详细,我重新整理出一份教程,希望对大家有所帮助。

基于Xcode7.1.1版本,模拟器iphone6,9.1系统。
部分地方直接摘自网络,省时省心省力。
多图预警!!!
转载请注明出处@yimouleng

一. 创建测试App

创建App-1

首先你需要登录 App的ItunesConnection,你会看到如下界面

简单的介绍一下这几个选项

  • 1.我的App主要用于管理自己的App应用,例如编辑资料,上架,下架等。
  • 2.销售和趋势主要是来查看App在各个平台的下载量,收入等方面数据,里面有曲线图等图文结合的方式给我们参考。
  • 3.付款和财务报告显示的是你的收入以及付款等相关信息。
  • 4.iAd主要是跟广告有关,开发者可以登录到Workbench,通过iAd对应用的广告进行控制。
  • 5.用户和职能用于生成相应账号,例如苹果沙河测试账号。
  • 6.协议,税务和银行业务则是你银行相关账户的信息设置。

在这里我们选择第一个选项,我的App, 然后点击左上角的加号,新建一个用来测试用的App。

我们会看到弹出的窗口

在这里有几个需要填写的地方,名称自己取,平台IOS,语言选择了简体中文,套装ID也就是你的Bundle Identifier,需要你在Certificates页面 申请BundleID,在这里简单的给大家介绍一下。

申请BundleID

打开Certificates页面 ,在左侧选择 Identifiers,并点击加号,申请一个新的Identifiers。

在这里Name可以随意填写,我填写的是TestAppStroeTestDemo,而用来使用的BundleID,我们在这里必须选择第一个选项唯一的,不用选择通配。在下面的选项中, 我们只需要勾选一个 Apple Pay即可,其他选项看自己需求,我在这里只选择了它。

之后一路Done即可。

创建App-2

之后我们回到创建App,选择好自己刚创建的 BundleID ,填写SKU, SKU是你App的专用ID,我在这里随意填写,直接复制了App名。点击创建,我们的测试App则创建成功。

二.添加内购

App创建好之后,我们打开创建的App,在左上角选择功能,会看到左侧的App 内购买项目。我们点击右下角的加号,为App添加内购项目。

之后我们会看到类型的选项,如下图

官方的注释写的很清楚了,只在这里简单的说下前两种

消耗型项目 就像你玩游戏需要买金币,买钻石等,只要花钱就可以无限次的购买
非消耗型项目 就像你在App Store购买App,买了一次之后就不用再买第二次,你拥有永久使用权。

在这里为了方便测试,我们选择第一种 消耗型项目 。来到内购项目填写页面,如下图。

这里有几个选项,需要填写商品名称,产品ID以及价格等级,简单说明一下

1.商品名称根据你的消费道具的实际意义来说明,比如“100颗宝石”,“100金币”等。
2.产品ID是比较重要的,由项目自定义,只要唯一即可,因为测试,我在这里随便填写的123,在实际应用中,一定要认真填写。
3.价格等级的话“查看价格表”中有对应的说明,可以对照着表中每个国家的货币价格与等级来选择

接下来是语言选择,和上传快照如下图

点击添加语言,填写名称和描述,这里我们依然选择简体中文,如下

审核备注,根据实际情况填写,可以不填。而下面的屏幕快照,则是商品图片,以像素为单位,最低尺寸为321,390,尺寸需求如下图,上传即可。

到这里为止, 我们的内购项目则添加完成。接下来则是测试阶段了。

三.申请沙盒测试账号(用来测试购买项目)

这个账号,是利用苹果的沙盒测试环境来模拟AppStore的购买流程,你肯定不会想要用真实RMB去购买测试吧?
首先我们回到iTunes Connect中,在这里我们选择用户和职能

然后在上面的第三个选项沙箱技术测试员中点击加号,添加测试员。

在信息填写页面只简单说两句。

所有信息都可以随意填写,不用管是否真实。
App Store地区选择,一定要选对,它对应的是你创建的App的地区, 你App是中国的话, 在这里我们依然选择中国。
此账号只能用来测试,不要在正式的appstore上使用

填写完毕,点击保存后,我们则生成一个测试账号,当然这个账号是可以随时删除和添加的。

四.核心代码

之后终于到了我们撸代码的时候了,点开你的Xcode创建你的项目!

首先我们需要在项目工程中加入“storekit.framework”,加入头文件#import 
在.h文件中加入“SKPaymentTransactionObserver,SKProductsRequestDelegate”监听机制
代码很简单,直接在.m文件在中填写,添加了二次验证,防止越狱手机等内购。如下,

.m文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
//
// ViewController.m
// 内购
//
// Created by Ely on 15/12/15.
// Copyright © 2015年 Ely. All rights reserved.
//

#import "ViewController.h"
#import <StoreKit/StoreKit.h>
#import "SVProgressHUD.h"

@interface ViewController ()<SKPaymentTransactionObserver,SKProductsRequestDelegate>
@property (nonatomic,strong) NSArray *profuctIdArr;
@property (nonatomic,copy) NSString *currentProId;

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

[self createPay];
}


- (void)createPay
{
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
self.profuctIdArr = @[@"123"];

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(100, 100, 100, 100);
button.backgroundColor = [UIColor greenColor];
[button setTitle:@"6元" forState:UIControlStateNormal];
[button addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchDown];
button.tag = 100;
[self.view addSubview:button];
}

- (void)btnClick:(UIButton *)button
{
NSString *product = self.profuctIdArr[button.tag-100];
_currentProId = product;
if([SKPaymentQueue canMakePayments]){
[self requestProductData:product];
}else{
NSLog(@"不允许程序内付费");
}
}

//请求商品
- (void)requestProductData:(NSString *)type{
NSLog(@"-------------请求对应的产品信息----------------");

[SVProgressHUD showWithStatus:nil maskType:SVProgressHUDMaskTypeBlack];

NSArray *product = [[NSArray alloc] initWithObjects:type,nil];

NSSet *nsset = [NSSet setWithArray:product];
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset];
request.delegate = self;
[request start];

}

//收到产品返回信息
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{

NSLog(@"--------------收到产品反馈消息---------------------");
NSArray *product = response.products;
if([product count] == 0){
[SVProgressHUD dismiss];
NSLog(@"--------------没有商品------------------");
return;
}

NSLog(@"productID:%@", response.invalidProductIdentifiers);
NSLog(@"产品付费数量:%lu",(unsigned long)[product count]);

SKProduct *p = nil;
for (SKProduct *pro in product) {
NSLog(@"%@", [pro description]);
NSLog(@"%@", [pro localizedTitle]);
NSLog(@"%@", [pro localizedDescription]);
NSLog(@"%@", [pro price]);
NSLog(@"%@", [pro productIdentifier]);

if([pro.productIdentifier isEqualToString:_currentProId]){
p = pro;
}
}

SKPayment *payment = [SKPayment paymentWithProduct:p];

NSLog(@"发送购买请求");
[[SKPaymentQueue defaultQueue] addPayment:payment];
}

//请求失败
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error{
[SVProgressHUD showErrorWithStatus:@"支付失败"];
NSLog(@"------------------错误-----------------:%@", error);
}

- (void)requestDidFinish:(SKRequest *)request{
[SVProgressHUD dismiss];
NSLog(@"------------反馈信息结束-----------------");
}
//沙盒测试环境验证
#define SANDBOX @"https://sandbox.itunes.apple.com/verifyReceipt"
//正式环境验证
#define AppStore @"https://buy.itunes.apple.com/verifyReceipt"
/**
* 验证购买,避免越狱软件模拟苹果请求达到非法购买问题

转载于:https://www.cnblogs.com/oc-bowen/p/6000183.html

相关文章:

  • matplotlib —— 添加文本信息(text)
  • linux下压缩包的解压
  • [Java][Liferay] File system in liferay
  • 用for、while、do-while循环输出10句“好好学习,天天向上!”
  • 常见标签的全称
  • 【EntityFramework Core】实体实例化注入
  • apiCloud中的API对象
  • 静态链接
  • 多大开始玩EV3
  • HTTP/2探索第一篇——概念
  • Atitit 图像清晰度 模糊度 检测 识别 评价算法 源码实现attilax总结
  • (BFS)hdoj2377-Bus Pass
  • 最少交换次数
  • 团队作业三之问题解答
  • srand()、rand()、time()函数的用法
  • 10个确保微服务与容器安全的最佳实践
  • ES6系列(二)变量的解构赋值
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • exif信息对照
  • javascript数组去重/查找/插入/删除
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • Mac转Windows的拯救指南
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 什么软件可以剪辑音乐?
  • 小程序滚动组件,左边导航栏与右边内容联动效果实现
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • mysql面试题分组并合并列
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • #QT(一种朴素的计算器实现方法)
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (附源码)php新闻发布平台 毕业设计 141646
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)
  • (三) diretfbrc详解
  • (五)c52学习之旅-静态数码管
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • .NET Core 将实体类转换为 SQL(ORM 映射)
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .NET/C# 推荐一个我设计的缓存类型(适合缓存反射等耗性能的操作,附用法)
  • .Net开发笔记(二十)创建一个需要授权的第三方组件
  • .Net下的签名与混淆
  • @cacheable 是否缓存成功_让我们来学习学习SpringCache分布式缓存,为什么用?
  • @RequestMapping处理请求异常
  • [ vulhub漏洞复现篇 ] Apache Flink目录遍历(CVE-2020-17519)
  • []error LNK2001: unresolved external symbol _m
  • [AI]文心一言出圈的同时,NLP处理下的ChatGPT-4.5最新资讯
  • [Android] Android ActivityManager
  • [Angular 基础] - 表单:响应式表单