需求

很多app(如淘宝、美团等)在启动图加载完毕后,还会显示几秒的广告,一般都有个跳过按钮可以跳过这个广告,有的app在点击广告页之后还会进入一个广告页面,点击返回进入首页。虽然说这个广告页面对用户体验来说并不是很好,但是如果真的有这个需求,我们还是要想办法去开发,至少这比内嵌广告要友善的多。今天我们就来开发一个广告页面,效果如下。

效果图.gif

思路

1.广告页加载思路。广告页的内容要实时显示,在无网络状态或者网速缓慢的情况下不能延迟加载,或者等到首页出现了再加载广告页。所以这里我不采用网络请求广告接口获取图片地址,然后加载图片的方式,而是先将图片异步下载到本地,并保存图片名,每次打开app时先根据本地存储的图片名查找沙盒中是否存在该图片,如果存在,则显示广告页。

2.判断广告页面是否更新。无论本地是否存在广告图片,每次启动都需要重新调用广告接口,根据图片名称或者图片id等方法判断广告是否更新,如果获取的图片名称或者图片id跟本地存储的不一致,则需要重新下载新图片,并删除旧图片。

3.广告页点击。如果点击广告需要跳转广告详情页面,那么广告链接地址也需要用NSUserDefaults存储。注意:广告详情页面是从首页push进去的。

4.广告页的显示代码可以放在AppDeleate中,也可以放在首页的控制器中。如果代码是在AppDelegate中,可以通过发送通知的方式,让首页push到广告详情页。

5.广告页面的底部和启动图的底部一般都是相同的,给我们的感觉就是启动图加载完之后把广告图放在了启动图上,而且不能有偏差,比如下图淘宝启动画面。美工在制作广告图的时候要注意这点。

淘宝启动.gif

6.研究了一下淘宝的广告显示机制,删除淘宝之后重新打开不会显示广告图片,第二次打开才会显示。美团的广告图有时候显示有时候不显示,所以后台在开发广告api的时候可以增加一个字段来判断是否启用广告,如果后台关闭了广告,将沙盒中的图片删除即可。

步骤

1.判断沙盒中是否存在广告图片,如果存在,直接显示

1
2
3
4
5
6
7
NSString *filePath = [self getFilePathWithImageName:[kUserDefaults valueForKey:adImageName]];
BOOL isExist = [self isFileExistWithFilePath:filePath];
if (isExist) {// 图片存在
AdvertiseView *advertiseView = [[AdvertiseView alloc] initWithFrame:self.window.bounds];
advertiseView.filePath = filePath;
[advertiseView show];
}

2.无论沙盒中是否存在广告图片,都需要重新调用获取广告接口,判断广告是否更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
AFHTTPRequestOperationManager * manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/html", nil];
[manager GET:urlStr parameters:nil success:^(AFHTTPRequestOperation * _Nonnull operation, id  _Nonnull responseObject) {
NSArray *dataArray = responseObject[@"data"];
NSString *imageUrl = dataArray[0][@"imageUrl"];
NSArray *stringArr = [imageUrl componentsSeparatedByString:@"/"];
NSString *imageName = stringArr.lastObject;
NSString *filePath = [self getFilePathWithImageName:imageName];
BOOL isExist = [self isFileExistWithFilePath:filePath];
if (!isExist){// 如果该图片不存在,则下载新图片,删除老图片
[self downloadAdImageWithUrl:imageUrl imageName:imageName];
}
} failure:^(AFHTTPRequestOperation * _Nullable operation, NSError * _Nonnull error) {
}];

