服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - iOS自定义推送消息提示框

iOS自定义推送消息提示框

2021-01-29 15:52勇敢的少年 IOS

这篇文章主要为大家详细介绍了自定义iOS推送消息提示框的相关代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

看到标题你可能会觉得奇怪 推送消息提示框不是系统自己弹出来的吗? 为什么还要自己自定义呢? 

因为项目需求是这样的:最近需要做 远程推送通知 和一个客服系统 包括店铺客服和官方客服两个模块 如果有新的消息推送的时候 如果用户当前不在客服界面的时候  要求无论是在app前台 还是app退到后台 顶部都要弹出系统的那种消息提示框

这样的需求 我们就只能自定义一个在app内 弹出消息提示框  

实现步骤如下: 

1.我们自定义一个view 为 stpushview 推送消息的提示框view 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
#import <uikit/uikit.h>
#import "stpushmodel.h"
 
@interface stpushview : uiview
 
/** *推送数据模型 */
@property(nonatomic,strong) stpushmodel *model;
 
+(instancetype)shareinstance;
+ (void)show;
+ (void)hide;
 
@end
?
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#import "stpushview.h"
#import "appdelegate.h"
 
@interface stpushview()
 
@property (nonatomic, weak) uiimageview *imagev;
@property (nonatomic,weak ) uilabel *timlabel;
@property (nonatomic,weak ) uilabel *content;
 
@end
 
@implementation stpushview
 
static stpushview *_instance = nil;
 
+(instancetype)shareinstance
{
 static dispatch_once_t oncetoken;
 dispatch_once(&oncetoken, ^{
 _instance = [[stpushview alloc] init];
 });
 return _instance;
}
 
+(instancetype) allocwithzone:(struct _nszone *)zone
{
 if (!_instance) {
 _instance = [super allocwithzone:zone];
 }
 return _instance ;
}
 
- (instancetype)initwithframe:(cgrect)frame
{
 if (self = [super initwithframe:frame]) {
 
 self.backgroundcolor = customcolor(15, 14, 12);
 
 cgfloat margin = 12;
 uiimageview *imagev = [[uiimageview alloc] init];
 imagev.userinteractionenabled = no;
 imagev.image = [uiimage imagenamed:@"logo"];
 imagev.layer.cornerradius = 5;
 [self addsubview:imagev];
 self.imagev = imagev;
 [imagev mas_makeconstraints:^(masconstraintmaker *make) {
  make.left.equalto(self).offset(margin);
  make.centery.equalto(self.mas_centery);
  make.width.mas_equalto(30);
  make.height.mas_equalto(30);
 }];
 
 
 uilabel *titlelabel = [[uilabel alloc] init];
 titlelabel.textcolor = [uicolor whitecolor];
 titlelabel.font = [uifont boldsystemfontofsize:12];
 titlelabel.text = @"121店官方客服";
 [self addsubview:titlelabel];
 [titlelabel mas_makeconstraints:^(masconstraintmaker *make) {
  make.left.equalto(imagev.mas_right).offset(margin);
  make.top.equalto(self.mas_top).offset(margin);
  make.height.mas_equalto(16);
 }];
 [titlelabel sizetofit];
 
 uilabel *timlabel = [[uilabel alloc] init];
 timlabel.font = [uifont systemfontofsize:12];
 timlabel.userinteractionenabled = no;
 timlabel.textcolor = [uicolor whitecolor];
 timlabel.text = @"刚刚";
 timlabel.textcolor = [uicolor lightgraycolor];
 [self addsubview:timlabel];
 self.timlabel = timlabel;
 [timlabel mas_makeconstraints:^(masconstraintmaker *make) {
  make.left.equalto(titlelabel.mas_right).offset(margin);
  make.top.equalto(self.mas_top).offset(margin);
  make.width.mas_lessthanorequalto(40);
  make.height.mas_equalto(16);
 }];
 
 
 uilabel *content = [[uilabel alloc] init];
 content.numberoflines = 2;
 content.font = [uifont systemfontofsize:13];
 content.textcolor = [uicolor whitecolor];
 content.userinteractionenabled = no;
 [self addsubview:content];
 self.content = content;
 [content mas_makeconstraints:^(masconstraintmaker *make) {
  make.left.equalto(imagev.mas_right).offset(margin);
  make.top.equalto(titlelabel.mas_bottom).offset(-3);
  make.right.equalto(self.mas_right).offset(-margin);
  make.height.mas_equalto(35);
 }];
 
 
 uiview *toolbar = [[uiview alloc] init];
 toolbar.backgroundcolor = customcolor(121, 101, 81);
 toolbar.layer.cornerradius = 3;
 [self addsubview:toolbar];
 [toolbar mas_makeconstraints:^(masconstraintmaker *make) {
  make.width.mas_equalto(35);
  make.height.mas_equalto(6);
  make.centerx.equalto(self.mas_centerx);
  make.bottom.equalto(self.mas_bottom).offset(-2);
 }];
 
 }
 return self;
}
 
