zoukankan      html  css  js  c++  java
  • IOS,苹果内购和添加广告

    内购——应用内购买

    通过苹果应用程序商店有三种主要赚钱的方式:
    直接收费(与国内大部分用户的消费习惯相悖)
    广告(降低用户体验 应用程序名称带Lite可以添加广告)
    O2O -> Online推广 & Offline交易,闭环
    不要砍功能,增加内容,而不是增加功能
    内购:应用程序本身的增值产品,游戏装备,应用程序中增值功能同样可以内购
    第三方支付:跟应用程序无关的
    内购分成:三(苹果)七(开发商)开
     
    提示:
    要做好游戏 & 应用,一定要研究心理,要研究哲学
    人人都是产品经理
     
    内购的五种产品类别
    非消耗品(Nonconsumable)一旦购买,终身拥有
      指的是在游戏中一次性购买并拥有永久访问权的物品或服务。非消耗品物品可以被用户再次下载,并且能够在用户的所有设备上使用
    消耗品(Consumable),买了就用,用了就没
      专为支持可消耗的物品或服务设计的,消耗品购买不可被再次下载,根据其特点,消耗品不能在用户的设备之间跨设备使用,除非自定义服务在用户的账号之间共享这些信息
     
    以下三种类别在iBooks中使用,目前iBooks不支持大陆市场
    ISBN:每本书的一个ID
    免费订阅(Free subscriptions)
    自动续费订阅(Auto-renewing subscriptions)
    非自动续费订阅(Nonrenewing subscriptions)
     

    准备工作:

    在Itunes  添加应用   设置 apppurese  内购的 道具

    并且制定每一个道具的名称跟 产品 ID

    bundleID:  唯一的 

    必须是真机: 要求  不能越狱

    添加测试账号:  (不花钱   苹果提供一个 沙盒 专门用来测试内购 

    注意点: 不能是苹果真的 账号 

    1> 内购程序的APP ID需要单独指定,因为在开发时,需要独立测试,通过苹果的网站进行交互

    2> iTunes Connect中添加可以销售的商品

    3> 中间有一个审批的过程,之后就可以在应用程序中添加

    4> 注册Sandbox(使用测试服务器的)用户,同样具备苹果ID的能力

    苹果官方有限定,不能用测试账号在苹果真正市场消费,一旦有消费行为,就会被禁用

    5> 在应用程序信息中,填写测试账号和密码,方便审核人员测试!

     

    开发前的注意事项:

     

    1> 要开发内购,必须用真机

    2> 真机一定不能越狱

    3> BundlID 和服务器上的 App ID要一致,靠AppID来识别具体的消费

     

    对于非消耗品,需要增加一个恢复购买的功能,提示:会一次性恢复所有的购买的非消耗品

     

    要使用内购,需要导入StoreKit框架

    内购的常用方法

    请求有效的产品代号集合
    购买指定产品
    验证购买(在购买完成之后,验证)
    恢复购买(针对非消耗品)
     
    请求有效产品集合

    // 1) 实例化产品请求

    SKProductsRequest *request = [[SKProductsRequest alloc]initWithProductIdentifiers:identifiers];

    // 2) 设置代理

    [request setDelegate:self];

    // 3) 启动请求

    [request start];

    提示:

    1. 实例化请求时,必须指定有效的identifiers集合,之所以如此处理,主要是为了确保提交的内购商品真的通过了苹果的审批,处于可用状态!

    2. 要想获取到准确的可用产品集合,需要通过代理方法实现

    - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response

    3. 越狱用户无法测试内购,但是可以购买

    购买产品

    1. 内购的交易过程是通过SKPaymentTransactionObserver监控的,因此需要为IAPHelper添加交易观察者:

    // 添加交易观察者对象

    [[SKPaymentQueue defaultQueue]addTransactionObserver:sharedInstance];

    2. 由于发起交易需要使用SKProduct对象,因此需要使用字典记录所有可用的商品

    NSMutableDictionary*_productsDict;

    交易队列回调方法

    - (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);

                }

            }

        }

    }

    恢复购买

    [[SKPaymentQueue defaultQueue]restoreCompletedTransactions];

    验证购买

    #if DEBUG

        #define ITMS_VERIFY_RECEIPT_URL             @"https://sandbox.itunes.apple.com/verifyReceipt"

    #else

        #define ITMS_VERIFY_RECEIPT_URL             @"https://buy.itunes.apple.com/verifyReceipt"

    #endif

    --------------------------------------------------------------------------------------------------------------------

    完整步骤代码:

    #import "ViewController.h"

    #import <StoreKit/StoreKit.h>

    @interface ViewController ()<SKProductsRequestDelegate,SKPaymentTransactionObserver>

     

    //产品

    @property (nonatomic,strong)NSArray *allProducts;

     

    @end

     

    @implementation ViewController

     

    - (void)viewDidLoad {

        [super viewDidLoad];

        

        //1.请求可销售的商品列表

        

        //准备自己需要销售的商品列表

        

        NSString *path = [[NSBundle mainBundle]pathForResource:@"products.json" ofType:nil];

        

        NSData *data = [NSData dataWithContentsOfFile:path];

        

        NSArray *arrayList = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];

        

        NSArray *arrayIdList = [arrayList valueForKeyPath:@"productId"];

        

        NSLog(@"%@",arrayIdList);

        

        NSSet *set = [NSSet setWithArray:arrayIdList];

        

        //创建一个请求对象

        SKProductsRequest *request = [[SKProductsRequest alloc]initWithProductIdentifiers:set];

        request.delegate = self;

        [request start];

     

        //6.创建监听对象 来监听交易队列中的交易对象的交易状态

        

        [[SKPaymentQueue defaultQueue]addTransactionObserver:self];

        

     

    }

     

    - (void)dealloc

    {

        //移除监听对象

        [[SKPaymentQueue defaultQueue]removeTransactionObserver:self];

    }

     

    #pragma mark - SKProductsRequestDelegate

    /**

     *  返回可销售的商品列表

     *

     *  @param request  请求对象

     *  @param response 返回数据

     */

    - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response

    {

        for (SKProduct *product in response.products) {

            

            NSLog(@"%@  %@  %@ %@",product.localizedTitle,product.localizedDescription,product.price,product.productIdentifier);

       

        }

        

        self.allProducts = response.products;

        

        //刷新表格

        [self.tableView reloadData];

        

    }

     

    /**

     *      //2.展示可销售的商品

     *

     *  @param tableView <#tableView description#>

     *  @param section   <#section description#>

     *

     *  @return <#return value description#>

     */

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    {

        return  self.allProducts.count;

    }

     

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

        static NSString *ID = @"cell";

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];

        

        if (cell == nil) {

            cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];

        }

        //取模型

        SKProduct *product = self.allProducts[indexPath.row];

        cell.textLabel.text = product.localizedTitle;

        cell.detailTextLabel.text = [NSString stringWithFormat:@"%@",product.price];

        

        return cell;

    }

     

     

    //3.点击购买

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    {

        //4.开具小票

        SKProduct *pro = self.allProducts[indexPath.row];

        //小票 创建一个交易

        SKPayment *payment = [SKPayment paymentWithProduct:pro];

        

        //5.创建交易对象并添加到交易队列

        [[SKPaymentQueue defaultQueue]addPayment:payment];

        

    }

     

     

    #pragma mark -SKPaymentTransactionObserver

    /**

     *  监听到交易队列中交易状态改变的时候就会调用

     *

     *  @param queue        队列

     *  @param transactions 在队列交易

     */

    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

    {

        //非消耗品  才能被恢复购买

        /*

         SKPaymentTransactionStatePurchasing,    交易正在被添加到交易队列  

         SKPaymentTransactionStatePurchased,     //交易已经在队列,用户已经付钱,客户端需要完成交易

         SKPaymentTransactionStateFailed,        //还没添加到队列中就取消或者失败了

         SKPaymentTransactionStateRestored,      // 交易被恢复购买,客户端需要完成交易

         SKPaymentTransactionStateDeferred NS_ENUM_AVAILABLE_IOS(8_0),   交易在队列中,交易状态不确定依赖别的参数参与

         */

        

        //7.如果交易状态购买成功  提供特殊服务

        

        for (SKPaymentTransaction *t in transactions) {

            

            if (t.transactionState == SKPaymentTransactionStatePurchased) {

                NSLog(@"购买成功提供增值");

                //结束交易完成

                [[SKPaymentQueue defaultQueue]finishTransaction:t];

            }else if (t.transactionState == SKPaymentTransactionStateRestored) {

                NSLog(@"恢复购买成功!");

                //结束交易完成

                [[SKPaymentQueue defaultQueue]finishTransaction:t];

            }

            

        }

        //测试账户

        //huijidazhan@126.com

        //密码

        //Yinuohanlei001

        

    }

    /**

     *  恢复 非消耗品的购买  从用户的交易记录

     *

     *  @param sender <#sender description#>

     */

    - (IBAction)retoreProduct:(UIBarButtonItem *)sender {

        

        [[SKPaymentQueue defaultQueue]restoreCompletedTransactions];

        

    }

     

    @end

     

    -------------------------------------------------------------------------------------------------------------

    广告:

     

    广告收益三七开
    添加 iAd.framework 框架
    添加 ADBannerView 视图,并设置代理方法
    广告条加载完成之前最好隐藏

    - (void)bannerViewDidLoadAd:(ADBannerView *)banner {

        self.bannerBottomConstraint.constant = 20.0;   

        [UIView animateWithDuration:0.5 animations:^{

            [self.view layoutIfNeeded];

        }];   

        NSLog(@"加载广告成功");

    }

    - (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {

        NSLog(@"加载广告失败 %@", error);

    ---------------------------------------------------------------------------------------------------

    广告完整代码

    #import "ViewController.h"

    #import <iAd/iAd.h>

    @interface ViewController ()<ADBannerViewDelegate>

    @property (weak, nonatomic) IBOutlet NSLayoutConstraint *cons;

     

    @end

     

    @implementation ViewController

    - (void)bannerViewDidLoadAd:(ADBannerView *)banner

    {

        self.cons.constant = 50;

     

        //显示完整广告条

        [UIView animateWithDuration:2.0 animations:^{

            

            [self.view layoutIfNeeded];

            

        }];

    }

    - (void)viewDidLoad {

        [super viewDidLoad];

        //1>3    7

        //2>根据用户的应用的分类  //自动推送

        

        //广告什么时候加载完毕

     

        

    }

     

     

    @end

     

     

  • 相关阅读:
    VS中生成时“sgen.exe”已退出,代码为 1解决办法
    配置 influxDB 鉴权及 HTTP API 写数据的方法
    InfluxDB 的UTC时间问题与简单的持续查询语句
    C# 中HttpClient的使用中同步异步问题
    Action<T> Delegate
    Task Class
    .net4.0、.net4.5、.net4.6 三者对系统的要求
    vue 组件动态 循环
    js 取得当天0点 / 23:59:59 时间
    vue中element-ui树形控件自定义节点,注意一下
  • 原文地址:https://www.cnblogs.com/AgentLXJ/p/4642525.html
Copyright © 2011-2022 走看看