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í)例一樣長(zhǎng)僚害。如果出現(xiàn)中斷情況硫椰,比如網(wǎng)絡(luò)失敗,那么app將不能完成購買流程贡珊,而相關(guān)的交易仍在支付隊(duì)列中最爬。當(dāng)app正常恢復(fù)后门岔,它將沒有觀察者存在爱致,因?yàn)樵趹?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];
returnYES;
}
// 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∈T溃可以查看Differences Between Product TypesRestoring 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 FunctionalityDelivering 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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蘑斧,隨后出現(xiàn)的幾起案子靖秩,更是在濱河造成了極大的恐慌,老刑警劉巖竖瘾,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沟突,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡捕传,警方通過查閱死者的電腦和手機(jī)惠拭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來庸论,“玉大人职辅,你說我怎么就攤上這事∧羰荆” “怎么了域携?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)鱼喉。 經(jīng)常有香客問我秀鞭,道長(zhǎng),這世上最難降的妖魔是什么扛禽? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任锋边,我火速辦了婚禮,結(jié)果婚禮上编曼,老公的妹妹穿的比我還像新娘豆巨。我一直安慰自己,他們只是感情好灵巧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布搀矫。 她就那樣靜靜地躺著抹沪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瓤球。 梳的紋絲不亂的頭發(fā)上融欧,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音卦羡,去河邊找鬼噪馏。 笑死,一個(gè)胖子當(dāng)著我的面吹牛绿饵,可吹牛的內(nèi)容都是我干的欠肾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拟赊,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼刺桃!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起吸祟,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤瑟慈,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后屋匕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體葛碧,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年过吻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了进泼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纤虽,死狀恐怖乳绕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情廓推,我是刑警寧澤刷袍,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站樊展,受9級(jí)特大地震影響呻纹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜专缠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一雷酪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧涝婉,春花似錦哥力、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽寞射。三九已至,卻和暖如春锌钮,著一層夾襖步出監(jiān)牢的瞬間桥温,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工梁丘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留侵浸,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓氛谜,卻偏偏與公主長(zhǎng)得像掏觉,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子值漫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容