- (void)setmodel:(stpushmodel *)model
{
 _model = model;
 self.timlabel.text = @"刚刚";
 self.content.text = model.content;
}
 
+ (void)show
{
 
 [uiapplication sharedapplication].statusbarhidden = yes;
 stpushview *pushview = [stpushview shareinstance];
 pushview.hidden = no;
 
 appdelegate *app = (appdelegate*)[uiapplication sharedapplication].delegate;
 [app.window bringsubviewtofront:pushview];
 
 [uiview animatewithduration:0.25 animations:^{
 
 pushview.frame = cgrectmake(0, 0, screen_width, pushviewheight);
 
 dispatch_after(dispatch_time(dispatch_time_now, (int64_t)(5 * nsec_per_sec)), dispatch_get_main_queue(), ^{
  
  [uiview animatewithduration:0.25 animations:^{
  
  pushview.frame = cgrectmake(0, -pushviewheight, screen_width, pushviewheight);
  
  
  } completion:^(bool finished) {
  
  [uiapplication sharedapplication].statusbarhidden = no;
  pushview.hidden = yes;
  
  }];
  
 });
 
 }];
}
 
+ (void)hide
{
 stpushview *pushview = [stpushview shareinstance];
 
 [uiview animatewithduration:0.25 animations:^{
 
 pushview.frame = cgrectmake(0, -pushviewheight, screen_width, pushviewheight);
 
 } completion:^(bool finished) {
 
 [uiapplication sharedapplication].statusbarhidden = no;
 pushview.hidden = yes;
 
 }];
 
}
 
@end

上面pushview需要一个模型 实现代码如下 

?
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
// push 推送的model
 
推送过来的数据如下:
/**
 content = dsfdsnfds;
 id = 5077;
 mid = 1270339;
 title = dsfdsnfds;
 url = "3?_from=push";
 urltype = 3;
 
 **/
#import <foundation/foundation.h>
 
@interface stpushmodel : stbasemodel<nscoding> //stbasemodel 是一个继承自nsobject的类 我主要是在这个类中实现了字典转模型的功能 你可以直接修改为nsobject
 
/***id**/
@property (copy,nonatomic) nsstring* recordid;
/***标题**/
@property (copy, nonatomic) nsstring *title;
/***url**/
@property (copy, nonatomic) nsstring *url;
/***url 类型**/
@property (copy, nonatomic) nsstring* urltype;
/***图标的高度**/
@property (assign,nonatomic) nsstring * mid;
/***推送内容**/
@property (copy, nonatomic) nsstring* content;
 
@end

因为涉及到好几个页面需要使用同样的推送消息数据 进行判断而处理相应的业务 所有我对此模型做了归档处理

?
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
33
34
35
36
37
38
39
40
41
42
#import "stpushmodel.h"
 
@implementation stpushmodel
 
 
/**
 * 保存对象到文件中
 *
 * @param acoder <#acoder description#>
 */
