內(nèi)購

zhun#1.通過蘋果應(yīng)用程序商店有三種主要賺錢的方式:
(1)直接收費(fèi)(與國內(nèi)大部分用戶的消費(fèi)習(xí)慣相悖)
(2)廣告
O2O -> Online推廣 & Offline交易,閉環(huán)
不要砍功能议双,增加內(nèi)容,而不是增加功能
(3)內(nèi)購:應(yīng)用程序本身的增值產(chǎn)品,游戲裝備,應(yīng)用程序中增值功能同樣可以內(nèi)購
第三方支付:跟應(yīng)用程序無關(guān)的
內(nèi)購:三(蘋果)七(開發(fā)商)開

2.內(nèi)購的五種產(chǎn)品類別

(1)非消耗品(Nonconsumable)一旦購買肺素,終身擁有
指的是在游戲中一次性購買并擁有永久訪問權(quán)的物品或服務(wù)。非消耗品物品可以被用戶再次下載宇驾,并且能夠在用戶的所有設(shè)備上共享
(2)消耗品(Consumable)倍靡,買了就用,用了就沒
消耗品購買不可被再次下載课舍,根據(jù)其特點(diǎn)菌瘫,消耗品不能在用戶的設(shè)備之間跨設(shè)備使用,除非自定義服務(wù)在用戶的賬號(hào)之間共享這些信息

以下三種類別在iBooks中使用布卡,目前iBooks不支持大陸市場
ISBN:每本書的一個(gè)ID
(3)免費(fèi)訂閱(Free subscriptions)
(4)自動(dòng)續(xù)費(fèi)訂閱(Auto-renewing subscriptions)
(5)非自動(dòng)續(xù)費(fèi)訂閱(Nonrenewing subscriptions)

3.內(nèi)購流程

屏幕快照 2017-06-23 下午8.52.39.png
屏幕快照 2017-06-23 下午8.53.58.png

4.要使用內(nèi)購雨让,需要導(dǎo)入StoreKit框架

5.內(nèi)購的常用方法

(1)請求有效的產(chǎn)品代號(hào)集合

// 1) 實(shí)例化產(chǎn)品請求
SKProductsRequest *request = [[SKProductsRequest alloc]initWithProductIdentifiers:identifiers];
// 2) 設(shè)置代理
[request setDelegate:self];

// 3) 啟動(dòng)請求
[request start];

提示:

  1. 實(shí)例化請求時(shí),必須指定有效的identifiers集合忿等,之所以如此處理栖忠,主要是為了確保提交的內(nèi)購商品真的通過了蘋果的審批,處于可用狀態(tài)贸街!
  2. 要想獲取到準(zhǔn)確的可用產(chǎn)品集合庵寞,需要通過代理方法實(shí)現(xiàn)
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response

3 . 越獄用戶無法測試內(nèi)購,但是可以購買

(2)購買指定產(chǎn)品

  1. 內(nèi)購的交易過程是通過SKPaymentTransactionObserver監(jiān)控的薛匪,因此需要為IAPHelper添加交易觀察者:
// 添加交易觀察者對象
[[SKPaymentQueue defaultQueue]addTransactionObserver:sharedInstance];
  1. 由于發(fā)起交易需要使用SKProduct對象捐川,因此需要使用字典記錄所有可用的商品
NSMutableDictionary         *_productsDict;

(3)驗(yàn)證購買(在購買完成之后,驗(yàn)證)

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    for (SKPaymentTransaction *transaction in transactions) {
        // 購買完成
            if (transaction.transactionState == SKPaymentTransactionStatePurchased) {
            NSLog(@"購買完成 %@", transaction.payment.productIdentifier);

            [queue finishTransaction:transaction];
        } else if (transaction.transactionState == SKPaymentTransactionStateFailed) {
            if (transaction.error.code != SKErrorPaymentCancelled) {
                NSLog(@"交易失斠菁狻: %@", transaction.error.localizedDescription);
            }
        }
    }
}

(4)恢復(fù)購買(針對非消耗品)

[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];

購買數(shù)據(jù)記錄問題——系統(tǒng)偏好

[[NSUserDefaults standardUserDefaults]setBool:isPurchased forKey:productId];
[[NSUserDefaults standardUserDefaults]synchronize];

案例

#import "ViewController.h"
#import <StoreKit/StoreKit.h>

@interface ViewController () <SKProductsRequestDelegate, UITableViewDataSource, UITableViewDelegate, SKPaymentTransactionObserver>

/** 所有的商品的數(shù)組 */
@property (nonatomic, strong) NSArray *products;

- (IBAction)restore:(id)sender;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 去自己的服務(wù)器請求所有想賣商品的ProductIds
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"iapdemo.plist" ofType:nil];
    NSArray *productArray = [NSArray arrayWithContentsOfFile:filePath];
    NSArray *productIdArray = [productArray valueForKeyPath:@"productId"];
    
    // 去蘋果服務(wù)器請求可賣的商品
    NSSet *productIdSet = [NSSet setWithArray:productIdArray];
    SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdSet];
    request.delegate = self;
    [request start];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    
    // 3.添加觀察者(代理是一對一的關(guān)系/觀察者一對多)
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    
    // 移除觀察者
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}

