[iOS]swift版内购
//内购Demo,看代码说话吧
class IAPTestViewController: UIViewController ,SKProductsRequestDelegate, SKPaymentTransactionObserver{ let VERIFY_RECEIPT_URL = "https://buy.itunes.apple.com/verifyReceipt"
let ITMS_SANDBOX_VERIFY_RECEIPT_URL = "https://sandbox.itunes.apple.com/verifyReceipt" var productDict:NSMutableDictionary! override func viewDidLoad() {
super.viewDidLoad()
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
requestProducts()//请求产品列表资料 }
deinit{
SKPaymentQueue.defaultQueue().removeTransactionObserver(self)
} override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
} // 点击购买产品后触发的
func onSelectRechargePackages(productId: String){
//先判断是否支持内购
if(SKPaymentQueue.canMakePayments()){
buyProduct(productDict[productId] as! SKProduct)
}
else{
println("============不支持内购功能")
} }
//询问苹果的服务器能够销售哪些商品
func requestProducts(){
var set = NSSet(array: ["你的产品id1","产品id2"。。。。更多])
let request = SKProductsRequest(productIdentifiers: set as Set<NSObject>)
request.delegate = self;
request.start()
} // 以上查询的回调函数
func productsRequest(request: SKProductsRequest!, didReceiveResponse response: SKProductsResponse!) {
if (productDict == nil) {
productDict = NSMutableDictionary(capacity: response.products.count)
} for product in response.products as! [SKProduct] {
// 激活了对应的销售操作按钮,相当于商店的商品上架允许销售
println("=======Product id=======\(product.productIdentifier)")
println("===产品标题 ==========\(product.localizedTitle)")
println("====产品描述信息==========\(product.localizedDescription)")
println("=====价格: =========\(product.price)") // 填充商品字典
productDict.setObject(product, forKey: product.productIdentifier) }
}
// 购买对应的产品
func buyProduct(product: SKProduct){ var payment = SKPayment(product: product)
SKPaymentQueue.defaultQueue().addPayment(payment)
}
func paymentQueue(queue: SKPaymentQueue!, updatedTransactions transactions: [AnyObject]!){
// 调试
for transaction in transactions {
// 如果小票状态是购买完成
if (SKPaymentTransactionState.Purchased == transaction.transactionState) {
// 更新界面或者数据,把用户购买得商品交给用户
println("支付成了==================")
// 验证购买凭据
self.verifyPruchase() // 将交易从交易队列中删除
SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction) }
else if(SKPaymentTransactionState.Failed == transaction.transactionState){
println("支付失败==================")
SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction)
}
else if (SKPaymentTransactionState.Restored == transaction.transactionState) {//恢复购买
// 更新界面或者数据,把用户购买得商品交给用户
// ... // 将交易从交易队列中删除
SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction)
} } }
func verifyPruchase(){
// 验证凭据,获取到苹果返回的交易凭据
// appStoreReceiptURL iOS7.0增加的,购买交易完成后,会将凭据存放在该地址
let receiptURL = NSBundle.mainBundle().appStoreReceiptURL
// 从沙盒中获取到购买凭据
let receiptData = NSData(contentsOfURL: receiptURL!)
// 发送网络POST请求,对购买凭据进行验证
let url = NSURL(string: ITMS_SANDBOX_VERIFY_RECEIPT_URL)
// 国内访问苹果服务器比较慢,timeoutInterval需要长一点
let request = NSMutableURLRequest(URL: url!, cachePolicy: NSURLRequestCachePolicy.UseProtocolCachePolicy, timeoutInterval: 10.0)
request.HTTPMethod = "POST"
// 在网络中传输数据,大多情况下是传输的字符串而不是二进制数据
// 传输的是BASE64编码的字符串
/**
BASE64 常用的编码方案,通常用于数据传输,以及加密算法的基础算法,传输过程中能够保证数据传输的稳定性
BASE64是可以编码和解码的
*/
let encodeStr = receiptData?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.EncodingEndLineWithLineFeed) let payload = NSString(string: "{\"receipt-data\" : \"" + encodeStr! + "\"}")
println(payload)
let payloadData = payload.dataUsingEncoding(NSUTF8StringEncoding) request.HTTPBody = payloadData; // 提交验证请求,并获得官方的验证JSON结果
let result = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil) // 官方验证结果为空
if (result == nil) {
//验证失败
println("验证失败")
return
}
var dict: AnyObject? = NSJSONSerialization.JSONObjectWithData(result!, options: NSJSONReadingOptions.AllowFragments, error: nil)
if (dict != nil) {
// 比对字典中以下信息基本上可以保证数据安全
// bundle_id&application_version&product_id&transaction_id
// 验证成功
println(dict)
}
}
func restorePurchase(){
SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
} }
PS:过程中遇到的问题
1.点击购买没有弹出输入账户密码框,解决方法是 到手机设置里面iTunes Store 与 App Store 里面注销你原本的账号
2.每次进来添加了 SKPaymentQueue.defaultQueue().addTransactionObserver(self) 状态监听之后,就会调用很多次 支付失败 ,原因是之前调试失败之后,没有 SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction) ,所以每次系统自动帮你请求上一次失败的操作,结果还是继续失败。
[iOS]swift版内购的更多相关文章
- iOS:苹果内购实践
iOS 苹果的内购 一.介绍 苹果规定,凡是虚拟的物品(例如:QQ音乐的乐币)进行交易时,都必须走苹果的内购通道,苹果要收取大约30%的抽成,所以不允许接入第三方的支付方式(微信.支付宝等),当然开发 ...
- iOS开发苹果内购的介绍与实现
1.iOS开发苹果内购的介绍 1.1 介绍 苹果规定,凡是虚拟的物品(例如:QQ音乐的乐币)进行交易时,都必须走苹果的内购通道,苹果要收取大约30%的抽成,所以不允许接入第三方的支付方式(微信.支付宝 ...
- iOS开发系列——内购、GameCenter、iCloud、Passbook系统服务开发汇总
社交 Social 现在很多应用都内置“社交分享”功能,可以将看到的新闻.博客.广告等内容分享到微博.微信.QQ.空间等,其实从iOS6.0开始苹果官方就内置了Social.framework专门来实 ...
- ios swift版 sqlite3详解
iOS中的SQLite3的封装与详细应用 SQLite是一个开源的嵌入式关系数据库,特点是易使用.高效.安全可靠.可移植性强. iOS中的本地持久化存储 NSUserDefault:一般用于存储小规模 ...
- [Xcode 实际操作]九、实用进阶-(31)为IAP(支付方式)内购功能的具体实现和测试
目录:[Swift]Xcode实际操作 本文将演示如何为IAP(支付方式)内购功能的具体实现和测试. 内购是苹果市场上的一种常见的盈利方式. 在项目中确保已经安装了第三方库[Pod],双击[Podfi ...
- AppStore ipa (苹果内购)笔记
内购示意图 准备条件 苹果的开发者证书,已经为应用启用App内购,并在Xcode更新配置文件 itunes store设置 itunes中创建App及其它设置 参考:iOS应用程序内购/内付费(一) ...
- iOS开发系列--通讯录、蓝牙、内购、GameCenter、iCloud、Passbook系统服务开发汇总
--系统应用与系统服务 iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用 ...
- iOS开发系列通讯录、蓝牙、内购、GameCenter、iCloud、Passbook系统服务开
--系统应用与系统服务 iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用 ...
- [Swift通天遁地]四、网络和线程-(15)程序内购功能
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
随机推荐
- check sub-string in the string
if "blah" not in somestring: continue
- toxiproxy 安装试用
备注: 实际上是一个代理工具,但是又不是简单的进行代理(tcp,可以配置策略,toxics 实现延迟,模拟故障, 对于这个大家可能了解的就是netflix 公司的chaos monkey, ...
- c++深拷贝/浅拷贝
拷贝构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化.其唯一的参数(对象的引用)是不可变的(const类型).此函数经常用在函数调用时用户定义类型的值传递及返 ...
- [深度学习]Wake-Sleep算法
本文翻译自2007-To recognize shapes, first learn to generate images, Geoffrey Hinton. 第五种策略的设计思想是使得高层的特征提取 ...
- Python——while、continue、break、while-else、or、and、not
1. while 终止while循环: (1) 改变条件,使其不成立 (2) break 应用实例1:计算1+2+3+...+100 #1.使用两个变量 count = 1 sum = 0 while ...
- 【Leetcode 338】 Counting Bits
问题描述:给出一个非负整数num,对[0, num]范围内每个数都计算它的二进制表示中1的个数 Example:For num = 5 you should return [0,1,1,2,1,2] ...
- css ! important 兼容性的一点测试
css ! important 这个东西网上一堆内容,我只说我用到的一点地方和我的理解, 这个东西ie6不支持,ie高版本是支持的.其他浏览器也是支持.先理解这一点 .abc { width:100p ...
- 基于JDBC的跨平台数据库管理工具DbVisualizer安装步骤(图文详解)(博主推荐)
首先,关于跨平台数据库管理工具DbVisualizer是什么?这个不多说,大家自行去看. 这个工具可以自定义连接其他没有驱动的数据库. 公司的项目牵扯到的数据库有mysql,sqlserver,o ...
- angualr 之 $$phase
对于angular, $$phase 是 作为angular 内部状态表示位,用来标示当前是处于哪个阶段. 用有的阶段有 $digest $apply 在使用的是例如你想调用scope.$apply的 ...
- [Python] Request module
http://docs.python-requests.org/zh_CN/latest/user/quickstart.html