-(void)encodewithcoder:(nscoder *)acoder
{
 [acoder encodeobject:self.recordid forkey:@"recordid"];
 [acoder encodeobject:self.title forkey:@"title"];
 [acoder encodeobject:self.url forkey:@"url"];
 [acoder encodeobject:self.urltype forkey:@"urltype"];
 [acoder encodeobject:self.mid forkey:@"mid"];
 [acoder encodeobject:self.content forkey:@"content"];
}
 
 
/**
 * 从文件中读取对象
 *
 * @param adecoder <#adecoder description#>
 *
 * @return <#return value description#>
 */
-(id)initwithcoder:(nscoder *)adecoder
{
 //注意:在构造方法中需要先初始化父类的方法
 if (self=[super init]) {
 self.recordid=[adecoder decodeobjectforkey:@"recordid"];
 self.title=[adecoder decodeobjectforkey:@"title"];
 self.url=[adecoder decodeobjectforkey:@"url"];
 self.urltype=[adecoder decodeobjectforkey:@"urltype"];
 self.mid=[adecoder decodeobjectforkey:@"mid"];
 self.content= [adecoder decodeobjectforkey:@"content"];
 }
 return self;
}
@end

做好了上面的准备工作之后  接下来我们就需要 appdelegate里面注册远程推送通知  并且监听推送消息 

这里以个推为例子:

第一步在下面的方法中 实现个推的注册方法 

?
1
2
3
4
5
6
7
- (bool)application:(uiapplication *)application didfinishlaunchingwithoptions:(nsdictionary *)launchoptions {
 
 // 注册个推推送服务
 [[getuiapilmpl sharedinstance] getuiregister];
 
 
}

getuiapilmpl 是一个单例类 专门用于注册个推的推送方法 实现代码如下:

?
1
2
3
4
5
6
7
8
9
#import <foundation/foundation.h>
#import "getuisdk.h"
@interface getuiapilmpl : nsobject <getuisdkdelegate>
 
+ (getuiapilmpl *) sharedinstance;
 
- (void) getuiregister;
 
@end
?
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#import "getuiapilmpl.h"
 
@implementation getuiapilmpl
 
+ (getuiapilmpl *) sharedinstance{
 static id instance = nil;
 static dispatch_once_t oncetoken;
 dispatch_once(&oncetoken, ^{
 instance = [[self alloc] init];
 });
 return instance;
}
 
- (id)init {
 self = [super init];
 if (self) {
 nsstring *path = [[nsbundle mainbundle] pathforresource:@"libgexin" oftype:@"plist"];
 nsdictionary *dic = [nsdictionary dictionarywithcontentsoffile:path];
 [getuisdk startsdkwithappid:[dic objectforkey:@"gt_appid"]
    appkey:[dic objectforkey:@"gt_appkey"]
    appsecret:[dic objectforkey:@"gt_appsecret"]
    delegate:self];
 }
 return self;
}
 
#pragma mark - getuisdkdelegate
/** sdk启动成功返回cid */
- (void)getuisdkdidregisterclient:(nsstring *)clientid {
 // [4-ext-1]: 个推sdk已注册,返回clientid
 nslog(@"\n>>>[getuisdk registerclient]:%@\n\n", clientid);
}
 
/** sdk遇到错误回调 */
- (void)getuisdkdidoccurerror:(nserror *)error {
 // [ext]:个推错误报告,集成步骤发生的任何错误都在这里通知,如果集成后,无法正常收到消息,查看这里的通知。
 nslog(@"\n>>>[gexinsdk error]:%@\n\n", [error localizeddescription]);
}
 
