詳解iOS應(yīng)用程序內(nèi)購/內(nèi)付費(fèi)(一)
很久之前就想出一篇iOS內(nèi)付費(fèi)的教程,但是一查網(wǎng)上的教程實在太多了,有的寫得真的蠻不錯的,就心想算了,于是就保存在草稿箱了。至于為什么寫完它呢!真是說來話長,最近公司有個項目經(jīng)理跑來問我有關(guān)蘋果內(nèi)付費(fèi)相關(guān)的細(xì)節(jié),跟他聊了半天,從項目對接蘋果官方支付接口聊到了如何查看App收益,最后終于使他有了一些眉目,但是悲催的是還要我繼續(xù)去跟他們項目的程序員講解(真是瘋了),所以我就決定給他們項目寫一個內(nèi)購的文檔,所以我順便把這篇博客完成吧!
首先進(jìn)入蘋果的ItunesConnection(https://itunesconnect.apple.com)點擊左上角的加號新建一個App應(yīng)用,點擊后該網(wǎng)站會彈出一個信息編輯框,大家只要將上面的信息填充完畢點擊save即可在蘋果的app平臺上擁有一個屬于自己的App。
在套裝ID的上,需要提前為該App申請一個AppID以及BundleID,只要是申請成功了就會在選擇列表中顯示出來。
這里順便多說一句這個ItunesConnect是用來干嘛的,它是蘋果公司給個人或企業(yè)提供管理自己App的一個平臺。在這個平臺上開發(fā)者可以新建,刪除和管理自己的App應(yīng)用,開發(fā)者可以根據(jù)需求對App應(yīng)用進(jìn)行上架與下架,編輯App信息,生成測試app所需的信息,例如賬號,邀請碼等,還有就是我們今天要講的內(nèi)付費(fèi)功能。當(dāng)然啦,他的功能可不止我講的這些,我大致說一下這個平臺的作用,如果你經(jīng)常跟它打交道的話就會慢慢熟悉了。
接下來,我就來為大家演示一下如何添加付費(fèi)道具,首先打開iTunesConnect,顯示如下頁面:
選擇紅圈所圈起來的選項,然后將里面的相關(guān)信息補(bǔ)充完畢,如果缺少這一步,內(nèi)購功能是不會成功的。
假如你已經(jīng)完成了上述相關(guān)銀行賬戶的設(shè)置,就點擊你的App,選擇上面標(biāo)題欄中的"App 內(nèi)購買項目"
隨后點擊左上角的 "create new"選項,如下圖所示,進(jìn)入到下一個界面:
這個界面是讓你選擇消費(fèi)道具的種類,現(xiàn)在改版的網(wǎng)站是有簡體中文翻譯的,所以不像以前打開一看都不知道選哪一個,甚至都不知道每個代表的什么意思(比如我第一次遇到的時候,在領(lǐng)導(dǎo)面前真是囧)。它的種類分為如下幾種:
一般對項目來說大多數(shù)都是選擇“消耗型項目”這個種類,比如游戲中購買金幣,寶石balabala~之類的,選中之后就會到這個界面中來:
在上圖所示的編輯框中輸入,商品名稱,產(chǎn)品ID以及價格等級,在這邊說明一下:
1.商品名稱根據(jù)你的消費(fèi)道具的實際意義來說明,比如“100顆寶石”,“100金幣”等。
2.產(chǎn)品ID是比較重要的,由項目自定義,只要唯一即可,像我一般都是用App的bundleID加一個后綴來表示,這樣既跟項目關(guān)聯(lián)又具有唯一性。
3.價格等級的話“查看價格表”中有對應(yīng)的說明,可以對照著表中每個國家的貨幣價格與等級來選擇。
我們繼續(xù),在這個網(wǎng)頁的接下來部分如圖所示:
選擇添加語言選項,彈出一個編輯頁面:
點擊save保存,則會在界面上顯示成如下:
最后一步就是點擊“選取文件”提交一張?zhí)O果它指定像素(640*920)的商品圖片,當(dāng)他上傳完畢后點擊“save”按鈕,我們這第二部分就大工告成了。提交的商品最后會在內(nèi)購的頁面上顯示為如圖:
這個圖是我在已經(jīng)發(fā)布的app上面截取的,添加了3個商品,已經(jīng)是通過的的狀態(tài)了(顯示綠色),當(dāng)您剛提交的時候,因為通過蘋果的審查需要一段時間所以會顯示黃色的等待狀態(tài),所以不必?fù)?dān)心是不是商品編輯錯了。如圖:
這部分,我主要給大家演示一下,如何申請測試賬號,利用蘋果的沙盒測試環(huán)境來模擬AppStore的購買流程。
在ItunesConnect中選擇“用戶和職能”選項~
隨后在左上角的選項中選擇沙盒測試者,點擊左上角的加號圖標(biāo)增加一位測試者,如圖:
編輯好相應(yīng)的內(nèi)容,點擊保存,就創(chuàng)建了一個測試賬號,是不是很簡單?。‘?dāng)然這個賬號如果你忘記了密碼可以重新生成一個,無關(guān)緊要。
順帶多句嘴,不要在正式的appstore上面用沙盒測試的賬號來登錄,千萬要牢記在心,此賬號只用于測試環(huán)境下~
接下來就是代碼部分啦~
1.首先在項目工程中加入“storekit.framework”,加入頭文件#import <StoreKit/StoreKit.h>
2.在.h文件中加入“SKPaymentTransactionObserver,SKProductsRequestDelegate”監(jiān)聽機(jī)制
下面貼上內(nèi)購的核心代碼,就幾個函數(shù),我在這邊就不在做更多詳細(xì)的解釋了,各位看官可以運(yùn)行跑一下就一目了然了。
.h文件
// // PaymentViewController.h // IAPPayTest // // Created by silicon on 14-10-28. // Copyright (c) 2014年 silicon. All rights reserved. // #import <UIKit/UIKit.h> #import <StoreKit/StoreKit.h> @interface PaymentViewController : UIViewController<SKPaymentTransactionObserver,SKProductsRequestDelegate> @property (strong, nonatomic) IBOutlet UITextField *productID; @property (strong, nonatomic) IBOutlet UIButton *purchase; - (IBAction)purchaseFunc:(id)sender; @end
.m文件
// // PaymentViewController.m // IAPPayTest // // Created by silicon on 14-10-28. // Copyright (c) 2014年 silicon. All rights reserved. // #import "PaymentViewController.h" @interface PaymentViewController () @end @implementation PaymentViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; self.productID.text = @"com.games.ztyxs.product_point.1"; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (IBAction)purchaseFunc:(id)sender { NSString *product = self.productID.text; if([SKPaymentQueue canMakePayments]){ [self requestProductData:product]; }else{ NSLog(@"不允許程序內(nèi)付費(fèi)"); } } //請求商品 - (void)requestProductData:(NSString *)type{ NSLog(@"-------------請求對應(yīng)的產(chǎn)品信息----------------"); NSArray *product = [[NSArray alloc] initWithObjects:type, nil nil]; NSSet *nsset = [NSSet setWithArray:product]; SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset]; request.delegate = self; [request start]; } //收到產(chǎn)品返回信息 - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{ NSLog(@"--------------收到產(chǎn)品反饋消息---------------------"); NSArray *product = response.products; if([product count] == 0){ NSLog(@"--------------沒有商品------------------"); return; } NSLog(@"productID:%@", response.invalidProductIdentifiers); NSLog(@"產(chǎn)品付費(fèi)數(shù)量:%d",[product count]); SKProduct *p = nil; for (SKProduct *pro in product) { NSLog(@"%@", [pro description]); NSLog(@"%@", [pro localizedTitle]); NSLog(@"%@", [pro localizedDescription]); NSLog(@"%@", [pro price]); NSLog(@"%@", [pro productIdentifier]); if([pro.productIdentifier isEqualToString:self.productID.text]){ p = pro; } } SKPayment *payment = [SKPayment paymentWithProduct:p]; NSLog(@"發(fā)送購買請求"); [[SKPaymentQueue defaultQueue] addPayment:payment]; } //請求失敗 - (void)request:(SKRequest *)request didFailWithError:(NSError *)error{ NSLog(@"------------------錯誤-----------------:%@", error); } - (void)requestDidFinish:(SKRequest *)request{ NSLog(@"------------反饋信息結(jié)束-----------------"); } //監(jiān)聽購買結(jié)果 - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction{ for(SKPaymentTransaction *tran in transaction){ switch (tran.transactionState) { case SKPaymentTransactionStatePurchased: NSLog(@"交易完成"); break; case SKPaymentTransactionStatePurchasing: NSLog(@"商品添加進(jìn)列表"); break; case SKPaymentTransactionStateRestored: NSLog(@"已經(jīng)購買過商品"); break; case SKPaymentTransactionStateFailed: NSLog(@"交易失敗"); break; default: break; } } } //交易結(jié)束 - (void)completeTransaction:(SKPaymentTransaction *)transaction{ NSLog(@"交易結(jié)束"); [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; } - (void)dealloc{ [[SKPaymentQueue defaultQueue] removeTransactionObserver:self]; [super dealloc]; } @end
代碼就這么多,到這邊我們的IOS內(nèi)購教程就接近尾聲了,在測試的時候還有幾點因素要注意一下:
1.沙盒環(huán)境測試appStore內(nèi)購流程的時候,請使用沒越獄的設(shè)備。
2.請務(wù)必使用真機(jī)來測試,一切以真機(jī)為準(zhǔn)。
3.項目的Bundle identifier需要與您申請AppID時填寫的bundleID一致,不然會無法請求到商品信息。
講了這么多,附上幾張測試截屏給大家展示一下:
請求商品時的打印日志:
交易成功后:
手機(jī)截屏:
要求輸入AppStore帳密,使用測試生成的即可:
確定購買:
交易完成:
當(dāng)我們的交易完成后還要去appstore 上面去驗證票據(jù)信息是否正確,這樣我們才可以給玩家發(fā)放道具,apple官方文檔:
//交易結(jié)束 - (void)completeTransaction:(SKPaymentTransaction *)transaction{ NSLog(@"交易結(jié)束"); //交易驗證 NSURL *recepitURL = [[NSBundle mainBundle] appStoreReceiptURL]; NSData *receipt = [NSData dataWithContentsOfURL:recepitURL]; if(!receipt){ } NSError *error; NSDictionary *requestContents = @{ @"receipt-data": [receipt base64EncodedStringWithOptions:0] }; NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents options:0 error:&error]; if (!requestData) { /* ... Handle error ... */ } //In the test environment, use https://sandbox.itunes.apple.com/verifyReceipt //In the real environment, use https://buy.itunes.apple.com/verifyReceipt // Create a POST request with the receipt data. NSURL *storeURL = [NSURL URLWithString:@"https://buy.itunes.apple.com/verifyReceipt"]; NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL]; [storeRequest setHTTPMethod:@"POST"]; [storeRequest setHTTPBody:requestData]; // Make a connection to the iTunes Store on a background queue. NSOperationQueue *queue = [[NSOperationQueue alloc] init]; [NSURLConnection sendAsynchronousRequest:storeRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { if (connectionError) { /* ... Handle error ... */ } else { NSError *error; NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; if (!jsonResponse) { /* ... Handle error ...*/ } /* ... Send a response back to the device ... */ //Parse the Response } }]; [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; }
好了,所有的內(nèi)購流程基本上講完了,原諒我在圖片上的涂抹,因為關(guān)系到產(chǎn)品的敏感詞匯所以希望大家能夠不介意。以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
iOS開發(fā)實現(xiàn)搜索框(UISearchController)
這篇文章主要為大家詳細(xì)介紹了iOS開發(fā)實現(xiàn)搜索框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-08-08iOS開發(fā)技巧之狀態(tài)欄字體顏色的設(shè)置方法
有時候我們需要根據(jù)不同的背景修改狀態(tài)欄字體的顏色,下面這篇文章主要給大家介紹了關(guān)于iOS開發(fā)技巧之狀態(tài)欄字體顏色的設(shè)置方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧2018-08-08iOS 判斷頁面中的該填項是否填完整,改變按鈕狀態(tài)的方法
下面小編就為大家分享一篇iOS 判斷頁面中的該填項是否填完整,改變按鈕狀態(tài)的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01IOS中快速集成短信SDK驗證開發(fā)(SMSSDK),IOS開發(fā)中如何設(shè)置手機(jī)短信驗證碼
這篇文章主要介紹了IOS中快速集成短信SDK驗證開發(fā)(SMSSDK),IOS開發(fā)中如何設(shè)置手機(jī)短信驗證碼 的相關(guān)資料,需要的朋友可以參考下2016-01-01