http://blog.csdn.net/pengyuan_D/article/details/47340083?locationNum=7
//
// SWStoreKit.swift
// NirvanaIOS
//
// Created by yaohongmin on 2017/11/30.
// Copyright © 2017年 nirvana. All rights reserved.
//
/*
*/
import Foundation
import StoreKit
public class SWStoreKit:UIViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver{
public static let shared = SWStoreKit()
deinit {
SKPaymentQueue.default().remove(self)
}
// record
var productIdentifier:String?
var paycallbackUrl:String?
public typealias funcSuccCallback = () ->()
var succCallback:funcSuccCallback!
//
func showAlert(content: String) {
let alert = UIAlertView()
alert.title = "Tips"
alert.message = content
alert.addButton(withTitle: "Ok")
alert.show()
}
// request
public func pay(productIdentifier:String, succCallback:@escaping funcSuccCallback){
print("[swift storekit pay]", productIdentifier)
self.productIdentifier = productIdentifier
self.succCallback = succCallback
// start request product info
SKPaymentQueue.default().add(self)
let productArray = NSArray(objects: productIdentifier)
let productBundleIdentifier = NSSet(array: productArray as! [Any])
let request = SKProductsRequest.init(productIdentifiers: productBundleIdentifier as! Set<String> )
request.delegate = self
request.start()
}
// request product info callback
public func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
print("[NirvanaStoreKit.productsRequest]")
let products = response.products
// check if request product info failed.
if (products.count == 0){
self.showAlert(content: "request product info failed.")
print("request product info failed. ")
let invalidProductIdentifiers = response.invalidProductIdentifiers
for product in invalidProductIdentifiers {
print("invaild product ", product)
}
return
}
// request product info success
print("request product info success")
//
var paymentProduct:SKProduct? = nil
for product in products {
print("description=\(product.description), localizedTitle=\(product.localizedTitle), localizedDescription=\(product.localizedDescription), price=\(product.price), productIdentifier=\(product.productIdentifier)")
if product.productIdentifier == self.productIdentifier {
paymentProduct = product
}
}
if paymentProduct == nil {
print("not find match product identifier.")
self.showAlert(content: "not find match product identifier.")
return
}
// request buy
let payment = SKPayment(product: paymentProduct!)
print("request payment")
SKPaymentQueue.default().add(payment)
}
//
public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
print("[sdk paymentQueue]")
for transaction in transactions {
print("transaction.transactionState = ", transaction.transactionState.rawValue)
switch transaction.transactionState{
case .purchased:
print("purchased")
self.completeTransaction(transaction: transaction)
SKPaymentQueue.default().finishTransaction(transaction)
break
case .purchasing:
print("purchasing")
break
case .restored:
print("restored")
SKPaymentQueue.default().finishTransaction(transaction)
break
case .failed:
print("failed ",transaction.error?.localizedDescription)
SKPaymentQueue.default().finishTransaction(transaction)
break
default:
break
}
}
}
func completeTransaction(transaction:SKPaymentTransaction){
print("[sdk completeTransaction]")
self.verifyPurchase(transaction, isSandbox: false)
}
func verifyPurchase(_ transaction:SKPaymentTransaction, isSandbox:Bool){
print("[sdk verify purchase] isSandBox = \(isSandbox)")
let receiptUrl = Bundle.main.appStoreReceiptURL
let receiptData = try! Data(contentsOf: receiptUrl!)
#if DEBUG
print("receipturl = ", receiptUrl)
#endif
let encodeStr = receiptData.base64EncodedString(options: Data.Base64EncodingOptions.endLineWithLineFeed)
let sendString = String("{\"receipt-data\":\"\(encodeStr)\"}")
//https://sandbox.itunes.apple.com/verifyReceipt
//https://buy.itunes.apple.com/verifyReceipt
var url = URL(string:"https://buy.itunes.apple.com/verifyReceipt")
if isSandbox {
url = URL(string:"https://sandbox.itunes.apple.com/verifyReceipt")
}
let postData = sendString?.data(using: String.Encoding.utf8)
let request = NSMutableURLRequest(url: url!, cachePolicy: NSURLRequest.CachePolicy.useProtocolCachePolicy, timeoutInterval: 50)
request.httpMethod = "POST"
request.httpBody = postData
let queue = OperationQueue()
NSURLConnection.sendAsynchronousRequest(request as URLRequest, queue: queue) { (response:URLResponse?, data:Data?, error:Error?) in
if (error != nil) {
self.showAlert(content: "verify failed")
} else {
let jsonResponse = try! JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions(rawValue: JSONSerialization.ReadingOptions.RawValue(0))) as! Dictionary<String, Any>
#if DEBUG
print("!! response = ", jsonResponse)
#endif
let status = jsonResponse["status"] as! NSNumber
if status == 21007 {
print("to sandbox")
self.verifyPurchase(transaction, isSandbox: true)
return
}
self.succCallback()
}
}
}
}