/** sdk收到透传消息回调 */
- (void)getuisdkdidreceivepayload:(nsstring *)payloadid andtaskid:(nsstring *)taskid andmessageid:(nsstring *)amsgid andoffline:(bool)offline fromapplication:(nsstring *)appid {
 // [4]: 收到个推消息
 nsdata *payload = [getuisdk retrivepayloadbyid:payloadid];
 nsstring *payloadmsg = nil;
 if (payload) {
 payloadmsg = [[nsstring alloc] initwithbytes:payload.bytes length:payload.length encoding:nsutf8stringencoding];
 }
 nsstring *msg = [nsstring stringwithformat:@" payloadid=%@,taskid=%@,messageid:%@,payloadmsg:%@%@", payloadid, taskid, amsgid, payloadmsg, offline ? @"<离线消息>" : @""];
 nslog(@"\n>>>[gexinsdk receivepayload]:%@\n\n", msg);
 /**
 *汇报个推自定义事件
 *actionid:用户自定义的actionid,int类型,取值90001-90999。
 *taskid:下发任务的任务id。
 *msgid: 下发任务的消息id。
 *返回值:bool,yes表示该命令已经提交,no表示该命令未提交成功。注:该结果不代表服务器收到该条命令
 **/
 [getuisdk sendfeedbackmessage:90001 taskid:taskid msgid:amsgid];
}
 
/** sdk收到sendmessage消息回调 */
- (void)getuisdkdidsendmessage:(nsstring *)messageid result:(int)result {
 // [4-ext]:发送上行消息结果反馈
 nsstring *msg = [nsstring stringwithformat:@"sendmessage=%@,result=%d", messageid, result];
 nslog(@"\n>>>[gexinsdk didsendmessage]:%@\n\n", msg);
}
 
/** sdk运行状态通知 */
- (void)getuisdkdidnotifysdkstate:(sdkstatus)astatus {
 // [ext]:通知sdk运行状态
 nslog(@"\n>>>[gexinsdk sdkstate]:%u\n\n", astatus);
}
 
/** sdk设置推送模式回调 */
- (void)getuisdkdidsetpushmode:(bool)ismodeoff error:(nserror *)error {
 if (error) {
 nslog(@"\n>>>[gexinsdk setmodeoff error]:%@\n\n", [error localizeddescription]);
 return;
 }
 nslog(@"\n>>>[gexinsdk setmodeoff]:%@\n\n", ismodeoff ? @"开启" : @"关闭");
}
 
-(void)getuiregister{
 
}

然后再appdelegate 调用注册远程推送的方法  

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/** 注册用户通知 */
- (void)registerusernotification {
 /*
 注册通知(推送)
 申请app需要接受来自服务商提供推送消息
 */
 // 判读系统版本是否是“ios 8.0”以上
 if ([[[uidevice currentdevice] systemversion] floatvalue] >= 8.0 ||
 [uiapplication instancesrespondtoselector:@selector(registerusernotificationsettings:)]) {
 // 定义用户通知类型(remote.远程 - badge.标记 alert.提示 sound.声音)
 uiusernotificationtype types = uiusernotificationtypealert | uiusernotificationtypebadge | uiusernotificationtypesound;
 // 定义用户通知设置
 uiusernotificationsettings *settings = [uiusernotificationsettings settingsfortypes:types categories:nil];
 // 注册用户通知 - 根据用户通知设置
 [[uiapplication sharedapplication] registerusernotificationsettings:settings];
 [[uiapplication sharedapplication] registerforremotenotifications];
 } else { // ios8.0 以前远程推送设置方式
 // 定义远程通知类型(remote.远程 - badge.标记 alert.提示 sound.声音)
 uiremotenotificationtype mytypes = uiremotenotificationtypebadge | uiremotenotificationtypealert | uiremotenotificationtypesound;
 // 注册远程通知 -根据远程通知类型
 [[uiapplication sharedapplication] registerforremotenotificationtypes:mytypes];
 }
}

然后再设置了窗口的跟控制器 之后 调用:addpushview方法 添加 消息提示框stpushview:  addpushview实现代码如下 

?
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#pragma mark 推送信息展示
//添加推送view
- (void)addpushview
{
 stpushview *topview = [stpushview shareinstance];
 topview.frame = cgrectmake(0, -pushviewheight, screen_width, pushviewheight);
 [_window addsubview:topview];
 self.topview = topview;
 topview.hidden = yes;
 
 uitapgesturerecognizer *tap = [[uitapgesturerecognizer alloc] initwithtarget:self action:@selector(hudclick)];
 uipangesturerecognizer *pan = [[uipangesturerecognizer alloc] initwithtarget:self action:@selector(pan:)];
 [topview addgesturerecognizer:tap];
 [tap requiregesturerecognizertofail:pan];
 topview.gesturerecognizers = @[tap,pan];
 
}
 
