如何做到无耦合插入启动广告

作者: 再见远洋 | 来源:发表于2016-08-09 11:23 被阅读253次

刚好,公司这个版本要加上启动页广告的功能,但是以前没有这个需求,所以一开始就想的是,这个得改原来的业务逻辑了,想想就心烦,直到看到了某一位大神的博客,茅塞顿开,下面说说怎么做到无耦合、不改变原有业务逻辑的情况下加入启动广告,老规矩,先贴代码,后面会给出github地址:

//
//  CMAdvertisement.h
//  Chemucao
//
//  Created by 遇见远洋 on 16/8/8.
//  Copyright © 2016年 CMC_IOS. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface CMAdvertisement : NSObject

@end
//
//  CMAdvertisement.m
//  Chemucao
//
//  Created by 遇见远洋 on 16/8/8.
//  Copyright © 2016年 CMC_IOS. All rights reserved.
//

#import "CMAdvertisement.h"

@interface CMAdvertisement ()
@property (nonatomic, strong) UIWindow* window;
@property (nonatomic, assign) NSInteger downCount;
@property (nonatomic, weak) UIButton* downCountButton;

@end

@implementation CMAdvertisement
///在load 方法中,启动监听,可以做到无注入
+ (void)load
{
    [self shareInstance];
}

+ (instancetype)shareInstance
{
    static id instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        
        ///应用启动, 首次开屏广告
        [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidFinishLaunchingNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
            ///要等DidFinished方法结束后才能初始化UIWindow,不然会检测是否有rootViewController
            dispatch_async(dispatch_get_main_queue(), ^{
                [self checkAD];
            });
        }];
        ///进入后台
        [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
            [self requestNewData];
        }];
        ///后台启动,二次开屏广告
        [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillEnterForegroundNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
            [self checkAD];
        }];
    }
    return self;
}

/**
 *  进入后台再返回时请求信的广告数据
 */
- (void)requestNewData
{
    ///.... 请求新的广告数据
}

/**
 *  检查是否有跟控制器
 */
- (void)checkAD
{
    ///如果有则显示,无则请求, 下次启动再显示。
    ///我们这里都当做有
    [self showImageView];
}

/**
 *  展示启动页广告图片
 */
- (void)showImageView
{
    ///初始化一个Window, 做到对业务视图无干扰。
    UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    
    ///广告布局
    [self setupSubviews:window];
    
    ///设置为最顶层,防止 AlertView 等弹窗的覆盖
    window.windowLevel = UIWindowLevelStatusBar + 1;
    
    ///默认为YES,当你设置为NO时,这个Window就会显示了
    window.hidden = NO;
    
    ///来个渐显动画
    window.alpha = 0;
    [UIView animateWithDuration:0.3 animations:^{
        window.alpha = 1;
    }];
    
    ///防止释放,显示完后  要手动设置为 nil
    self.window = window;
}

/**
 *  初始化显示的视图, 可以挪到具
 *
 *  @param window
 */
- (void)setupSubviews:(UIWindow*)window
{
    ///随便写写
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:window.bounds];
    imageView.image = [UIImage imageNamed:@"garage_default_list_img"];
    imageView.contentMode = UIViewContentModeScaleToFill;
    imageView.userInteractionEnabled = YES;
    
    //给非UIControl的子类,增加点击事件
    UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pushToADViewController)];
    [imageView addGestureRecognizer:tap];
    
    [window addSubview:imageView];
    
    ///增加一个倒计时跳过按钮
    self.downCount = 3;
    
    UIButton * goout = [[UIButton alloc] initWithFrame:CGRectMake(window.bounds.size.width - 100 - 20, 20, 100, 60)];
    [goout setContentHorizontalAlignment:UIControlContentHorizontalAlignmentRight];
    [goout addTarget:self action:@selector(dismissAdImageView) forControlEvents:UIControlEventTouchUpInside];
    [window addSubview:goout];
    
    self.downCountButton = goout;
    [self timer];
}

/**
 *  点击广告跳转页面 这就是你要做的广告页面
 */
- (void)pushToADViewController {
    
}

/**
 *  移除视图
 */
