[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) ,所以每次系统自动帮你请求上一次失败的操作,结果还是继续失败。

				
时间: 2024-08-19 22:01:46

[iOS]swift版内购的相关文章

iOS:苹果内购实践

iOS 苹果的内购 一.介绍 苹果规定,凡是虚拟的物品(例如:QQ音乐的乐币)进行交易时,都必须走苹果的内购通道,苹果要收取大约30%的抽成,所以不允许接入第三方的支付方式(微信.支付宝等),当然开发者可以设置后门,在审核时避开审核人员.这个是有风险的,一旦发现,app会被立即下架,还是老老实实接入内购吧. 二.注意 内购接入还是比较简单的,苹果提供了专门的框架<StoreKit/StoreKit.h>,只要按照它提供的api进行开发就行.然而,接入的过程还是有需要注意的地方,分别是:漏单处理

iOS开发系列——内购、GameCenter、iCloud、Passbook系统服务开发汇总

社交 Social 现在很多应用都内置“社交分享”功能,可以将看到的新闻.博客.广告等内容分享到微博.微信.QQ.空间等,其实从iOS6.0开始苹果官方就内置了Social.framework专门来实现社交分享功能,利用这个框架开发者只需要几句代码就可以实现内容分享.下面就以一个分享到新浪微博的功能为例来演示Social框架的应用,整个过程分为:创建内容编辑控制器,设置分享内容(文本内容.图片.超链接等),设置发送(或取消)后的回调事件,展示控制器. 程序代码: // // ViewContro

iOS 审核因为“内购”被拒的解决方案!

苹果审核支付功能哪些属于内购哪些不属于内购? 1.首先,我们要知道哪些是产品需要内购,哪些不需要内购: 2.走不走内购,主要看我们付费的产品,是留存在App内使用和操作:还是在App外部使用:比如说:我们付费的视频,答题,游戏中的英雄,道具等都需要走内购,因为这些都是在App内部使用的:而我们付费买的电子产品,衣服,体验卷等之类的商品可以不走内购,因为他们都是实体的物件. 3.如果我们不是内购产品,则用支付宝和微信直接支付是没有问题的,但是一旦我们的产品是内购产品不走内购就会被拒绝!!! 如果我

iOS应用程序内购/内付费

最近应用审核被拒绝了,原因是因为使用了第三方支付,苹果说需要使用到应用内购买.但是查了下相关资料,太杂且不详细,好吧,所以现在自己来写博客咯,把我所知道的一一列出来,可能内容有点乱,大家就将就着些吧 一.创建应用 首先进入苹果的ItunesConnection(https://itunesconnect.apple.com)点击左上角的加号新建一个App应用,点击后该网站会弹出一个信息编辑框,大家只要将上面的信息填充完毕点击save即可在苹果的app平台上拥有一个属于自己的App. 在套装ID的

苹果内购笔记

前提 苹果的开发者证书那边,已经为应用启用App内购,在Xcode更新配置文件 itunes store中的设置 itunes中创建App及其它设置 参考:iOS应用程序内购/内付费(一)  http://blog.csdn.net/shenjie12345678/article/details/40978977   1.一定要同意协议.银行.税务的协议,才能创建有价格的商品,且协议的状态一定要是已经生效 ,一般一两小时内就可以生效 参考:iOS App提交指南-协议.税务和银行业务 2.启用沙

iOS开发之--通讯录、蓝牙、内购、GameCenter、iCloud、Passbook功能开发汇总

前言 iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用系统应用.使用系统服务: 目录 系统应用 系统服务 2.1. 短信与邮件 2.2. 通讯录 2.3. 蓝牙 2.4. 社交 2.5. Game Center 2.6. 应用内购买 2.7. iCloud 2.8. Passbook 1. 系统应用 在开发某些应用时可能希望能够调用iOS系统内置的电话.短信.邮件.浏览

iOS开发系列--通讯录、蓝牙、内购、GameCenter、iCloud、Passbook系统服务开发汇总

--系统应用与系统服务 iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用系统应用.使用系统服务: 调用系统应用 使用系统服务 短信与邮件 通讯录 蓝牙 社交 Game Center 应用内购买 iCloud Passbook 系统应用 在开发某些应用时可能希望能够调用iOS系统内置的电话.短信.邮件.浏览器应用,此时你可以直接使用UIApplication的OpenUR

iOS开发系列通讯录、蓝牙、内购、GameCenter、iCloud、Passbook系统服务开

--系统应用与系统服务 iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用系统应用.使用系统服务:http://www.jinhusns.com/Products/Download/?type=xcj 调用系统应用 使用系统服务 短信与邮件 通讯录 蓝牙 社交 Game Center 应用内购买 iCloud Passbook 目 录 系统应用 在开发某些应用时可能希望能

iOS证书说明和发布内购流程整理

关于证书 1.首先通过钥匙串访问--证书助理--从证书颁发机构请求证书--填写证书信息(邮箱,常用名称,存储到磁盘)--存储为(自定义名称.certSigningReuqest,简称CSR文件,只是为了提交到苹果开发者账号中,然后就没用了)到本地 2.苹果开发者账号中,创建证书(Development和Production)--上传CSR文件--下载证书运行 ( xxx.cer文件) 注意:只有在当前电脑中生成本地生成证书,上传到苹果开发账号,然后下载cer文件运行后,钥匙串中才有证书以及对应的