美文网首页程序员键盘上的鼓手账号
实现 iOS 前台时的推送弹窗效果

实现 iOS 前台时的推送弹窗效果

作者: pikacode | 来源:发表于2016-07-25 17:11 被阅读11496次

    或许很多童鞋还不知道,在 iOS 中收到推送通知时,如果 App 处于前台运行的情况下,推送的顶部弹窗是不会弹出来的。

    然而就是有很多**的产品经理都会提出类似这样的**需求:
    那就是在 App 处于前台时一样要弹出推送的窗口,而且还要能点击,能跳转到指定页面,甚至这一需求还涉及到了产品的核心功能。

    今天 Pikacode 就跟大家分享一下自己写的小插件,仅仅只需 1、2 行代码,即可搞定这一需求。

    Github: https://github.com/Yasashi/EBForeNotification

    EBForeNotification


    在 App 处于前台时展示跟系统完全一样的推送弹窗声音。获取推送内容,并且处理点击事件。

    支持 iOS 7~10 beta,支持模拟器真机运行。

    效果

    实际效果如下:

    本地弹窗

    在任意方法内调用以下任 1 行代码即可弹窗

    #import "EBForeNotification.h"
    {...
    //普通弹窗(系统声音)
    [EBForeNotification handleRemoteNotification:@{@"aps":@{@"alert":@"展示内容"}} soundID:1312];
    
    //普通弹窗(指定声音文件)
    [EBForeNotification handleRemoteNotification:@{@"aps":@{@"alert":@"展示内容"}} customSound:@"my_sound.wav"];
    
    //带自定义参数的弹窗(系统声音)
    [EBForeNotification handleRemoteNotification:@{@"aps":@{@"alert":@"展示内容"}, @"key1":@"value1", @"key2":@"value2"} soundID:1312];
    
    //普通弹窗(指定声音文件)
    [EBForeNotification handleRemoteNotification:@{@"aps":@{@"alert":@"展示内容"}, @"key1":@"value1", @"key2":@"value2"} customSound:@"my_sound.wav"];
    ...}
    

    接收远程/本地推送后弹窗

    接收远程/本地推送后,自动在前台展示推送弹窗及声音。
    AppDelegate.m 中添加代码

    //AppDelegate.m
    #import "EBForeNotification.h"
    
    //ios7 before
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { 
        ...
        //系统声音弹窗
        [EBForeNotification handleRemoteNotification:userInfo soundID:1312];
        
        //指定声音文件弹窗
        [EBForeNotification handleRemoteNotification:userInfo customSound:@"my_sound.wav"];
        ...
    }
    
    //ios7 later  
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {    
        ...
        //系统声音弹窗
        [EBForeNotification handleRemoteNotification:userInfo soundID:1312];
        
        //指定声音文件弹窗
        [EBForeNotification handleRemoteNotification:userInfo customSound:@"my_sound.wav"];
        ...
        completionHandler(UIBackgroundFetchResultNewData);
    }
    

    soundID 参数

    iOS 系统自带的声音 id,系统级的推送服务默认使用的是三全音,id = 1312

    其他系统声音 id 可以在这里查询到 iOS Predefined sounds
    备用地址 AudioServices sounds

    监听并处理点击事件

    添加 Observer 监听 EBBannerViewDidClick,获取推送内容,通过推送时自定义的字段处理自己逻辑,如:跳转到对应页面等。

    接收到的推送内容类似以下:

    {
        "aps":
        {
            "alert":"推送内容",
            "sound":"sound",
            "badge":"3"
        },
            "key1":"跳转页面1"  //自定义此字段以跳转到相应页面
    }
    

    添加 Observer 获取自定义的字段,并处理:

    #import "EBForeNotification.h"
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(eBBannerViewDidClick:) name:EBBannerViewDidClick object:nil];
    -(void)eBBannerViewDidClick:(NSNotification*)noti{
        if(noti[@"key1" == @"跳转页面1"]){
            //跳转到页面1
        }
    }
    

    相关文章

      网友评论

      • 吴欧:现在ios11系统是可以前台弹出横幅了, ios8,9好像不可以 10还没测过
        吴欧:同时有多个消息过来貌似不能一个个显示,只会一条消息?
      • 英俊神武:请问一下这个有demo吗
        pikacode:@我是宋仲基 有 demo 的,https://github.com/pikacode/EBBannerView
      • 多LV信源:不写个EBBannerView吗?
        多LV信源:bannerViewDidClick这个通知注册的方法的参数, 只有noti(NSNotification)
        多LV信源:@pikacode 遇到一个难题, 在线等回复, app前台运行时, 点击推送, 在通知注册的方法bannerViewDidClick里, 怎么获取通知的内容? (用的是EBBannerView)
        pikacode:@多LV信源 没空啊,要不您帮忙写一个?
      • 不辣先生:大神,为什么我改了这个EBBannerView的位置,上面的标题图片都是展示不出来了,求解
        pikacode:@不辣先生 我把这个组件全部重写过了,功能强大很多,已经上传,还没正式发布 qq57380422
      • bc3d3e66fba3:已经OK了,谢谢
      • bc3d3e66fba3:弹框的背景能改吗?
      • 唯爱灬晓萌神:当设备正常使用的时候可以 但是当设备横屏的时候 弹框没有横屏 在左侧边弹出了 这个能解决吗?
        pikacode:@b5fc32a05149 能,期待你们解决
      • 4f38d8742e72:你好, 我集成的友盟推送, 在前台时自定义了一个系统的alert弹窗, 我想在任意的界面(当消息推送过来时用户所在的页面)点击弹窗的按钮跳转页面, 这该怎么做呢? 求大神指点, 我现在用一个方法获取到rootViewController, 但是却是UIAlertController来的, 没办法做跳转啊, 急急急
        pikacode:加q群
      • koreadragon:在这个方法里,iOS10 前台是可以展示的,什么情况?
        // iOS 10 Support前台
        - (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
        completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置


        }
        pikacode:@koreadragon q群里问啊
        koreadragon:@pikacode 除了加q群还有没其他回复?
        pikacode:@koreadragon 加q群
      • 哈哈大笑呼呼呼呼:你好 ,我按照你的方法集成后还是不行,我在前台还是没有收到消息的 能加你QQ问问嘛着急
      • w_xiao_wu:-(void)apperWithAnimation{
        CGFloat bannerHeight = self.isIos10 ? BannerHeightiOS10 : BannerHeight;
        self.frame = CGRectMake(0, 0, ScreenWidth, 0);
        WEAK_SELF(weakSelf);
        [UIView animateWithDuration:BannerSwipeUpTime animations:^{
        weakSelf.frame = CGRectMake(0, 0, ScreenWidth, bannerHeight);
        } completion:^(BOOL finished) {
        weakSelf.frame = CGRectMake(0, 0, ScreenWidth, bannerHeight);
        }];
        [NSTimer scheduledTimerWithTimeInterval:BannerStayTime target:self selector:@selector(removeWithAnimation) userInfo:nil repeats:NO];
        }
        报错报在第二个 “weakSelf.frame = CGRectMake(0, 0, ScreenWidth, bannerHeight);”

        错误信息:
        warning: could not load any Objective-C class information. This will significantly reduce the quality of type information available.

        死循环?
        w_xiao_wu:(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
        (
        "<_UIWindowAnchoringConstraint:0x161a4f90 h=--- v=--- _UIAlertControllerShimPresenterWindow:0x14feb530.midX == + 160>",
        "<_UIWindowAnchoringConstraint:0x160000d0 h=-&- v=-&- EBBannerView:0x161a0d30.midX == + 160>",
        "<NSAutoresizingMaskLayoutConstraint:0x161a4bf0 h=-&- v=-&- UITransitionView:0x161b4950.midX == _UIAlertControllerShimPresenterWindow:0x14feb530.midX>",
        "<NSAutoresizingMaskLayoutConstraint:0x16002a30 h=-&- v=-&- EBBannerView:0x161a0d30.midX == _UIAlertControllerView:0x165147e0'\U53d6\U6d88\U8ba2\U5355'.midX + 25>",
        "<NSLayoutConstraint:0x14e87720 _UIAlertControllerView:0x165147e0'\U53d6\U6d88\U8ba2\U5355'.centerX == UIView:0x14fd7a30.centerX>",
        "<NSLayoutConstraint:0x161b24c0 UIView:0x14fd7a30.width == UITransitionView:0x161b4950.width>",
        "<NSLayoutConstraint:0x161a35f0 H:|-(0)-[UIView:0x14fd7a30](LTR) (Names: '|':UITransitionView:0x161b4950 )>"
        )
      • w_xiao_wu:请问手机静音状态下怎样让没声音
      • 茄子重新开始:你好我想问下,要是手机在静音环境下不想有声音怎么处理呢,怎样判断是否静音呢
        pikacode:@包子头 加q群
      • o0下一站生活0o:好奇转换成本地通知可以吗?
        o0下一站生活0o:@pikacode 不是,我意思是如果APP在前台,我把远程推送,改成本地推送,这个会在前台显示这个同志吗?不是用你的APP。
        pikacode:@o0下一站生活0o 按照格式给个字典就行了
        pikacode:可以
      • dong_liang:你好,应用在前台运行时,这个很好用,谢谢,但是有个问题不会处理,就是程序在后台时远程推送会有系统弹窗,点击弹窗打开应用,又会跳出来这个自定义的弹窗,怎么能不跳出这个自定义弹窗
        dong_liang:@pikacode - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
        // Required, iOS 7 Support

        [EBForeNotification handleRemoteNotification:@{@"aps":@{@"alert":userInfo[@"aps"][@"alert"]}} soundID:1312 isIos10:NO];
        [JPUSHService handleRemoteNotification:userInfo];
        completionHandler(UIBackgroundFetchResultNewData);
        } 点击系统弹窗打开app时,走这个方法的时候app应该都是运行的状态了,没法区分啊
        pikacode:@dong_liang 这个bug一直打算更新解决,但是最近太忙。。
        pikacode:@dong_liang 判断一下app状态
      • YY_Lee:你好,没有获取到应用图标是什么原因
        pikacode:@Gradient 搜一下 appicon 然后在那里打断点看看
        YY_Lee:@pikacode 什么意思啊,哪里设置,直接用系统的弹窗有图标的:cry:
        pikacode:@Gradient 没有设置图标
      • Johnny_Chang:给力,赞,👍👍
      • 7332eba3b81a:mark 不过系统的推送 时间label是在title label的右边 而不是靠右 这里可以优化以下 而且 为什么ios10 需要重新画个ui呀
      • 豆小兽:已经在Guthub上加星了!
      • 名字微信超級會員: 好像加NavigationController了这层后,只能听到声音,却不见UI ,是不是UI层级出现问题
        pikacode:@名字微信超級會員 试试在 viewDidAppear 里面再调用弹窗
        pikacode:@名字微信超級會員 源码已经放在了 dev 分支上,你也可以帮我看看 ^ ^
        pikacode:@名字微信超級會員 我测试一下
      • 胖子程:按照你说的,我这添加之后只有声音没有上面的提示。错误提示:Cannot find executable for CFBundle 0x7fe31bd32000 </Users/fcl/Library/Developer/CoreSimulator/Devices/7A31E96D-E0AE-4EF2-BACA-705762F2DFDA/data/Containers/Bundle/Application/BEEFB49F-E5D4-4511-9069-7C8F0A71F76F/FCLForeNotification.app/EBForeNotificationBundle.bundle> (not loaded)。这个怎么回事呢?
        pikacode:@胖子程 安装第2步做了吗?
      • 若非长得丑怎会做逗比:为啥要打包成静态库呢
        pikacode:@若非长得丑怎会做逗比 下一版会完全开源 ^。^
      • xxttw:给力 收藏起
      • 小城东风:收下我的膝盖 同样被**的组长折磨了一周了,你终于把我救了
        pikacode:@_虫二 :stuck_out_tongue:
      • 钢铁少侠:用心了
      • ocarol:收藏备用:smile:
      • 凯文Kevin21:还有,我是把下载下来的文件里面的一个名叫EBForeNotification拖到项目当中, 如果直接把文件拖到项目当中会报错, 日志说install.png图片找不到。不知道什么原因。
        胖子程:@七秒小鱼人 又看到你了!哈哈 :blush:
        凯文Kevin21:@Pikacode 对,我之前第一次的时候拖错了
        pikacode:@七秒小鱼人 就是拖里面的这个文件夹就行了,那个图片是readme安装那一步的图片
      • 凯文Kevin21:试了下,搞定。确实不错,挺好用的。谢谢开源,给你个赞。。
        pikacode:@七秒小鱼人 源码已经放 github 上了 ^_^
        凯文Kevin21:@Pikacode 大神啊,怎么封装得。教教我啊
        pikacode:@七秒小鱼人 >_<
      • 丿丨丨:有人试过了吗?好用不?
        胖子程:@丿丨丨 我试过了,可以的。 :smile:
        pikacode:@丿丨丨 好用的哥们,分分钟。有问题加我问就行
      • 拿铁加冰:可以的,666
      • 27bba2520ac9:感谢,试试看
      • Double丶K:马克

      本文标题:实现 iOS 前台时的推送弹窗效果

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