#pragma mark addpushview相关事件
- (void)hudclick
{
 self.topview.userinteractionenabled = no;
 
 [uiview animatewithduration:0.25 animations:^{
 self.topview.frame = cgrectmake(0, -pushviewheight, screen_width, pushviewheight);
 }completion:^(bool finished) {
 [uiapplication sharedapplication].statusbarhidden = no;
 [self hudclickoperation];
 
 }];
}
 
- (void)hudclickoperation
{
 [self push:nil];
 dispatch_after(dispatch_time(dispatch_time_now, (int64_t)(1 * nsec_per_sec)), dispatch_get_main_queue(), ^{
 self.topview.userinteractionenabled = yes;
 });
}
 
 
- (void)pan:(uipangesturerecognizer*)pan
{
 cgfloat distance = pushviewheight-(pushviewheight-[pan translationinview:self.window].y);
 if (distance<-20) {
 [uiview animatewithduration:0.25 animations:^{
  self.topview.frame = cgrectmake(0, -pushviewheight, screen_width, pushviewheight);
 }completion:^(bool finished) {
  [uiapplication sharedapplication].statusbarhidden = no;
 }];
 }
}
 
//显示pushview
- (void)displaypushview
{
 [stpushview show];
}

上面push方法的实现代码如下: 处理逻辑 是根据我自己的项目中需求定的 在这里实现你需要处理的代码

