IAP最佳實(shí)踐方法
該文檔是蘋果8月5號(hào)發(fā)布的新Technical Note--In-App Purchase Best Practices,最要描述了iOS 和 OS X 應(yīng)用程序中的IAP的最佳實(shí)踐。
以下是推薦給開發(fā)者的IAP最佳實(shí)踐列表。
在應(yīng)用啟動(dòng)時(shí)添加一個(gè)交易隊(duì)列觀察者
應(yīng)用程序調(diào)用StoreKit把觀察者鏈接到payment queue。
- [SKPaymentQueue defaultQueue] addTransactionObserver:your_observer];
在恢復(fù)或者運(yùn)行你的app應(yīng)用時(shí),如果支付隊(duì)列的內(nèi)容發(fā)生了變化,StoreKit則會(huì)自動(dòng)通知你(注冊(cè)的)觀察者 在應(yīng)用啟動(dòng)時(shí)添加觀察者確保它在所有app啟動(dòng)時(shí)都會(huì)存在,這將允許你的應(yīng)用能接收到所有的payment queue提醒。
考慮應(yīng)用程序這樣一個(gè)情況,在向隊(duì)列(如表1)添加支付請(qǐng)求前,應(yīng)用的 DetailViewController 類創(chuàng)建了一個(gè)觀察者。這個(gè)觀察者的存在時(shí)間和 DetailViewController 實(shí)例一樣長。如果出現(xiàn)中斷情況,比如網(wǎng)絡(luò)失敗,那么app將不能完成購買流程,而相關(guān)的交易仍在支付隊(duì)列中。當(dāng)app正常恢復(fù)后,它將沒有觀察者存在,因 為在應(yīng)用被發(fā)送至后臺(tái)時(shí),上述觀察者就已經(jīng)被解除了。因此,你的應(yīng)用將不會(huì)收到隊(duì)列中的交易通知。
列表 1.不遵循實(shí)現(xiàn)交易觀察者最佳實(shí)踐:當(dāng)用戶嘗試購買產(chǎn)品時(shí),應(yīng)用為 payment queue 添加觀察者:
- @implementation DetailViewController
- ....
- // Called when a customer attempts to purchase a product
- - (IBAction)purchase:(id)sender
- {
- // Register an observer to the payment queue
- [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
- // Create a payment request
- SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:self.product];
- // Submit the payment request to the payment queue
- [[SKPaymentQueue defaultQueue] addPayment:payment];
- }
- ....
- @end
列表 2.遵循注冊(cè)交易觀察者的最佳實(shí)踐
- @implementation AppDelegate
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
- {
- // Attach an observer to the payment queue
- [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
- return YES;
- }
- // Called when the application is about to terminate
- - (void)applicationWillTerminate:(UIApplication *)application
- {
- // Remove the observer
- [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
- }
- ....
- @end
StoreKit 在app調(diào)用時(shí)從payment queue移除觀察者:
同樣,如果沒有從 payment queue 移除觀察者,StoreKit 將會(huì)試圖通知上述觀察者,從而導(dǎo)致應(yīng)用崩潰,好像觀察者已經(jīng)不復(fù)存在了。
在展示應(yīng)用內(nèi)商店UI之前向App Store詢問產(chǎn)品信息
在決定在用戶界面中展示可購買商品之前,你的應(yīng)用必須首先向App Store發(fā)送一個(gè)產(chǎn)品請(qǐng)求。發(fā)送產(chǎn)品請(qǐng)求可讓你確定產(chǎn)品是否可在App Store中出售,從而阻止展示不能購買的產(chǎn)品??刹榭?Retrieving Product Information 學(xué)習(xí)如何創(chuàng)建一個(gè)產(chǎn)品請(qǐng)求。App Store使用 SKResponse 對(duì)象響應(yīng)產(chǎn)品請(qǐng)求,使用其 products 屬性來更新你的UI,以確保你的用戶只能看到App Store中可供銷售的產(chǎn)品。
列表 3.不遵循IAP產(chǎn)品展示最佳實(shí)踐:在展示可銷售產(chǎn)品后, APP向App Store詢問相關(guān)產(chǎn)品信息。
- // App first displays a product for sale, then queries the App Store about it when a customer attempts to purchase it
- - (IBAction)purchase:(id)sender
- {
- // Create a set for your product identifier
- NSSet *productSet = [NSSet setWithObject:@"your_product_identifier"];
- // Create a product request object and initialize it with the above set
- SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:productSet];
- request.delegate = self;
- // Send the request to the App Store
- [request start];
- }
- // Get the App Store's response
- - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
- {
- // No purchase will take place if there are no products available for sale.
- // As a result, StoreKit won't prompt your customer to authenticate their purchase.
- if ([response.products count] > 0)
- {
- SKProduct *product = (SKProduct *)[response.products objectAtIndex:0];
- // The product is available, let's submit a payment request to the queue
- SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
- [[SKPaymentQueue defaultQueue] addPayment:payment];
- }
- }
列表 4. 遵循IAP產(chǎn)品展示最佳實(shí)踐
- -(void)fetchProductInformationForIds:(NSArray *)productIds
- {
- // Create a set for your product identifier
- NSSet *mySet = [NSSet setWithObject:your_product_identifier];
- // Create a product request object and initialize it with the above set
- SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:mySet];
- request.delegate = self;
- // Send the request to the App Store
- [request start];
- }
- //Get the App Store's response
- - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
- {
- if ([response.products count] > 0)
- {
- // Use availableProducts to populate your UI
- NSArray *availableProducts = response.products;
- }
- }
為restoring products提供一個(gè)UI
如果你的應(yīng)用出售 non-consumable、auto-renewable subscription 或者 non-renewing subscription產(chǎn)品,那你必須提供一個(gè)允許恢復(fù)它們的UI??梢圆榭?Differences Between Product Types 和 Restoring Purchased Products 獲得更多信息。
處理交易
調(diào)用 StoreKit 為 payment queue 添加支付請(qǐng)求:
- [[SKPaymentQueue defaultQueue] addPayment:your_payment];
隊(duì)列創(chuàng)建交易對(duì)象來處理這個(gè)請(qǐng)求。當(dāng)交易狀態(tài)改變時(shí),StoreKit通過調(diào)用 paymentQueue: updatedTransactions: 來通知你的觀察者。
In-App Purchase Programming Guide> Delivering Products> Table 4-1 Transaction statuses and corresponding actions 列出了每個(gè)交易可能存在的4種交易狀態(tài)。要確保觀察者的 paymentQueue: updatedTransactions: 可以在任何時(shí)間響應(yīng)這些狀態(tài)。如果IAP產(chǎn)品是由蘋果托管的,那么需在在觀察者上實(shí)現(xiàn) paymentQueue:updatedDownloads: 方法。
提供付費(fèi)內(nèi)容
當(dāng)收到一個(gè)狀態(tài)是 SKPaymentTransactionStatePurchased 或者 SKPaymentTransactionStateRestored 的交易時(shí),應(yīng)用程序?qū)?huì)向用戶交付內(nèi)容或者解鎖app的功能。這些狀態(tài)表明已經(jīng)接收到可售產(chǎn)品的付款。用戶也希望應(yīng)用能提供付費(fèi)內(nèi)容。
如果你的購買產(chǎn)品包括App Store托管內(nèi)容,要確保調(diào)用 SKPaymentQueue's startDownloads: 下載內(nèi)容??刹榭?Unlocking App Functionality 和 Delivering Associated Content 獲得更多信息。
完成交付
交易將會(huì)保存在支付隊(duì)列中直到它們被移除。每次啟動(dòng)應(yīng)用或者從后臺(tái)恢復(fù)時(shí),StoreKit將會(huì)調(diào)用觀察者的 paymentQueue: updatedTransactions: 直到它們被移除。大意是你的用戶可能反復(fù)請(qǐng)求驗(yàn)證它們的購買,或者被阻止購買你的產(chǎn)品。
調(diào)用 finishTransaction: 從隊(duì)列中移除交易。完成的交易是不可恢復(fù)的,因此你務(wù)必提供內(nèi)容,下載所有蘋果托管的產(chǎn)品內(nèi)容,或者在完成交易前完成你的購買流程。查看 Finishing the Transaction 獲得更多信息。
測(cè)試IAP的實(shí)現(xiàn)
要確保在把應(yīng)用提交審核之前徹底測(cè)試IAP的實(shí)現(xiàn)??稍?Suggested Testing Steps 查看多測(cè)試場(chǎng)景,在 Frequently Asked Questions 查看各種疑難解答。
參考:
In-App Purchase Programming Guide
Adding In-App Purchase to your iOS and OS X Applications
WWDC 2012: Selling Products with Store Kit
WWDC 2012: Managing Subscriptions with In-App Purchase
WWDC 2013: Using Store Kit for In-App Purchases
WWDC 2014: Optimizing In-App Purchases
本文鏈接:http://www.cocoachina.com/applenews/devnews/2014/0818/9407.html