App啟動廣告頁的實現和封裝
歡迎訪問我的部落格muhlenXi,該文章出自我的部落格。
版權宣告:本文為muhlenXi原創文章,轉載請註明出處,未經允許不得轉載.
導語:
也許你也注意到了,現在很多App在啟動頁載入完畢後,還會出現一個n秒的廣告頁面,頁面中有一個倒數計時的按鈕,我們可以通過點選跳過那個按鈕來跳過,我們點選廣告的時候,會進入廣告的詳情頁面。如果我們不做任何操作的話,當倒數計時為0秒是會自動進入主頁面。
接下來我們就研究研究這個是如何實現的。
解決方案
我們仔細想想:不妨也有兩種思路來解決。
1、一種是App初次執行時,將廣告頁面的圖片URL和要點選廣告要跳轉的URL資料通過伺服器下載下來,然後再非同步下載圖片資料,最後將圖片的資料和跳轉URL儲存到本地沙盒中。第二次執行App的時候會顯示廣告介面,這時候再通過伺服器更新本地沙盒中的資料。第一次由於本地沙盒中沒有資料則不會顯示。目前大部分App採用此方式
-
2、第二種是每次啟動時就通過伺服器非同步下載圖片資料和跳轉URL,然後將其顯示出來。這樣做的優點時,可以實時更新廣告頁面資料。缺點是當網路出現阻塞時或無網路時,會出現一個空白的廣告介面。
針對該缺點,有一個解決思路,就是當網路不好時,用一個固定的圖片和跳轉URL來替換或者只用一個固定的圖片來替換,點選廣告則不跳轉。但是當跳轉URL失效時,需要通過迭代版本,重新上架來更新,週期比較長。
第一種方案。
XYJAdvertisementView的實現
在Xcode
中通過File
-> New
->File...
新建一個繼承與UIVIew
的XYJLaunchAdvertisingView
;
編寫程式的核心在於要有一個完整的思路!其次為了高效率的程式設計,我們需要學會一些偷懶的方法,比如巨集定義的使用、型別常量的使用、變數的高效命名...
【1】在XYJAdvertisementView.h
檔案中,我們需要幾個巨集定義和型別常量。程式碼如下:
#define kScreenWidth [UIScreen mainScreen].bounds.size.width
#define kScreenHeight [UIScreen mainScreen].bounds.size.height
#define kScreenBounds [UIScreen mainScreen].bounds
static NSString * const adImageName = @"adImageName";
static NSString * const adDownloadUrl = @"adDownloadUrl";
static NSInteger const adTime = 3;
static NSString * const pushToADNotiName = @"pushToADNotiName";
static NSString * const pushToADUrl = @"pushToADUrl";
我們還需宣告一個圖片路徑和一個顯示廣告的show方法。
@property (nonatomic,copy) NSString * filePath; //!< �圖片路徑 用於屬性傳值
- (void) showAD; //顯示廣告頁面方法
【2】在XYJAdvertisementView.m
檔案中,在匿名類中宣告我們需要的控制元件。
宣告如下:
@property (nonatomic,strong) UIImageView * adImageView;
@property (nonatomic,strong) UIButton * countBtn; //倒數計時
@property (nonatomic,strong) NSTimer * countTimer;
@property (nonatomic,assign) NSInteger count; //記錄當前的秒數
接下來我們依次實現相應的方法,我們要記住高內聚低耦合
的原則
通過重寫initWithFrame
方法來搭建我們的UI介面
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//其他控制元件的初始化寫在這裡
//1.廣告圖片
_adImageView = [[UIImageView alloc] initWithFrame:frame];
_adImageView.userInteractionEnabled = YES;
_adImageView.backgroundColor = [UIColor yellowColor];
_adImageView.contentMode = UIViewContentModeScaleAspectFill;
_adImageView.clipsToBounds = YES;
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesHandle:)];
[_adImageView addGestureRecognizer:tap];
//2.跳過按鈕
CGFloat btnW = 60.0f;
CGFloat btnH = 30.0f;
_countBtn = [[UIButton alloc] initWithFrame:CGRectMake(kScreenWidth-btnW-24, btnH, btnW, btnH)];
[_countBtn addTarget:self action:@selector(dismissAD) forControlEvents:UIControlEventTouchUpInside];
_countBtn.titleLabel.font = [UIFont systemFontOfSize:15];
[_countBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[_countBtn setTitle:[NSString stringWithFormat:@"跳過%ld",adTime] forState:UIControlStateNormal];
_countBtn.backgroundColor = [UIColor colorWithRed:38/255.0 green:38/255.0 blue:38/255.0 alpha:0.6];
_countBtn.layer.cornerRadius = 4;
[self addSubview:_adImageView];
[self addSubview:_countBtn];
}
return self;
}
-
通過
懶載入
的方式實現我們的定時器countTimer*所謂的懶載入也就是延時載入,即當物件需要用到的時候再去載入,簡單理解就是,重寫物件的get方法。當我們重寫get方法時,一定要注意,先要判斷當前物件是否為空,為空的話再去例項化物件。
懶載入的優點如下:
1、物件的例項化在get方法中實現,可以降低耦合度。
2、不需要在viewDidLoad中再例項化物件,可以簡化程式碼,同時增強程式碼的可讀性。
3、有效減少記憶體的佔用率。
程式碼如下:
- (NSTimer *)countTimer
{
if (_countTimer == nil) {
_countTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(countDownEventHandle) userInfo:nil repeats:YES];
}
return _countTimer;
}
實現我們的事件響應方法
//廣告介面點選
- (void) tapGesHandle:(UITapGestureRecognizer *) tap
{
[self dismissAD];
[[NSNotificationCenter defaultCenter] postNotificationName:pushToADNotiName object:nil userInfo:nil];
}
//定時器響應
- (void) countDownEventHandle
{
_count--;
[_countBtn setTitle:[NSString stringWithFormat:@"跳過%ld",_count] forState:UIControlStateNormal];
if (_count == 0) {
[self dismissAD];
}
}
//跳過按鈕觸發
- (void) dismissAD
{
[self.countTimer invalidate];
self.countTimer = nil;
[UIView animateWithDuration:0.3 animations:^{
self.alpha = 0;
} completion:^(BOOL finished) {
[self removeFromSuperview];
}];
}
實現我們前面宣告的Show方法
//啟動定時器
- (void) startTimer
{
_count = adTime;
[[NSRunLoop mainRunLoop] addTimer:self.countTimer forMode:NSRunLoopCommonModes];
}
//顯示廣告頁面
- (void)showAD
{
[self startTimer];
UIWindow * window = [UIApplication sharedApplication].keyWindow;
[window addSubview:self];
}
//圖片賦值
- (void)setFilePath:(NSString *)filePath
{
_filePath = filePath;
_adImageView.image = [UIImage imageWithContentsOfFile:filePath];
}
到這裡,我們的View就定製完成,我們還需要一個資料管理類來管理沙盒中的廣告資料!
資料管理類XYJADDataManager的實現
通過File
-> New
->File...
新建一個繼承與NSObject
的XYJADDataManager
;
【1】在XYJADDataManager.h
檔案中,宣告一個新增廣告的方法宣告。程式碼如下:
匯入標頭檔案:
#import "XYJAdvertisementView.h"
方法宣告:
+ (void) addXYJAdvertisementView;
【2】在XYJADDataManager.m
檔案中,實現相應的方法。程式碼如下:
在實現show方法之前,我們要先實現一些幫助方法
通過圖片的名字獲取該圖片在沙盒中的絕對路徑
+ (NSString *)getFilePathWithImageName:(NSString *)imageName
{
if (imageName) {
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
//圖片預設儲存在Cache目錄下
return [paths[0] stringByAppendingPathComponent:imageName];
}
return nil;
}
判斷該路徑下是否存在檔案
+ (BOOL)isFileExistWithFilePath:(NSString *) filePath
{
NSFileManager * fileManager = [NSFileManager defaultManager];
BOOL isDirectory = NO;
return [fileManager fileExistsAtPath:filePath isDirectory:&isDirectory];
}
刪除舊的圖片
+ (void) deleteOldImage
{
NSString * imageName = [[NSUserDefaults standardUserDefaults] objectForKey:adImageName];
if (imageName) {
NSString * filePath = [self getFilePathWithImageName:imageName];
NSFileManager * fileManager = [NSFileManager defaultManager];
if ([self isFileExistWithFilePath:filePath]) {
[fileManager removeItemAtPath:filePath error:nil];
}
}
}
向伺服器請求廣告資料
該方法中要根據實際專案需求做相應調整
+ (void) UpdateAdvertisementDataFromServer
{
//TODO 在這裡請求廣告的資料,包含圖片的圖片路徑和點選圖片要跳轉的URL
//我們這裡假設從伺服器中獲得的 圖片的下載URl和跳轉URl如下所示
NSString * imageurl = @"http://pic.paopaoche.net/up/2012-2/20122220201612322865.png";
NSString * pushtoURl = @"http://www.jianshu.com";
//獲取圖片名
NSString * imageName = [[imageurl componentsSeparatedByString:@"/"] lastObject];
//將圖片名與沙盒中的資料比較
NSString * oldImageName =[[NSUserDefaults standardUserDefaults] objectForKey:adImageName];
if ((oldImageName == nil) || (![oldImageName isEqualToString:imageName]) ) {
//非同步下載廣告資料
[self downloadADImageWithUrl:imageurl iamgeName:imageName];
//儲存跳轉路徑到沙盒中
[[NSUserDefaults standardUserDefaults] setObject:pushtoURl forKey:pushToADUrl];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
非同步下載圖片資料
+ (void) downloadADImageWithUrl:imageUrl iamgeName:(NSString *) imageName
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//TODO 非同步操作
//1、下載資料
NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];
UIImage * image = [UIImage imageWithData:data];
//2、獲取儲存檔案的路徑
NSString * filePath = [self getFilePathWithImageName:imageName];
//3、寫入檔案到沙盒中
BOOL ret = [UIImagePNGRepresentation(image) writeToFile:filePath atomically:YES];
if (ret) {
NSLog(@"廣告圖片儲存成功");
[self deleteOldImage];
//儲存�圖片名和下載路徑
[[NSUserDefaults standardUserDefaults] setObject:imageName forKey:adImageName];
[[NSUserDefaults standardUserDefaults] setObject:imageUrl forKey:adDownloadUrl];
[[NSUserDefaults standardUserDefaults] synchronize];
} else {
NSLog(@"廣告圖片儲存失敗");
}
});
}
實現addXYJAdvertisementView
方法
+ (void) addXYJAdvertisementView;
{
//1.判斷沙盒中是否存在廣告的圖片名字和圖片資料,如果有則顯示
NSString * imageName = [[NSUserDefaults standardUserDefaults] objectForKey:adImageName];
if (imageName != nil)
{
NSString * filePath = [self getFilePathWithImageName:imageName];
BOOL isExist = [self isFileExistWithFilePath:filePath];
//本地存在圖片
if (isExist) {
NSLog(@"本地存在圖片");
XYJAdvertisementView * adView = [[XYJAdvertisementView alloc] initWithFrame:kScreenBounds];
adView.filePath = filePath;
[adView showAD];
}
}
//更新本地廣告資料
[self UpdateAdvertisementDataFromServer];
}
最後一步,在AppDelegate檔案中新增廣告
- 1、在
AppDelegate.h
檔案中匯入XYJADDataManager.h
檔案 。 - 2、在
didFinishLaunchingWithOptions
方法中加入如下程式碼即可。
//新增啟動廣告
[XYJADDataManager addXYJAdvertisementView];
- 3、如果你需要獲取廣告點選事件,則需要進行如下操作。
在主介面ViewController的viewDidLoad
方法中新增:
//新增廣告點選的監聽
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pushToADVC) name:pushToADNotiName object:nil];
同時實現事件響應方法:
- (void) pushToADVC
{
//TODO 在這裡處理廣告事件響應
NSLog(@"廣告點選了");
XYJADWebViewController * webVC = [[XYJADWebViewController alloc] init];
webVC.url = [[NSUserDefaults standardUserDefaults] objectForKey:pushToADUrl];
[self.navigationController pushViewController:webVC animated:YES];
}
編譯執行後,會發現跟我們前面的效果展示是一樣的。
目前暫無實現第二種方案
感謝閱讀,有什麼建議可以給我留言
相關文章
- iOS APP啟動頁載入廣告iOSAPP
- iOS APP啟動廣告實現方式 與 APP喚端呼叫iOSAPP
- 使用Webview實現app啟動引導頁WebViewAPP
- Flutter實現啟動頁、閃屏廣告頁、引導頁Flutter的flutter_native_splash庫Flutter
- 案例分享,Appium+Python實現APP啟動頁跳轉到首頁APPPython
- 啟動載入廣告頁面
- Flutter 啟動頁(閃屏頁)具體實現和原理分析Flutter
- Twitter iOS App 啟動動畫的實現iOSAPP動畫
- UIScrollView和UIPageControl實現app啟動滑動圖UIViewAPP
- App啟動頁設計例項和技巧,啟動即讓人心動APP
- 封裝ListView,實現自動載入更多封裝View
- 封裝RecyclerView,實現新增頭部和底部封裝View
- App啟動頁面優化APP優化
- 如何實現 iOS App 的冷啟動優化iOSAPP優化
- 如何在我的應用啟動介面實現「開屏廣告」?
- css3實現的箱子拆開和封裝效果CSSS3封裝
- 用go封裝和實現掃碼登入Go封裝
- iOS純Autolayout實現微信朋友圈和通訊錄另附App啟動頁短視訊效果iOSAPP
- iOS-設定AppIcon圖示和啟動頁iOSAPP
- 封裝 uniapp 請求庫的最佳實踐封裝APP
- 安全啟動和安全升級的實現
- 介面自動化之實現日誌記錄封裝封裝
- 仿知乎拖動廣告的實現iOSiOS
- iOS App圖示和LaunchImage啟動頁尺寸及命名規則iOSAPP
- 【JavaScript框架封裝】實現一個類似於JQuery的動畫框架的封裝JavaScript框架封裝jQuery動畫
- app直播原始碼,平臺登入頁面實現和修改密碼頁面實現APP原始碼密碼
- 使用微信wx-open-launch-app標籤實現微信網頁開啟AppAPP網頁
- 使用promise封裝jquery的ajax來實現async和await方式Promise封裝jQueryAI
- android 4.0.4系統下實現apk的靜默安裝和啟動AndroidAPK
- UIColletionView瀑布流佈局實現思路以及封裝的實現UIView封裝
- 分分鐘解決iOS開發中App啟動廣告的功能iOSAPP
- js實現的dom元素拖動封裝外掛程式碼例項JS封裝
- 螞蟻動態卡片,讓App首頁實現敏捷更新APP敏捷
- Dapper的封裝、二次封裝、官方擴充套件包封裝,以及ADO.NET原生封裝APP封裝套件
- 業務爬坑與總結——開屏廣告熱啟動實現方案
- android app 啟動第一個頁面AndroidAPP
- 一次有意思的技術降級,iOS 啟動廣告,直接 push,首頁不出現iOS
- 【JavaScript框架封裝】實現一個類似於JQuery的CSS樣式框架的封裝JavaScript框架封裝jQueryCSS