3
每當我構建一個adhoc構建並在ios 11上運行它時,它會彈出消息「需要登錄 - 輸入***** [Environment:Sandbox]的密碼」。因此,這繼續像循環激活而不會消失。嘗試從iCloud發出也沒有工作。我inAppPurchase代碼如下。登錄所需的環境沙盒問題
class InAppPurchase: NSObject,SKProductsRequestDelegate,
SKPaymentTransactionObserver {
///Singleton
private static var inappPurChase:InAppPurchase?;
public static var shared:InAppPurchase {
if inappPurChase == nil{
inappPurChase = InAppPurchase()
}
return inappPurChase!
}
override private init() {
//Singleton complete
}
////////////
var productsList = [SKProduct]()
var productToPurchase = SKProduct()
var productID = ""
let PURCHASE_ID_PREFIX = ""//"com.purelightbeta."
var onInAppPurchaseSuccess: (()->Void)? = nil
var onInAppPurchaseError: (()->Void)? = nil
var onNoProductsIDs: (()->Void)? = nil
var appEnvironment: ((String,Bool)->Void)? = nil
var onReceiptVarificationError: (()->Void)? = nil
var onRestorePurchaseError: ((String)->Void)? = nil
var onRestoreProductsIDs: ((NSMutableArray)->Void)? = nil
public func initPayment (productID: String) {
self.productID = PURCHASE_ID_PREFIX + productID
print("Initializing Purchase Product ID: \(self.productID)")
if SKPaymentQueue.canMakePayments() {
let productID: NSSet = NSSet(objects: self.productID)
let request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set<String>)
request.delegate = self
request.start()
}else {
print("In App Purchases not enabled")
}
}
func buyProduct() {
let payment = SKPayment(product: productToPurchase)
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().add(payment as SKPayment)
}
public func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
let myProducts = response.products
print(myProducts)
productsList = []
if myProducts.count == 0 {
print("No products")
if(onNoProductsIDs != nil){
onNoProductsIDs!()
}
}
for product in myProducts {
print("Prod Details :\(product.productIdentifier) \(product.price) \(product.localizedDescription)")
productsList.append(product)
}
for product in productsList {
let productID = product.productIdentifier
if productID == self.productID {
productToPurchase = product
buyProduct()
}
}
}
func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
let productIDs: NSMutableArray = []
for trasacton in queue.transactions {
if trasacton.transactionState == SKPaymentTransactionState.restored
{
let t: SKPaymentTransaction = trasacton as SKPaymentTransaction
let prodID = t.payment.productIdentifier as String
print("prodID:",prodID)
//let appStoreId = prodID.components(separatedBy: "com.purelightbeta.")
productIDs.add(prodID)
SKPaymentQueue .default().finishTransaction(trasacton)
}
}
if onRestoreProductsIDs != nil {
print(productIDs)
onRestoreProductsIDs! (productIDs)
}
}
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction: AnyObject in transactions {
let trans = transaction as! SKPaymentTransaction
print(trans.error ?? "No in app error")
switch trans.transactionState {
case .purchased:
print("buy ok, AIP unlocked for item :", productToPurchase.productIdentifier)
let productID = productToPurchase.productIdentifier
switch productID {
case self.productID:
print("Item found")
// startValidatingReceipt()
default:
print("Item not found")
}
queue.finishTransaction(trans)
if self.onInAppPurchaseSuccess != nil {
self.onInAppPurchaseSuccess!()
self.startValidatingReceipt()
}
case .failed:
print("buy error")
if self.onInAppPurchaseError != nil {
self.onInAppPurchaseError!()
}
queue.finishTransaction(trans)
break
case .restored:
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
// break
default:
print("default")
break
}
}
}
func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) {
print("ERROR: \(error.localizedDescription)")
if onRestorePurchaseError != nil {
onRestorePurchaseError! (error.localizedDescription)
}
}
func restorePurchase() {
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().restoreCompletedTransactions()
}
func startValidatingReceipt() {
if let isExists = try? self.getReceiptURL()?.checkResourceIsReachable(), isExists == true {
do {
let data = try Data(contentsOf: self.getReceiptURL()!)
// self.startValidatingData(data: data)
self.sendReceiptToLocalServer(data: data)
}catch {
let appReceiptRefreshRequest = SKReceiptRefreshRequest(receiptProperties: nil)
appReceiptRefreshRequest.delegate = self
appReceiptRefreshRequest.start()
}
}else {
print("No receipt for this purchase")
}
}
func getReceiptURL() -> URL? {
return Bundle.main.appStoreReceiptURL
}
enum receiptValidationURLs:String {
case sandbox = "https://sandbox.itunes.apple.com/verifyReceipt"
case production = "https://buy.itunes.apple.com/verifyReceipt"
static var url:URL{
if isDebug {
return URL.init(string: self.sandbox.rawValue)!
}else{
return URL.init(string: self.production.rawValue)!
}
}
}
func sendReceiptToLocalServer(data:Data) {
let base64encodedReceipt = data.base64EncodedString()
if self.appEnvironment != nil {
self.appEnvironment! (base64encodedReceipt,isDebug)
}
}
func startValidatingData(data:Data){
let base64encodedReceipt = data.base64EncodedString()
print(base64encodedReceipt)
let requestDictionary = ["receipt-data":base64encodedReceipt]
guard JSONSerialization.isValidJSONObject(requestDictionary) else { print("requestDictionary is not valid JSON"); return }
do {
let requestData = try JSONSerialization.data(withJSONObject: requestDictionary)
// let validationURLString = "https://sandbox.itunes.apple.com/verifyReceipt" // this works but as noted above it's best to use your own trusted server
NSLog("The Environment is: %@", receiptValidationURLs.url.absoluteString)
guard let validationURL = URL(string: receiptValidationURLs.url.absoluteString) else { print("the validation url could not be created, unlikely error"); return }
let session = URLSession(configuration: URLSessionConfiguration.default)
var request = URLRequest(url: validationURL)
request.httpMethod = "POST"
request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringCacheData
let task = session.uploadTask(with: request, from: requestData) { (data, response, error) in
if let data = data , error == nil {
do {
let appReceiptJSON = try JSONSerialization.jsonObject(with: data)
print((appReceiptJSON as AnyObject).count)
print("success. here is the json representation of the app receipt: \(appReceiptJSON)")
NSLog("Receipt is: %@", appReceiptJSON as! NSDictionary)
if let environment = (appReceiptJSON as? NSDictionary)?["environment"]{
if self.appEnvironment != nil {
self.appEnvironment! (environment as? String ?? "No value",isDebug)
}
}
} catch let error as NSError {
print("json serialization failed with error: \(error)")
}
} else {
print("the upload task returned an error: \(error)")
}
}
task.resume()
} catch let error as NSError {
print("json serialization failed with error: \(error)")
}
}
// func requestDidFinish(_ request: SKRequest) {
// // a fresh receipt should now be present at the url
// do {
//
//
//
// } catch {
// // still no receipt, possible but unlikely to occur since this is the "success" delegate method
// }
// }
func request(_ request: SKRequest, didFailWithError error: Error) {
print("app receipt refresh request did fail with error: \(error)")
// for some clues see here: https://samritchie.net/2015/01/29/the-operation-couldnt-be-completed-sserrordomain-error-100/
if self.onReceiptVarificationError != nil {
self.onReceiptVarificationError!()
}
}
}
請問您可以在這裏發佈您的IAP代碼...我認爲您的觀察員處理過程中出現問題 – AlexWoe89
代碼已更新並已發佈 – danu