异步下载图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
*  下载新图片
*/
- (void)downloadAdImageWithUrl:(NSString *)imageUrl imageName:(NSString *)imageName
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];
UIImage *image = [UIImage imageWithData:data];
NSString *filePath = [self getFilePathWithImageName:imageName]; // 保存文件的名称
if ([UIImagePNGRepresentation(image) writeToFile:filePath atomically:YES]) {// 保存成功
NSLog(@"保存成功");
[self deleteOldImage];// 保存成功后删除旧图片
[kUserDefaults setValue:imageName forKey:adImageName];
[kUserDefaults synchronize];
// 如果有广告链接,需要将广告链接也保存下来
}else{
NSLog(@"保存失败");
}
});
}
/**
*  删除旧图片
*/
- (void)deleteOldImage
{
NSString *imageName = [kUserDefaults valueForKey:adImageName];
if (imageName) {
NSString *filePath = [self getFilePathWithImageName:imageName];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:filePath error:nil];
}
}

3.广告页面的跳过按钮倒计时功能可以通过定时器或者GCD实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// GCD倒计时
- (void)startCoundown
{
__block int timeout = showtime + 1; //倒计时时间 + 1
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
dispatch_source_set_timer(_timer,dispatch_walltime(NULL, 0),1.0 * NSEC_PER_SEC, 0); //每秒执行
dispatch_source_set_event_handler(_timer, ^{
if(timeout <= 0){ //倒计时结束,关闭
dispatch_source_cancel(_timer);
dispatch_async(dispatch_get_main_queue(), ^{
[self dismiss];
});
}else{
dispatch_async(dispatch_get_main_queue(), ^{
[_countBtn setTitle:[NSString stringWithFormat:@"跳过%d",timeout] forState:UIControlStateNormal];
});
timeout--;
}
});
dispatch_resume(_timer);
}

4.为广告页面添加一个点击手势,跳转到广告页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//AdvertiseView.m
- (void)pushToAd{
[self dismiss];
[[NSNotificationCenter defaultCenter] postNotificationName:@"pushtoad" object:nil userInfo:nil];
}
// ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"首页";
self.view.backgroundColor = [UIColor orangeColor];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pushToAd) name:@"pushtoad" object:nil];
}
- (void)pushToAd {
AdvertiseViewController *adVc = [[AdvertiseViewController alloc] init];
[self.navigationController pushViewController:adVc animated:YES];
}

完整代码下载地址

http://download.csdn.net/detail/hbblzjy/9564652

推荐文章:http://www.jianshu.com/p/e52806516139

关于App启动加载广告页面思路的更多相关文章

  1. App启动加载广告页面思路

    需求 很多app(如淘宝.美团等)在启动图加载完毕后,还会显示几秒的广告,一般都有个跳过按钮可以跳过这个广告,有的app在点击广告页之后还会进入一个广告页面,点击返回进入首页.今天我们就来开发一个广告 ...

  2. App 启动加载广告页面思路

    需求 很多app(如淘宝.美团等)在启动图加载完毕后,还会显示几秒的广告,一般都有个跳过按钮可以跳过这个广告,有的app在点击广告页之后还会进入一个广告页面,点击返回进入首页.今天我们就来开发一个广告 ...

  3. PhoneGap 白名单安全机制 navigator.app 加载外部页面返回以及退出介绍

    一. Phonegap 白名单安全机制 Phonegap应用的页面大多存在于本地,但有时需要加载外部的Web页面到应用内置的浏览器 视图中已完成特定的应用功能,出于安全性考虑,PhoneGap 设立了 ...

  4. iOS-APP启动页加载广告

    概述 加载广告页, 展现跳过按钮实现倒计时功能, 并判断广告页面是否更新. 详细 代码下载:http://www.demodashi.com/demo/10698.html 目前市场上很多APP(如淘 ...

  5. iOSAPP启动时实现加载广告

    现在很多APP在启动的时候都在加载广告,现在也很流行,主要是盈利啊.笔者也做了很多关于广告的事情.现在记录下自己在APP启动的时候,怎么加载广告的. 下面总结下广告加载的三种方式 1.现在很多APP的 ...

  6. AngularJS进阶(三十九)基于项目实战解析ng启动加载过程

    基于项目实战解析ng启动加载过程 前言 在AngularJS项目开发过程中,自己将遇到的问题进行了整理.回过头来总结一下angular的启动过程. 下面以实际项目为例进行简要讲解. 1.载入ng库 2 ...

  7. iOS欢迎界面Launch Screen动态加载广告

    有许多应用程序在打开的时候,欢迎界面会加载一张连网获取的广告图片或者显示一组动画,这样的效果是如何做到的呢?下面给大家介绍一种简单的实现加载广告的方式. 程序运行起来,欢迎界面之后,会进入AppDel ...

  8. iOS “请在微信客户端打开链接” UIWebview加载H5页面携带session、cookie、User-Agent信息 设置cookie、清除cookie、设置User-Agent

    公司新开的一个项目..内容基本上是加载H5页面显示..当时觉得挺简单的..后来发现自己掉坑里了..一些心理历程就不说了..说这个项目主要用到的知识点吧..也是自己踩得坑. 首先说说..这个项目上的内容 ...

  9. Microsoft Corporation 去掉 windows 修改 启动加载 版权

    windows 修改 开机界面 boot启动界面 windows 修改 启动加载 版权 windows 系统如何修改开机画面的版权文字“Microsoft Corporation ... ◎Micro ...

