美文网首页
无入侵插入开屏广告

无入侵插入开屏广告

作者: 海辰 | 来源:发表于2024-11-21 18:01 被阅读0次

很多App都会有开屏广告,但实现方式往往入侵AppDelegate和ViewController。本文介绍一种新的设计方式。下面是我使用的一套方案,先说结论,具有一下优势:

- 减少对AppDelegate和ViewController的入侵,将广告逻辑与核心业务逻辑分离,提高代码的可维护性和可测试性。

- 提供模块化的开屏广告功能,使其更加灵活和可扩展。

- 简化对广告平台SDK的依赖,并提供统一的接口供其他模块使用。

#实现原理

##通知

iOS的通知是一个神器,它会发出应用的启动,退到后台等事件通知,有了通知我们就可以做到对AppDelegate的无入侵。 

```swift

///在load 方法中,启动监听,可以做到无注入

+ (void)load

{

    [self shareInstance];

}

- (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 request];

        }];

        ///后台启动,二次开屏广告

        [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillEnterForegroundNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {

            [self checkAD];

        }];

    }

    return self;

}

```

只有通知还是没有用的,我们还需要显示。 

##核心突破点:显示

```swift

- (void)show

{

    ///初始化一个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;

}

```

其实大家一般盖视图,习惯在 KeyWindow 上直接AddSubview, 其实这是不好的。首先KeyWindow 会被AlertView覆盖, 还有可能别的业务代码也进行了AddSubview 这样就会把你的广告给覆盖了。 

而使用我这种 UIWindow 的初始化,可以让你的视图出现在最顶层,不用怕乱七八糟的业务逻辑覆盖。 

调用KeyWindow 还有个坏处。下面会说到。

##跳转

其实倒计时跟跳转是个很普通的功能点,没啥说的。有个关键点还是要说的 就是KeyWindow的调用

```swift

///不直接取KeyWindow 是因为当有AlertView 或者有键盘弹出时, 取到的KeyWindow是错误的。

UIViewController* rootVC = [[UIApplication sharedApplication].delegate window].rootViewController;

[[rootVC imy_navigationController] pushViewController:[IMYWebViewController new] animated:YES];

```

其实[UIApplication sharedApplication].keyWindow 取到的Window 不一定是你想要的。 因为KeyWindow 是会变的,所以劲量使用[Delegate Window]来获取显示的Window

获取任意ViewController的navigationController

```swift

@implementation UIViewController (IMYPublic)

- (UINavigationController*)imy_navigationController

{

    UINavigationController* nav = nil;

    if ([self isKindOfClass:[UINavigationController class]]) {

        nav = (id)self;

    }

    else {

        if ([self isKindOfClass:[UITabBarController class]]) {

            nav = [((UITabBarController*)self).selectedViewController imy_navigationController];

        }

        else {

            nav = self.navigationController;

        }

    }

    return nav;

}

@end

```

相关文章

网友评论

      本文标题:无入侵插入开屏广告

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