?
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
- (void)push:(nsdictionary *)params{
 
 stpushmodel *model = [ nskeyedunarchiver unarchiveobjectwithfile:krapi_push_data];
 
 //如果是h5
 if ([model.urltype isequaltostring:@"h5"]) {
 
 bool isstore = [[analysisurl sharedinstance] analysisweburl:model.url];
 bool isgoods = [[analysisurl sharedinstance] analysisgoodsidweburl:model.url];
 bool isredbag =[[analysisurl sharedinstance] analyredbagweburl:model.url];
 bool istrace =[[analysisurl sharedinstance] analytracewebur:model.url];
 bool islog =[[analysisurl sharedinstance] analylogweburl:model.url];
 if (isstore || isgoods) {
  [[wypagemanager sharedinstance] pushviewcontrollerwithurlstring:model.url currenturlstring:traker_url_index];
  
 }else if (isredbag)
 {
  redbageviewcontroller * regbag =[[redbageviewcontroller alloc]init];
  nsarray *array = [model.url componentsseparatedbystring:@"="];
  nsstring * string = [array lastobject];
  regbag.messageid = string;
  regbag.redtype = @"coupon";
  uitabbarcontroller *tabvc = (uitabbarcontroller *)self.window.rootviewcontroller;
  uinavigationcontroller *pushclassstance = (uinavigationcontroller *)tabvc.viewcontrollers[tabvc.selectedindex];
  // 跳转到对应的控制器
  regbag.hidesbottombarwhenpushed = yes;
  [pushclassstance pushviewcontroller:regbag animated:yes];
  return;
 }else if (istrace)
 {
  redbageviewcontroller * regbag =[[redbageviewcontroller alloc]init];
  nsstring * string = [strutils getidfromurlstring:model.url interceptstring:@"/trace/"];
  regbag.messageid = string;
  regbag.redtype = @"trace";
  uitabbarcontroller *tabvc = (uitabbarcontroller *)self.window.rootviewcontroller;
  uinavigationcontroller *pushclassstance = (uinavigationcontroller *)tabvc.viewcontrollers[tabvc.selectedindex];
  // 跳转到对应的控制器
  regbag.hidesbottombarwhenpushed = yes;
  [pushclassstance pushviewcontroller:regbag animated:yes];
  return;
 }else if (islog)
 {
  redbageviewcontroller * regbag =[[redbageviewcontroller alloc]init];
  nsstring * string = [strutils getidfromurlstring:model.url interceptstring:@"/log/"];
  regbag.messageid = string;
  regbag.redtype = @"log";
  uitabbarcontroller *tabvc = (uitabbarcontroller *)self.window.rootviewcontroller;
  uinavigationcontroller *pushclassstance = (uinavigationcontroller *)tabvc.viewcontrollers[tabvc.selectedindex];
  // 跳转到对应的控制器
  regbag.hidesbottombarwhenpushed = yes;
  [pushclassstance pushviewcontroller:regbag animated:yes];
  return;
 }
 else{
  if (![model.url isequaltostring:@""]) {
  uistoryboard *setstoryboard = [uistoryboard storyboardwithname:@"usercenter" bundle:nil];
  totalwebviewcontroller *setvc = [setstoryboard instantiateviewcontrollerwithidentifier:@"totalwebviewcontroller"];
  setvc.shopurl = model.url;
  setvc.shoptitle = [model.title isequaltostring:@""] ? @"121店" : model.title;
  uitabbarcontroller *tabvc = (uitabbarcontroller *)self.window.rootviewcontroller;
  uinavigationcontroller *pushclassstance = (uinavigationcontroller *)tabvc.viewcontrollers[tabvc.selectedindex];
  setvc.hidesbottombarwhenpushed = yes;
  [pushclassstance pushviewcontroller:setvc animated:yes];
  }
 }
 }else if ([model.urltype isequaltostring:@"native"]){
  
  if ([model.url isequaltostring:@"1"]) {
  //一元体验购 已经删除
  
  }else if ([model.url isequaltostring:@"2"]){
  if (([[stcommoninfo getauthtype] intvalue] != 1)) {
   [self creategroundglass];
  }else{
   stprofitviewcontroller *vc = [[stprofitviewcontroller alloc] init];
   uitabbarcontroller *tabvc = (uitabbarcontroller *)self.window.rootviewcontroller;
   uinavigationcontroller *pushclassstance = (uinavigationcontroller *)tabvc.viewcontrollers[tabvc.selectedindex];
   vc.hidesbottombarwhenpushed = yes;
   [pushclassstance pushviewcontroller:vc animated:yes];
  }
  }else if ([model.url isequaltostring:@"3"]){
  if (([[stcommoninfo getauthtype] intvalue] != 1)) {
   [self creategroundglass];
  }else{
   
   messagemainvc *messagevc = [[messagemainvc alloc] init];
   messagevc.hidesbottombarwhenpushed = yes;
   uitabbarcontroller *tabvc = (uitabbarcontroller *)self.window.rootviewcontroller;
   uinavigationcontroller *pushclassstance = (uinavigationcontroller *)tabvc.viewcontrollers[tabvc.selectedindex];
   [pushclassstance pushviewcontroller:messagevc animated:yes];
  }
  }else if ([model.url hasprefix:@"http://"]&&([model.url rangeofstring:@"client"].location!=nsnotfound)){ //跳转到客服接 界面
  
  nsstring *orgidstring =[[analysisurl sharedinstance] extractorgid:model.url];
  nsstring *siteidstring = [[analysisurl sharedinstance] extractorgidstoreid:model.url];
  [[wypagemanager sharedinstance] pushviewcontroller:@"tlchatviewcontroller" withparam:
   @{
   @"title_namestring":@"官方客服",
   @"orgidstring":orgidstring,
   @"siteidstring":siteidstring,
   @"currenturl":model.url
   } animated:yes];
  
  }
 }
}

然后再appdelegate 实现以下方法

?
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/** 自定义:app被“推送”启动时处理推送消息处理(app 未启动--》启动)*/- (void)receivenotificationbylaunchingoptions:(nsdictionary *)launchoptions {
 if (!launchoptions)
 return;
 /*
 通过“远程推送”启动app
 uiapplicationlaunchoptionsremotenotificationkey 远程推送key
 */
 nsdictionary *userinfo = [launchoptions objectforkey:uiapplicationlaunchoptionsremotenotificationkey];
 if (userinfo) {
 nslog(@"\n>>>[launching remotenotification]:%@", userinfo);
 }
}
 