随机推荐

  1. Zookeeper的安装配置及基本开发

    一.简介 Zookeeper 是分布式服务框架,主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务.状态同步服务.集群管理.分布式应用配置项的管理等等. ZooKeeper的目标就 ...

  2. Writing Sentences [1]

    1) try 'there will be' instead of 'then' In homogeneity MRF, if and , there will be even if . 2) in ...

  3. Java学习之继承中的执行顺序详解

    代码块(理解) (1)用{}括起来的代码. (2)分类: A:局部代码块 用于限定变量的生命周期,及早释放,提高内存利用率. B:构造代码块 把多个构造方法中相同的代码可以放到这里,每个构造方法执行前 ...

  4. 微软Telnet的回显功能开启

    win7和XP系统默认telnet的回显功能是关闭的.启用telnet回显功能:(1)首先进入命令行界面:输入telnet(2)进入Microsoft Telnet>命令提示符下,输入:set ...

  5. C++对象模型的那些事儿之二:对象模型(下)

    前言 上一篇博客C++对象模型的那些事儿之一为大家讲解了C++对象模型的一些基本知识,可是C++的继承,多态这些特性如何体现在对象模型上呢?单继承.多重继承和虚继承后内存布局上又有哪些变化呢?多态真正 ...

  6. 《java入门第一季》之TreeSet存储自定义对象并保证排序和唯一

    上一篇用一个简单的例子,介绍了treeset集合存储的内部过程,这里再完善其存储自定义对象保证唯一. 需求:A:  * 自然排序,按照年龄从小到大排序  *         B:  * 成员变量值都相 ...

  7. XMPP即时通讯资料记录

    几天开始研究XMPP即时通讯的技术,来实现移动应用的计时聊天功能.记录下参考的博客地址,还挺详细的. http://blog.csdn.net/fhbystudy/article/details/16 ...

  8. iOS中 快速正确的安装 CocoaPods

    有问题或技术交流可以咨询!欢迎加入! 第一部分: CocoaPods 的安装 步骤1 - 安装 RVM RVM 是干什么的这里就不解释了,后面你将会慢慢搞明白. $ curl -L https://g ...

  9. UNIX环境高级编程——管道和FIFO限制

    系统加于管道和FIFO的唯一限制为: OPEN_MAX     一个进程在任意时刻打开的最大描述符数: PIPE_BUF       可原子的写往一个管道或FIFO的最大数据量. OPEN_MAX的值 ...

  10. UNIX环境高级编程——system函数

    system函数 功能:调用fork产生子进程,由子进程来调用:/bin/sh -c command来执行参数command所代表的命令,阻塞当前进程直到command命 令执行完毕. int sys ...