iOS App启动页加载广告
最近自己在练习写一个小项目 其中有一项是App启动时需要在启动完毕以后 加载一个广告页面 同时 广告页面在用户点击以后 可以通过Safari打开跳到指定的网页中去 现在写完了这个功能 打算记录下
干活前的思路
1.既然是广告页面 那如果是在用户使用App的过程中 以弹框形式出现的话 估计用户要报警了 因此 我们选择在用户启动完App以后 添加一个广告页 并且设定一个时间 XX秒之后关闭页面随后进入App 造成一个 App还在启动过程中出现的一个广告页的假象 实际上App已经启动完毕了
2.上面已经提到了 既然是App已经启动完毕才出现的广告页 那随之也可以非常容易想到一点 我们只需要将App启动以后的RootViewController先改为指定的广告页也就是一个ViewController 然后再进入App真正的主界面
3.通过上面的思路可以得出一个结论 既然是指定一个ViewController为根控制器(RootViewController)那么立马可以联想到一个方法
ViewController *VC = [ViewController alloc]init];
其中这个init方法中又有一个InitWithNibName: 因此 我们需要创建一个Nib文件来加载广告控制器
4.假设已经成功加载了Nib文件 那么现在要做的就是加载广告数据了也就是要用到AFNetworking这个第三方库了(感谢github上这些大牛)
5.加载完广告以后 需要点击广告页面来跳转 因此又可以想到 我们需要在上面加一个Tap手势
6.上面提到过 需要XX秒之后关闭页面 因此需要一个定时器 定时器有两种 NSTimer和CADisplaylink 两者区别在于调用的频繁程度 我们这里并不需要频繁的调用 所以 用NSTimer就可以了
思路理清了 开始写代码吧 少年!
1.首先 需要新建一个类 来控制我们的广告控制器 同时新建一个Nib文件(这里就不赘述新建类和Nib文件了。。毕竟 还是蛮简单的)
控制器.png2.捋一捋Nib中的层级关系 App的启动页->广告->跳过Button 这里有一点需要注意 跳过的这个Button是和广告的这个View同级的 并不是镶嵌在View里 不然的话 等广告图片出来以后 Button会被遮挡住
启动页应该是一个ImageView 广告页应该是一个View 同时做一下Autolayout 让他们的距离屏幕的上中下分别都为0 button的约束分别是 距离右边20 顶部20 宽度固定
Nib层级关系.png3.新建Nib以后 我们去到AppDelegate文件里进行设置 因为我这个项目并不是通过StoryBorad来加载界面的 在AppDelegate中创建窗口 指定根控制器为ADViewController
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//由于是纯代码构建 没有从storyboard加载UI 所以需要自己手工实现1.创建窗口 2.指定rootViewController 3.显示窗口
//1.
self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
//2.
//ZHHMainBarController *tabVC = [[ZHHMainBarController alloc]init];
ZHHADViewController *adVC = [[ZHHADViewController alloc]init];
self.window.rootViewController =adVC;
//3.
[self.window makeKeyAndVisible];
return YES;
}
4.Nib加载的时候既然是有启动页的 那么也需要加载启动页 因此我们做一个判断 判断的条件就是根据屏幕的高度来适配不同的图片 这里列举一下
iphone7P 6P 高度为 736
iphone7 6 高度为667
iphone5 5S 5C 高度为568
iphone4 4S 高度为480
适配屏幕的代码如下: 同时在ViewDidLoad里调用该方法
- (void)setScreenForLauchScreen{
if ([UIScreen mainScreen].bounds.size.height == 736) {
self.LaunchImageView.image = [UIImage imageNamed:@"LaunchImage-800-Portrait-736h@3x.png"];
}else if([UIScreen mainScreen].bounds.size.height == 667){
self.LaunchImageView.image = [UIImage imageNamed:@"LaunchImage-800-667h@2x.png"];
}else if([UIScreen mainScreen].bounds.size.height == 568){
self.LaunchImageView.image = [UIImage imageNamed:@"LaunchImage-700-568h@2x.png"];
}else if ([UIScreen mainScreen].bounds.size.height == 480){
self.LaunchImageView.image = [UIImage imageNamed:@"LaunchImage@2x.png"];
}
}
PS:不要导入Assets.Xcassets文件中 否则会报错 导入Supporting.files里
5.已经有了Nib也指定了根控制器 这个时候就需要加载网络上的广告图片了 首先利用Cocoapods导入AFNetworking 这里我用的是最新版的 否则Xcode8会有一堆警告 导入过程不再赘述
5.1使用AFN的过程 1.创建管理者 2.发送请求 3.将返回的json做处理 4.由于我返回的是一个字典 因此做字典转模型的处理 5.拿到模型以后 将图片加载到Nib中的View里
#pragma mark ---load AD---
- (void)loadAdData{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSMutableDictionary *parameter = [NSMutableDictionary dictionary];
parameter[@"code2"] = code2;
[manager GET:@"http://mobads.baidu.com/cpro/ui/mads.php" parameters:parameter progress:nil success:^(NSURLSessionDataTask * _Nonnull task, NSDictionary * _Nullable responseObject) {
[responseObject writeToFile:@"/Users/zzzzhu/Desktop/ad.plist" atomically:YES];
NSLog(@"%@",responseObject);
NSDictionary *dict = [responseObject[@"ad"] lastObject];
//5.
self.model = [ZHHAdModel mj_objectWithKeyValues:dict];
self.ADimageView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
//7.加载网络上的图片
[self.ADimageView sd_setImageWithURL:[NSURL URLWithString:self.model.w_picurl]];
NSLog(@"%@",self.model.w_picurl);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@",error);
}];
}
这里同时也用到了第三方库 SDWebImage 和 MJExtension 再次感谢github上的各路大神
其中SDWebImage用于可以直接加载网络上的图片 MJExtension用于字典转模型
5.2拿到数据以后的处理
开发过程中发现 虽然我拿到了数据 但是我并没有办法直接用 因此需要一个模型 于是新建一个Model类 类中分别定义图片的URL和点击广告以后需要跳转的URL 这里需要注意 取变量名的时候 需要和返回的json数据变量名一致 否则都是拿不到的 还有一点就是 我们在Nib中定义的是一个View 因此我们需要新建一个imageView放到View上 由于只需要用一次 因此可以用懒加载 也就是新建一个属性
#pragma mark ---creat ADimageView---
- (UIImageView *)ADimageView{
if (_ADimageView == nil) {
UIImageView *AdImageView = [[UIImageView alloc]init];
[self.ADView addSubview:AdImageView];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
[AdImageView addGestureRecognizer:tap];
NSLog(@"添加成功");
AdImageView.userInteractionEnabled = YES;
_ADimageView =AdImageView;
}
return _ADimageView;
}
Model类.png
6.这个时候 运行一下程序 会神奇的发现 已经可以拿到广告图了 但是 还有几个问题需要处理
1.程序不进入主界面
2.跳过button没有达到想要的效果 想要的效果应该分别是显示倒计时以及点击button可以跳过广告
3.点击图片 并没有跳转到相对应的广告网站上去
6.1 那先来解决跳转的问题吧
其实也非常简单 OC中提供了相对应的API 只需要调用这个API就好 思路就是 从Json文件中获取需要跳转的URL 同时在程序里判断URL是否能打开 有个小细节就是 如果直接这样做是不行的 因为我们需要点击 因此 需要一个Tap手势 添加到ImageView上 代码如上 就不重复添加了 同时需要设置ImageView的交互 默认是不允许交互的
跳转方法的代码如下:
#pragma mark ---UIGestureRecognizer---
- (void)tap{
//用Safari打开广告指向的网页
NSURL *url = [NSURL URLWithString:self.model.ori_curl];
UIApplication *app = [UIApplication sharedApplication];
if ([app canOpenURL:url]) {
[app openURL:url];
NSLog(@"打开成功");
}else{
NSLog(@"打开失败");
}
}
6.2 至此大部分的功能已经实现了 我们已经实现了从网络上加载广告图片 以及点击跳转的功能 那么接下来 来解决下倒计时的问题吧 也就是跳过按钮同时显示倒计时 假设为3秒 其实也非常简单 我们可以使用上文提到的NSTimer类 新建一个定时器来管理
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timeChange) userInfo:nil repeats:YES];
新建完毕以后 我们就需要去实现这个timeChange方法 其中实现的思路是 要在倒计时完毕以后 销毁定时器 不销毁的话 会一直存在 浪费内存 同时也需要销毁广告页面 进入到主程序 这里我们需要用到一个静态变量
代码如下:
#pragma mark ---NSTimer---
- (void)timeChange{
//使用静态变量 否则的话 只会调用一次
//销毁广告界面
//销毁定时器
static int i = 3;
[self.jumpBtn setTitle:[NSString stringWithFormat:@"跳转(%d)",i] forState:UIControlStateNormal];
if (i == 0) {
ZHHMainBarController *mainVC = [[ZHHMainBarController alloc]init];
[UIApplication sharedApplication].keyWindow.rootViewController = mainVC;
}
i --;
[self.timer invalidate];
}
6.3 至此我们基本上 99%的功能已经完成了 App启动加载广告页面显示广告数据 点击跳转到相应的URL 同时Button可以显示倒计时 不过还有两个功能没有实现
1.广告倒计时都结束了 总不能还不进入App主界面吧?
2.既然是个跳过按钮就需要可以点击跳过广告进入App的主界面 实现起来也非常简单
整体思路就是 既然上文已经提到过 我们只是指定了根控制器为ADViewController 那么我们只需要在倒计时为0的时候 将根控制器指定为App的主界面就可以了 其次就是跳过Button的点击事件 其实也是一样的思路 就是点击了Button 根控制器变化为App的主控制器 其中倒计时结束以后的处理代码已经贴在上面了 就不重复添加了 这里是一个Button点击事件的代码(其实代码都是一样的 可以单独抽取一个方法来实现 代码就不会有重复了 )
- (IBAction)pressJumpBtn:(id)sender {
ZHHMainBarController *mainVC = [[ZHHMainBarController alloc]init];
[UIApplication sharedApplication].keyWindow.rootViewController = mainVC;
}
7.写到这里 我们整个功能就已经全部搞定了 大功告成 !感谢各位看官看到了这里!走过路过不要错过!点个赞吧!2333333
----------------------------------分割线------------------------------------
之前提到的第七点 认真的审视代码的时候发现 假设用户点击了跳过按钮 但是如果在倒计时为0的时候 设置再次根控制器的话 会有非常奇怪效果 比如 本来已经进入第二页 但是三秒时间一到 会返回第一页 因此 我们需要在控制时间的地方 当倒计时为0的时候 直接调用pressJumpBtn这个方法就好了 就可以解决这个bug了
PS 杭州地区求一份iOS实习工作联系方式 QQ: 406132631