#pragma mark - 用户通知(推送)回调 _ios 8.0以上使用
 
/** 已登记用户通知 */
- (void)application:(uiapplication *)application didregisterusernotificationsettings:(uiusernotificationsettings *)notificationsettings {
 // 注册远程通知(推送)
 [application registerforremotenotifications];
}
 
#pragma mark - 远程通知(推送)回调
 
/** 远程通知注册成功委托 */
- (void)application:(uiapplication *)application didregisterforremotenotificationswithdevicetoken:(nsdata *)devicetoken {
 nsstring *mytoken = [[devicetoken description] stringbytrimmingcharactersinset:[nscharacterset charactersetwithcharactersinstring:@"<>"]];
 mytoken = [mytoken stringbyreplacingoccurrencesofstring:@" " withstring:@""];
 nsuserdefaults *kr = [nsuserdefaults standarduserdefaults];
 [kr setvalue:mytoken forkey:@"devicetoken"];
 [kr synchronize];
 [getuisdk registerdevicetoken:mytoken];
 [[postdevicetoken sharedinstance] postupdevicetoken];
 nslog(@"\n>>>[devicetoken success]:%@\n\n", mytoken);
}
 
/** 远程通知注册失败委托 */
- (void)application:(uiapplication *)application didfailtoregisterforremotenotificationswitherror:(nserror *)error {
 [getuisdk registerdevicetoken:@""];
 nslog(@"\n>>>[devicetoken error]:%@\n\n", error.description);
}
 
 
#pragma mark - app运行中接收到通知(推送)处理
/** app已经接收到“远程”通知(推送) - 透传推送消息 */
- (void)application:(uiapplication *)application didreceiveremotenotification:(nsdictionary *)userinfo fetchcompletionhandler:(void (^)(uibackgroundfetchresult result))completionhandler {
 // 处理apn
 nslog(@"\n>>>[receive remotenotification - background fetch]:%@\n\n", userinfo);
 completionhandler(uibackgroundfetchresultnewdata);
 
 nsstring *payloadstring = [[myprevent sharedinstance] dictionary:userinfo objectforkey:@"payload"];
 [[spotpunch sharedinstance] spotpunch:@"999.999.1" pointtwo:@"21" info:payloadstring];
 // nsuserdefaults *kr = [nsuserdefaults standarduserdefaults];
 if (!([[stcommoninfo getauthtype] intvalue] != 1)) {
 nsdata *jsondata = [payloadstring datausingencoding:nsutf8stringencoding];
 nsdictionary *jsondic = [nsjsonserialization jsonobjectwithdata:jsondata
        options:nsjsonreadingmutablecontainers
         error:nil];
 
 stpushmodel *model = [stpushmodel modelobjectwithdict:jsondic];
 [nskeyedarchiver archiverootobject:model tofile:krapi_push_data];
//如果应用程序在前台 就显示客服提示框
 if (application.applicationstate == uiapplicationstateactive) {
  self.topview.model = model;
  [self displaypushview]; //此方法 的实现 在上一步中 就是展示提示框出来
 }
 
 
 }
}

然后这些工作做好了之后 就是你需要在个推的后台 配置推送证书  这个配置的步骤 大家可以到个推官网去参考文档 配置  

这里我假设 你已经配置到证书了  经过上面的步骤 我们的远程推送通知的方法 基本完成 现在我们运行 测试下 你会发现即使在前台 有新消息推送的时候 顶部也会弹出和系统一样的提示框 点击 跳转到对应的页面的方法逻辑根据你的需要 去做跳转处理 

测试效果如下:

用户在后台 收到的消息提示如下:

iOS自定义推送消息提示框

用户在前台 收到的消息提示如下:

iOS自定义推送消息提示框

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

延伸 · 阅读

精彩推荐
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28
  • IOS关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01
  • IOSiOS布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25