• iOS IAP教程


    1. 创建应用

    首先进入iTunes Connect然后按下 Manage Your Applications


    接下来按下Add New Applicationbutton创建应用

    2. 在应用中创建IAP


    创建应用之后,在Manage Your Applications中点应用的图示,进入应用

    就会看到上图画面点击Manage In App Purchases就能够进入IAP的管理画面

    在这边要注意左边的Bundle ID,在Xcode项目中,info.plist中的设定需与此Bundle同样

    (此Bundle ID会在创建应用时填入)

    此为IAP的管理画面,仅仅要按下Create Newbutton就可创建IAP

    在本图中我已经创建好三个IAP

    而当中要注意的是Product ID,仅仅要用Product ID就能够请求IAP的相关讯息及交易

    Consumable

    消耗品,每次下载都需付费

    Non-Consumable

    一次性付费,通经常使用在升级pro版或是移除广告等

    Auto-Renewable Subscriptions

    自己主动更新订阅

    Free Subscription

    免费订阅

    Non-Renewing Subscription

    自己主动更新订阅

    3. 怎样创建沙盒測试用户

    进入iTunes Connect,点击Manage Users

    在这个画面中点下Test User

    按下Add New User就能够了Email Address就是登入沙盒測试的username

    password的部份在Add New User时可自行创建

    4.代码

    /*
     *  CBiOSStoreManager.h
     *  CloudBox Cross-Platform Framework Project
     *
     *  Created by Cloud on 2012/10/30.
     *  Copyright 2011 Cloud Hsu. All rights reserved.
     *
     */
    
    #import <UIKit/UIKit.h> 
    #import <StoreKit/StoreKit.h>
    
    @interface CBiOSStoreManager : NSObject<SKProductsRequestDelegate,SKPaymentTransactionObserver>
    {
        NSString* _buyProductIDTag;
    }
    
    + (CBiOSStoreManager*) sharedInstance;
    
    - (void) buy:(NSString*)buyProductIDTag;
    - (bool) CanMakePay;
    - (void) initialStore;
    - (void) releaseStore;
    - (void) requestProductData:(NSString*)buyProductIDTag;
    - (void) provideContent:(NSString *)product;
    - (void) recordTransaction:(NSString *)product;
    
    - (void) requestProUpgradeProductData:(NSString*)buyProductIDTag;
    - (void) paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions;
    - (void) purchasedTransaction: (SKPaymentTransaction *)transaction;
    - (void) completeTransaction: (SKPaymentTransaction *)transaction;
    - (void) failedTransaction: (SKPaymentTransaction *)transaction;
    - (void) paymentQueueRestoreCompletedTransactionsFinished: (SKPaymentTransaction *)transaction;
    - (void) paymentQueue:(SKPaymentQueue *) paymentQueue restoreCompletedTransactionsFailedWithError:(NSError *)error;
    - (void) restoreTransaction: (SKPaymentTransaction *)transaction;
    
    @end

    /*
     *  CBiOSStoreManager.mm
     *  CloudBox Cross-Platform Framework Project
     *
     *  Created by Cloud on 2012/10/30.
     *  Copyright 2011 Cloud Hsu. All rights reserved.
     *
     */
    
    #import "CBiOSStoreManager.h"
    
    @implementation CBiOSStoreManager
    
    static CBiOSStoreManager* _sharedInstance = nil;
    
    +(CBiOSStoreManager*)sharedInstance
    {
    	@synchronized([CBiOSStoreManager class])
    	{
    		if (!_sharedInstance)
    			[[self alloc] init];
            
    		return _sharedInstance;
    	}
    	return nil;
    }
    
    +(id)alloc
    {
    	@synchronized([CBiOSStoreManager class])
    	{
    		NSAssert(_sharedInstance == nil, @"Attempted to allocate a second instance of a singleton.
    ");
    		_sharedInstance = [super alloc];
    		return _sharedInstance;
    	}
    	return nil;
    }
    
    -(id)init {
    	self = [super init];
    	if (self != nil) {
    		// initialize stuff here
    	}
    	return self;
    }
    
    -(void)initialStore
    {
        [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    }
    -(void)releaseStore
    {
        [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
    }
    
    -(void)buy:(NSString*)buyProductIDTag
    {
        [self requestProductData:buyProductIDTag];
    }
    
    -(bool)CanMakePay
    {
        return [SKPaymentQueue canMakePayments];
    }   
    
    -(void)requestProductData:(NSString*)buyProductIDTag
    {
        NSLog(@"---------Request product information------------
    ");
        _buyProductIDTag = [buyProductIDTag retain];
        NSArray *product = [[NSArray alloc] initWithObjects:buyProductIDTag,nil];
        NSSet *nsset = [NSSet setWithArray:product];
        SKProductsRequest *request=[[SKProductsRequest alloc] initWithProductIdentifiers: nsset];
        request.delegate=self;
        [request start];
        [product release];
    }
    
    - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{   
        
        NSLog(@"-----------Getting product information--------------
    ");
        NSArray *myProduct = response.products;
        NSLog(@"Product ID:%@
    ",response.invalidProductIdentifiers);
        NSLog(@"Product count: %d
    ", [myProduct count]);
        // populate UI
        for(SKProduct *product in myProduct){
            NSLog(@"Detail product info
    ");
            NSLog(@"SKProduct description: %@
    ", [product description]);
            NSLog(@"Product localized title: %@
    " , product.localizedTitle);
            NSLog(@"Product localized descitption: %@
    " , product.localizedDescription);
            NSLog(@"Product price: %@
    " , product.price);
            NSLog(@"Product identifier: %@
    " , product.productIdentifier);
        }
        SKPayment *payment = nil;
        payment = [SKPayment paymentWithProduct:[response.products objectAtIndex:0]];
        NSLog(@"---------Request payment------------
    ");
        [[SKPaymentQueue defaultQueue] addPayment:payment];
        [request autorelease];    
        
    }
    - (void)requestProUpgradeProductData:(NSString*)buyProductIDTag
    {
        NSLog(@"------Request to upgrade product data---------
    ");
        NSSet *productIdentifiers = [NSSet setWithObject:buyProductIDTag];
        SKProductsRequest* productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
        productsRequest.delegate = self;
        [productsRequest start];    
        
    }
    
    - (void)request:(SKRequest *)request didFailWithError:(NSError *)error
    {
        NSLog(@"-------Show fail message----------
    ");
        UIAlertView *alerView =  [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Alert",NULL) message:[error localizedDescription]
                                                           delegate:nil cancelButtonTitle:NSLocalizedString(@"Close",nil) otherButtonTitles:nil];
        [alerView show];
        [alerView release];
    }   
    
    -(void) requestDidFinish:(SKRequest *)request
    {
        NSLog(@"----------Request finished--------------
    ");
        
    }   
    
    -(void) purchasedTransaction: (SKPaymentTransaction *)transaction
    {
        NSLog(@"-----Purchased Transaction----
    ");
        NSArray *transactions =[[NSArray alloc] initWithObjects:transaction, nil];
        [self paymentQueue:[SKPaymentQueue defaultQueue] updatedTransactions:transactions];
        [transactions release];
    }    
    
    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
    {
        NSLog(@"-----Payment result--------
    ");
        for (SKPaymentTransaction *transaction in transactions)
        {
            switch (transaction.transactionState)
            {
                case SKPaymentTransactionStatePurchased:
                    [self completeTransaction:transaction];
                    NSLog(@"-----Transaction purchased--------
    ");
                    UIAlertView *alerView =  [[UIAlertView alloc] initWithTitle:@"Congratulation"
                                                                  message:@"Transaction suceed!"
                                                                  delegate:nil cancelButtonTitle:NSLocalizedString(@"Close",nil) otherButtonTitles:nil];   
                    
                    [alerView show];
                    [alerView release];
                    break;
                case SKPaymentTransactionStateFailed:
                    [self failedTransaction:transaction];
                    NSLog(@"-----Transaction Failed--------
    ");
                    UIAlertView *alerView2 =  [[UIAlertView alloc] initWithTitle:@"Failed"
                                                                   message:@"Sorry, your transcation failed, try again."
                                                                   delegate:nil cancelButtonTitle:NSLocalizedString(@"Close",nil) otherButtonTitles:nil];   
                    
                    [alerView2 show];
                    [alerView2 release];
                    break;
                case SKPaymentTransactionStateRestored:
                    [self restoreTransaction:transaction];
                    NSLog(@"----- Already buy this product--------
    ");
                case SKPaymentTransactionStatePurchasing:
                    NSLog(@"-----Transcation puchasing--------
    ");
                    break;
                default:
                    break;
            }
        }
    }
    
    - (void) completeTransaction: (SKPaymentTransaction *)transaction   
    {
        NSLog(@"-----completeTransaction--------
    ");
        // Your application should implement these two methods.
        NSString *product = transaction.payment.productIdentifier;
        if ([product length] > 0) {   
            
            NSArray *tt = [product componentsSeparatedByString:@"."];
            NSString *bookid = [tt lastObject];
            if ([bookid length] > 0) {
                [self recordTransaction:bookid];
                [self provideContent:bookid];
            }
        }   
        
        // Remove the transaction from the payment queue.   
        [[SKPaymentQueue defaultQueue] finishTransaction: transaction];   
        
    }   
    
    -(void)recordTransaction:(NSString *)product
    {
        NSLog(@"-----Record transcation--------
    ");
        // Todo: Maybe you want to save transaction result into plist.
    }   
    
    -(void)provideContent:(NSString *)product
    {
        NSLog(@"-----Download product content--------
    ");
    }   
    
    - (void) failedTransaction: (SKPaymentTransaction *)transaction
    {
        NSLog(@"Failed
    ");
        if (transaction.error.code != SKErrorPaymentCancelled)
        {
        }
        [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
    }
    -(void) paymentQueueRestoreCompletedTransactionsFinished: (SKPaymentTransaction *)transaction
    {   
        
    }
    
    - (void) restoreTransaction: (SKPaymentTransaction *)transaction
    {
        NSLog(@"-----Restore transaction--------
    ");
    }
    
    -(void) paymentQueue:(SKPaymentQueue *) paymentQueue restoreCompletedTransactionsFailedWithError:(NSError *)error
    {
        NSLog(@"-------Payment Queue----
    ");
    }
    
    #pragma mark connection delegate
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
    {
        NSLog(@"%@
    ",  [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]);
    }
    - (void)connectionDidFinishLoading:(NSURLConnection *)connection
    {   
        
    }   
    
    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
    {
        switch([(NSHTTPURLResponse *)response statusCode]) {
            case 200:
            case 206:
                break;
            case 304:
                break;
            case 400:
                break;
            case 404:
                break;
            case 416:
                break;
            case 403:
                break;
            case 401:
            case 500:
                break;
            default:
                break;
        }
    }   
    
    - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
    {
        NSLog(@"test
    ");
    }   
    
    -(void)dealloc
    {
        [super dealloc];
    }
    
    @end


    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    因为交易是永久有效的,建议addTransactionObserver这个于应用启动后即可监听,而不要在用户想买东西时才监听

    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
    交易结果会于此处显示

    苹果准备沙盒測试环境需一段时间,若是创建IAP后能够取得资讯,却无法交易成功,要稍待一下

    另外若是模拟器能够购买,但真机购买却失败的话,做Hard Reset就能够了,一直按住Home键跟电源键就能够做Hard Reset

    按住后会出现关机画面,不要理会它,继续等,直到等到白苹果出现后,就能够放开等重开机完成后再測试

    5. IAP运作流程图

    6.范例下载

    下载连结

  • 相关阅读:
    常用浏览器内核
    点透问题及解决
    移动端click延迟和tap事件
    CommandoVM-虚拟机映像文件 | VM打开直接用
    Crackme006
    CrackMe005-下篇 | 逆向破解分析 | 160个CrackMe(视频+图文)深度解析系列
    拼多多被薅-谈网络安全中最后的屏障
    一次VB汇编中看-溢出计算
    CM005-逆向分析过程(上篇)
    CrackMe-005全破详解(图文+源码)--上篇
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4079168.html
Copyright © 2020-2023  润新知