- (void)dismissAdImageView
{
    [self hide];
}

/**
 *  移除视图
 */
- (void)hide
{
    ///来个渐显动画
    [UIView animateWithDuration:0.3 animations:^{
        self.window.alpha = 0;
    } completion:^(BOOL finished) {
        [self.window.subviews.copy enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            [obj removeFromSuperview];
        }];
        self.window.hidden = YES;
        self.window = nil;
    }];
    
}

/**
 *  时间递减到0时移除视图
 */
- (void)timer
{
//    [self.downCountButton setTitle:[NSString stringWithFormat:@"跳过:%ld",(long)self.downCount] forState:UIControlStateNormal];
    if (self.downCount <= 0) {
        [self hide];
    }
    else {
        self.downCount --;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self timer];
        });
    }
}

@end

最后来讲解一下思路:

  • 其实代码里面都已经写的挺详细了,这里还是做一下总结和分析吧,其实关键的点就是,我们只需要任意建一个类,重写 - init{}方法,我们在程序还没有启动的时候都会调用,再加上我们可以通过监听程序是否启动完成(通过通知,代码里可以详细看到),通过监听程序启动是否完毕来判断是否添加广告页面,当然这里的广告页面最好是通过window来做,而且一定要把window的级别提到最高,否则可能会被盖住而看不到,关键代码如下:
- (instancetype)init
{
    self = [super init];
    if (self) {
        
        ///应用启动, 首次开屏广告
        [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidFinishLaunchingNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
            ///要等DidFinished方法结束后才能初始化UIWindow,不然会检测是否有rootViewController
            dispatch_async(dispatch_get_main_queue(), ^{
                [self checkAD];
            });
        }];
        ///进入后台
        [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
            [self requestNewData];
        }];
        ///后台启动,二次开屏广告
        [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillEnterForegroundNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
            [self checkAD];
        }];
    }
    return self;
}

下面给一个demo吧:https://github.com/wxh794708907/YJYYAdvertisementDemo

相关文章

  • 如何做到无耦合插入启动广告

    刚好,公司这个版本要加上启动页广告的功能,但是以前没有这个需求,所以一开始就想的是,这个得改原来的业务逻辑了,想想...

  • RahmenView 类似于一个相框,可以将插入图片(本地及网络

    场景: 业务需要,在app的启动页面做一个模版,可以将广告图片直接插入进去.......适合启动页广告、相框 思...

  • 【思维导图】深入理解HTTPS原理、过程

    我们经常会遇到页面被运营商插入小广告这种事情(数据被篡改),可想而知,HTTP是有多么不安全。 如何做到的? 答:...

  • 记录下Ubuntu安装过程,超简单。

    Ubuntu安装 1、将Ubuntu系统做到U盘上,从U盘启动 2、PC插入U盘,从U盘启动电脑 3、U盘上的系统...

  • 广告插入

    周五放学回家,经过建设路口子,买2个蛋烘糕充饥,女儿看见盒子上的广告词 “带不走的成都味”,自己即兴补了一句“带得...

  • 区块链在广告中的应用

    区块链有助于恢复人们对数字广告购买的信心,为广告商提供更高的透明度,做到明确每个交易涉及哪些参与者,以及如何更加无...

  • iOS启动广告设计与实现

    购物类app、微博、手机百度 打开app的时候经常会出现启动广告。 这个启动广告如何做的呢? 更新机制是什么? 图...

  • 无广告插入

    从简书频繁的锁文,到简书交易贝市场关闭,还有评论被吞掉的现象,反正就是毛病一大堆,但这广告是从来没有停止过的。 会...

  • 作为一名文案狗,是什么体验?

    其实我很难理解在一篇好好的文章里插入一个广告是怎么做到的。很多公司要我在一篇严肃的热点评论硬要插入,真的很难。对于...

  • 耦合

    耦合表示模块之间联系的程度。紧密耦合表示模块之间联系非常强,松散耦合表示模块之间联系比较弱,非耦合则表示模块之间无...

网友评论

    本文标题:如何做到无耦合插入启动广告

    本文链接:https://www.haomeiwen.com/subject/qffdsttx.html