#pragma mark - 實(shí)現(xiàn)SKProductsRequest的代理方法
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    // 展示商品
    self.products = [response.products sortedArrayWithOptions:NSSortConcurrent usingComparator:^NSComparisonResult(SKProduct *obj1, SKProduct *obj2) {
        return [obj1.price compare:obj2.price];
    }];
    
    // 2.刷新表格
    [self.tableView reloadData];
}

#pragma mark - 實(shí)現(xiàn)tableView的數(shù)據(jù)源和代理方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.products.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"ProductCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
    }
    
    // 1.取出模型
    SKProduct *product = self.products[indexPath.row];
    
    // 2.給cell設(shè)置數(shù)據(jù)
    cell.textLabel.text = product.localizedTitle;
    cell.detailTextLabel.text = [NSString stringWithFormat:@"價(jià)格:%@", product.price];
    
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 1.取出模型
    SKProduct *product = self.products[indexPath.row];
    
    // 2.購買商品
    [self buyProduct:product];
}

#pragma mark - 購買商品
- (void)buyProduct:(SKProduct *)product
{
    // 1.創(chuàng)建票據(jù)
    SKPayment *payment = [SKPayment paymentWithProduct:product];
    
    // 2.將票據(jù)加入到交易隊(duì)列中
    [[SKPaymentQueue defaultQueue] addPayment:payment];
}

#pragma mark - 實(shí)現(xiàn)SKPaymentQueue的回調(diào)方法
/*
 隊(duì)列中的交易發(fā)生改變時(shí),就會(huì)調(diào)用該方法
 */
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    /*
     SKPaymentTransactionStatePurchasing,    正在購買
     SKPaymentTransactionStatePurchased,     已經(jīng)購買(購買成功)
     SKPaymentTransactionStateFailed,        購買失敗
     SKPaymentTransactionStateRestored,      恢復(fù)購買
     SKPaymentTransactionStateDeferred       未決定
     */
    for (SKPaymentTransaction *transation in transactions) {
        switch (transation.transactionState) {
            case SKPaymentTransactionStatePurchasing:
                NSLog(@"用戶正在購買");
                break;
                
            case SKPaymentTransactionStatePurchased:
                NSLog(@"購買成功,將對應(yīng)的商品給用戶");
                
                // 將交易從交易隊(duì)列中移除
                [queue finishTransaction:transation];
                break;
                
            case SKPaymentTransactionStateFailed:
                NSLog(@"購買失敗,告訴用戶沒有付錢成功");
                
                // 將交易從交易隊(duì)列中移除
                [queue finishTransaction:transation];
                break;
                
            case SKPaymentTransactionStateRestored:
                NSLog(@"恢復(fù)商品,將對應(yīng)的商品給用戶");
                // transation.payment.productIdentifier
                // 將交易從交易隊(duì)列中移除
                [queue finishTransaction:transation];
                break;
                
            case SKPaymentTransactionStateDeferred:
                NSLog(@"未決定");
                break;
            default:
                break;
        }
    }
}

#pragma mark - 恢復(fù)購買
- (IBAction)restore:(id)sender {
    [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
@end

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末古沥,一起剝皮案震驚了整個(gè)濱河市瘸右,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌岩齿,老刑警劉巖太颤,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異盹沈,居然都是意外死亡龄章,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進(jìn)店門乞封,熙熙樓的掌柜王于貴愁眉苦臉地迎上來做裙,“玉大人,你說我怎么就攤上這事肃晚」接茫” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵陷揪,是天一觀的道長惋鸥。 經(jīng)常有香客問我,道長悍缠,這世上最難降的妖魔是什么卦绣? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮飞蚓,結(jié)果婚禮上滤港,老公的妹妹穿的比我還像新娘。我一直安慰自己趴拧,他們只是感情好溅漾,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著著榴,像睡著了一般添履。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上脑又,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天暮胧,我揣著相機(jī)與錄音,去河邊找鬼问麸。 笑死往衷,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的严卖。 我是一名探鬼主播席舍,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼哮笆!你這毒婦竟也來了来颤?” 一聲冷哼從身側(cè)響起汰扭,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎脚曾,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體启具,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡本讥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鲁冯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拷沸。...
    茶點(diǎn)故事閱讀 40,505評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖薯演,靈堂內(nèi)的尸體忽然破棺而出撞芍,到底是詐尸還是另有隱情,我是刑警寧澤跨扮,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布序无,位于F島的核電站,受9級特大地震影響衡创,放射性物質(zhì)發(fā)生泄漏帝嗡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一璃氢、第九天 我趴在偏房一處隱蔽的房頂上張望哟玷。 院中可真熱鬧,春花似錦一也、人聲如沸巢寡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抑月。三九已至,卻和暖如春舆蝴,著一層夾襖步出監(jiān)牢的瞬間爪幻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工须误, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留挨稿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓京痢,卻偏偏與公主長得像奶甘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子祭椰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評論 2 359

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