我所說的內購——也可以說是應用內購買
定義好的商品
#define kIAPBomb @"airplay.10bombs"
#define kIAPBullet @"airplay.laserBullet"
1. 實例化請求時,必須指定有效的identifiers集合,之所以如此處理,主要是為了確保提交的內購商品真的通過了蘋果的審批,處于可用狀態!
2. 要想獲取到準確的可用產品集合,需要通過代理方法實現
- (void)PRoductsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
3. 越獄用戶無法測試內購,但是可以購買
1 @interface ITViewController () <SKProductsRequestDelegate, SKPaymentTransactionObserver>2 {3 // 產品字典4 NSMutableDictionary *_productDict;5 }
1 - (void)viewDidLoad2 {3 [super viewDidLoad];4 5 [self requestProducts];6 7 // 設置購買隊列的監聽器8 [[SKPaymentQueue defaultQueue] addTransactionObserver:self];9 }
#pragma mark 詢問蘋果的服務器能夠銷售哪些商品- (void)requestProducts{ // 能夠銷售的商品 NSSet *set = [[NSSet alloc] initWithObjects:kIAPBomb, kIAPBullet, nil]; // "異步"詢問蘋果能否銷售 SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:set]; request.delegate = self; // 啟動請求 [request start];}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{ if (_productDict == nil) { _productDict = [NSMutableDictionary dictionaryWithCapacity:response.products.count]; } for (SKProduct *product in response.products) { // 激活了對應的銷售操作按鈕,相當于商店的商品上架允許銷售 NSLog(@"%@", product.productIdentifier); if ([product.productIdentifier isEqualToString:kIAPBullet]) { _bulletButton.enabled = YES; } if ([product.productIdentifier isEqualToString:kIAPBomb]) { _bombButton.enabled = YES; } // 填充商品字典 [_productDict setObject:product forKey:product.productIdentifier]; }}
1 #pragma mark - 用戶決定購買商品 2 - (void)buyProduct:(SKProduct *)product 3 { 4 // 要購買產品(店員給用戶開了個小票) 5 SKPayment *payment = [SKPayment paymentWithProduct:product]; 6 7 // // 設置購買隊列的監聽器 8 // [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 9 10 // 去收銀臺排隊,準備購買(異步網絡)11 [[SKPaymentQueue defaultQueue] addPayment:payment];12 }
1 - (IBAction)purchaseProducts2 {3 [self buyProduct:_productDict[kIAPBullet]];4 }5 6 - (IBAction)purchaseBomb:(id)sender7 {8 [self buyProduct:_productDict[kIAPBomb]];9 }
#pragma mark - SKPaymentTransaction Observer#pragma mark 購買隊列狀態變化- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{ // 調試 for (SKPaymentTransaction *transaction in transactions) { NSLog(@"隊列狀態變化 %@", transaction); // 如果小票狀態是購買完成 if (SKPaymentTransactionStatePurchased == transaction.transactionState) { NSLog(@"購買完成 %@", transaction.payment.productIdentifier); // 更新界面或者數據,把用戶購買得商品交給用戶 // ... // 驗證購買憑據 [self verifyPruchase]; // 將交易從交易隊列中刪除 [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; } else if (SKPaymentTransactionStateRestored == transaction.transactionState) { NSLog(@"恢復成功 %@", transaction.payment.productIdentifier); // 更新界面或者數據,把用戶購買得商品交給用戶 // ... // 將交易從交易隊列中刪除 [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; } }}
#pragma mark - 恢復商品- (void)restorePurchase{ // 恢復已經完成的所有交易.(僅限永久有效商品) [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];}
1 #pragma mark 驗證購買憑據 2 - (void)verifyPruchase 3 { 4 // 驗證憑據,獲取到蘋果返回的交易憑據 5 // appStoreReceiptURL iOS7.0增加的,購買交易完成后,會將憑據存放在該地址 6 NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL]; 7 // 從沙盒中獲取到購買憑據 8 NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL]; 9 10 // 發送網絡POST請求,對購買憑據進行驗證11 NSURL *url = [NSURL URLWithString:ITMS_SANDBOX_VERIFY_RECEIPT_URL];12 // 國內訪問蘋果服務器比較慢,timeoutInterval需要長一點13 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0f];14 15 request.HTTPMethod = @"POST";16 17 // 在網絡中傳輸數據,大多情況下是傳輸的字符串而不是二進制數據18 // 傳輸的是BASE64編碼的字符串19 /**20 BASE64 常用的編碼方案,通常用于數據傳輸,以及加密算法的基礎算法,傳輸過程中能夠保證數據傳輸的穩定性21 BASE64是可以編碼和解碼的22 */23 NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];24 25 NSString *payload = [NSString stringWithFormat:@"{/"receipt-data/" : /"%@/"}", encodeStr];26 NSData *payloadData = [payload dataUsingEncoding:NSUTF8StringEncoding];27 28 request.HTTPBody = payloadData;29 30 // 提交驗證請求,并獲得官方的驗證JSON結果31 NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];32 33 // 官方驗證結果為空34 if (result == nil) {35 NSLog(@"驗證失敗");36 }37 38 NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:result options:NSJSONReadingAllowFragments error:nil];39 40 NSLog(@"%@", dict);41 42 if (dict != nil) {43 // 比對字典中以下信息基本上可以保證數據安全44 // bundle_id&application_version&product_id&transaction_id45 NSLog(@"驗證成功");46 }47 }
1.蘋果APP(商家)——— 2.告訴蘋果Store服務器要賣的商品 ——— 3.蘋果審核完(告訴你是否可以賣)
4.用戶(買商品)——— 5.蘋果APP(商家)——— 6.開發票給(用戶)————
7.用戶(拿著發票去蘋果Store服務器付款)——8.付款成功(用戶在APP里獲得服務商品)
(注意:如果要模擬測試內購,需要用真機才可以測試)
作者: 清澈Saup
出處: http://www.49028c.com/qingche/
本文版權歸作者和博客園共有,歡迎轉載,但必須保留此段聲明,且在文章頁面明顯位置給出原文連接。
新聞熱點
疑難解答