推送证书

推送证书

0
评论

源码下载:全国首个直播答题开源项目了解一下!!!(基于环信即时通讯云) 直播答题 开源项目

beyond 发表了文章 • 863 次浏览 • 2018-03-06 18:10 • 来自相关话题

2018年伊始,全民直播答题浪潮来袭,一度被认为是一个新的互联网风口,王思聪凭借在现象级产品《冲顶大会》上疯狂"撒币"一时风光无二,凭借超高奖金和超低门槛吸引了大量网民参与和市场的目光。正因为直播答题是一种通过极低的成本来推动APP获客、保留存、拉活跃的新模式,各类直播答题APP如雨后春笋般进入大家的视野,越来越多企业希望赶上这波风口,快速搭建一套直播答题系统。作为一名环信生态圈资深开发者,本着对技术的热衷,对环信的眷恋和对党的忠诚,基于环信即时通讯云写了“小信竞答”这个直播答题开源项目,目前项目源码已全部免费开放,希望对有需求的企业和开发者提供一个思路和参考。



 

[b]


[/b]
 
小信竞答技术架构图:



     整个项目分为管理员端,观众端和服务端,首先在服务端预设好题目,由管理员发起直播开始答题,服务端收到指令将12道题目利用环信IM推送到观众端,观众端收到题目开始答题,将答案返回给服务端由服务端进行判断,如果答题正确进入下一题,答题错误判断是否使用复活卡,这里要注意的是需要加一个复活卡的使用次数判断。
 
   在整个答题过程中,管理员端会定时去服务端查询答题结果,等到全部答题结束,点击结束本次答题,服务端将计算好的结果返回并发放奖金,使用环信IM推送将答题结果推给观众端。
 
小信竞答效果图




关于直播间:
   直播间由直播画面和聊天室两个部分组成,“小信竞答”的聊天室使用环信聊天室,集成比较简单,基础版就能支持5000人在线聊天,增值服务版聊天室人数无上限,可以去环信官网注册一个开发者账号,创建应用将APPKEY替换成自己的;环信直播聊天室可以集成所有市场主流CDN厂商的推拉流功能(腾讯,七牛,UCloud,网宿等)。
 
环信直播聊天室特点  
This is Title
 
1、采用支持高并发的异步架构,轻松应对千万级并发请求; 各项基础服务集群化,确保系统高可用性; 系统冗余度高,容量评估体系完善,弹性扩容应对流量峰值;
2、支持各种消息格式:文字、表情、图片、声音、视频、附件、位置、扩展消息;
3、支持实时配置的消息分级策略,确保重要消息优先必达; 
4、支持直播聊天室后台管理及审核功能,提供直播相关数据统计;
5、提供智能反垃圾和自定义敏感词过滤功能;
6、快速集成,demo提供高质量代码示例,可根据运营情况随时扩展;
7、聊天室人数无上限 
小信竞答项目源码: github源码地址
 
写到最后:
   
     小信竞答源码全部开放,仅供学习和参考,如果作为商业用途,按照广电总局对网络直播答题节目管理的,需要 “网络视听许可证、主持人持证、还有通过审批发放的节目备案号”,三证缺一不可,未持有《信息网络传播视听节目许可证》的任何机构和个人,一律不得开办网络直播答题节目。
 
本月底《环信公开课第19期-直播答题开源项目》将线上讲解“小信竞答”实现思路,手把手教您从零开始搭建一个直播答题项目,扫码加入公开课微信群与大牛面对面交流。




  查看全部
   2018年伊始,全民直播答题浪潮来袭,一度被认为是一个新的互联网风口,王思聪凭借在现象级产品《冲顶大会》上疯狂"撒币"一时风光无二,凭借超高奖金和超低门槛吸引了大量网民参与和市场的目光。正因为直播答题是一种通过极低的成本来推动APP获客、保留存、拉活跃的新模式,各类直播答题APP如雨后春笋般进入大家的视野,越来越多企业希望赶上这波风口,快速搭建一套直播答题系统。作为一名环信生态圈资深开发者,本着对技术的热衷,对环信的眷恋和对党的忠诚,基于环信即时通讯云写了“小信竞答”这个直播答题开源项目,目前项目源码已全部免费开放,希望对有需求的企业和开发者提供一个思路和参考。



 

[b]
微信图片_20180316190105.jpg
[/b]
 
小信竞答技术架构图:
theFlowChart.png

     整个项目分为管理员端,观众端和服务端,首先在服务端预设好题目,由管理员发起直播开始答题,服务端收到指令将12道题目利用环信IM推送到观众端,观众端收到题目开始答题,将答案返回给服务端由服务端进行判断,如果答题正确进入下一题,答题错误判断是否使用复活卡,这里要注意的是需要加一个复活卡的使用次数判断。
 
   在整个答题过程中,管理员端会定时去服务端查询答题结果,等到全部答题结束,点击结束本次答题,服务端将计算好的结果返回并发放奖金,使用环信IM推送将答题结果推给观众端。
 
小信竞答效果图

微信图片_20180316190206.jpg


关于直播间:
   直播间由直播画面和聊天室两个部分组成,“小信竞答”的聊天室使用环信聊天室,集成比较简单,基础版就能支持5000人在线聊天,增值服务版聊天室人数无上限,可以去环信官网注册一个开发者账号,创建应用将APPKEY替换成自己的;环信直播聊天室可以集成所有市场主流CDN厂商的推拉流功能(腾讯,七牛,UCloud,网宿等)。
 
环信直播聊天室特点  
This is Title
 
1、采用支持高并发的异步架构,轻松应对千万级并发请求; 各项基础服务集群化,确保系统高可用性; 系统冗余度高,容量评估体系完善,弹性扩容应对流量峰值;
2、支持各种消息格式:文字、表情、图片、声音、视频、附件、位置、扩展消息;
3、支持实时配置的消息分级策略,确保重要消息优先必达; 
4、支持直播聊天室后台管理及审核功能,提供直播相关数据统计;
5、提供智能反垃圾和自定义敏感词过滤功能;
6、快速集成,demo提供高质量代码示例,可根据运营情况随时扩展;
7、聊天室人数无上限 
小信竞答项目源码: github源码地址
 
写到最后:
   
     小信竞答源码全部开放,仅供学习和参考,如果作为商业用途,按照广电总局对网络直播答题节目管理的,需要 “网络视听许可证、主持人持证、还有通过审批发放的节目备案号”,三证缺一不可,未持有《信息网络传播视听节目许可证》的任何机构和个人,一律不得开办网络直播答题节目。
 
本月底《环信公开课第19期-直播答题开源项目》将线上讲解“小信竞答”实现思路,手把手教您从零开始搭建一个直播答题项目,扫码加入公开课微信群与大牛面对面交流。
微信图片_20180316190334.jpg

 
8
回复

收集基于环信SDK开发的开源项目 开源项目

JuN_Yong Wang 回复了问题 • 10 人关注 • 6926 次浏览 • 2018-02-07 11:49 • 来自相关话题

10
评论

【新手快速入门】集成环信常见问题+解决方案汇总 常见问题

dujiepeng 发表了文章 • 11057 次浏览 • 2017-05-22 15:51 • 来自相关话题

   这里整理了集成环信的常见问题和一些功能的实现思路,希望能帮助到大家。感谢热心的开发者贡献,大家在观看过程中有不明白的地方欢迎直接跟帖咨询。
 
ios篇
APNs证书创建和上传到环信后台头像昵称的简述和处理方案音视频离线推送Demo实现环信服务器聊天记录保存多久?离线收不到好友请求IOS中环信聊天窗口如何实现文件发送和预览的功能ios集成常见问题环信推送的一些常见问题实现名片|红包|话题聊天室等自定义cell
 
Android篇
Android sdk 的两种导入方式环信3.0SDK集成小米推送教程EaseUI库中V4、v7包冲突解决方案Android EaseUI里的百度地图替换为高德地图android扩展消息(名片集成)关于会话列表的置顶聊天java.lang.UnsatisfiedLinkError: 的问题android 端 app 后台被杀死收不到消息的解决方案
昵称头像篇
android中如何显示开发者服务器上的昵称和头像 Android中显示头像(接上一篇文章看)环信(Android)设置头像和昵称的方法(最简单暴力的基于环信demo的集成)IOS中如何显示开发者服务器上的昵称和头像【环信公开课第12期视频回放】-所有关于环信IM昵称头像的问题听这课就够了
 
直播篇
一言不合你就搞个直播APP
 
客服集成
IM-SDK和客服SDK并存开发指南—Android篇IM-SDK和客服SDK并存开发指南—iOS篇
 
开源项目
Android简版demoios简版demo凡信2.0:超仿微信的开源项目 凡信3.0:携直播和红包而来高仿微信:Github 3,515 Star方圆十里:环信编程大赛冠军项目泛聊:定一个小目标写一个QQSlack聊天机器人:一天时间做一个聊天机器人TV视频通话:在电视上视频通话视频通话:Android手机视频通话酷信:ios高仿微信公众号助手:与订阅用户聊天沟通
 
持续更新ing...小伙伴们还有什么想知道欢迎跟帖提出。
  查看全部
   这里整理了集成环信的常见问题和一些功能的实现思路,希望能帮助到大家。感谢热心的开发者贡献,大家在观看过程中有不明白的地方欢迎直接跟帖咨询。
 
ios篇

 
Android篇

昵称头像篇

 
直播篇
  1. 一言不合你就搞个直播APP

 
客服集成
  1. IM-SDK和客服SDK并存开发指南—Android篇
  2. IM-SDK和客服SDK并存开发指南—iOS篇

 
开源项目

 
持续更新ing...小伙伴们还有什么想知道欢迎跟帖提出。
 
0
回复

android消息推送 非华为小米怎么配置 环信_Android 推送 android 推送证书 推送证书管理

回复

xuzheng 发起了问题 • 1 人关注 • 96 次浏览 • 2018-04-13 11:05 • 来自相关话题

1
评论

【环信征文】| iOS集成环信推送,最详细流程(证书创建、环信集成、测试) 环信iOS 环信iOS真机调试 环信 JPush 推送 iOS 推送证书

奔跑的虫子 发表了文章 • 256 次浏览 • 2018-01-31 10:41 • 来自相关话题

这几天项目里又用到了环信的推送,虽然之前做过,但是很久不做还是有很多细节没有注意到,所以还是决定从头开始做一遍,把每一个环节都详细记录下来,同样的把每一个坑也记录下来.方便自己以后做的时候忘记哪个流程了可以在看一遍.我很能理解那种遇到问题网上百度一堆类似答案但是并不好使的情况,所以我会将我在项目中遇到的问题都贴出来,希望能给大家带来些许参考和帮助,

一.推送的原理和流程(着急做推送的可以跳过这一步)
首先给大家推荐一个介绍推送机制很优秀的帖子:http://www.jianshu.com/p/e347f999ed95 ,里面关于本地推送和远程推送的介绍都很详细,至少我看了感觉还是收获很多的.尤其是里面有几张图片不知道是博主在哪里找的,但是真的是一看就透,太赞了,所以我果断盗过来了0.0. 这里我对推送的流程做了一个简单的叙述,力求用最简单的语言能说明整个推送的机制.

先搬过来一张图再说






再搬一张:







当我们的苹果手机联网的时候,会自动与苹果的服务器建立长连接,长连接的好处有很多,比如系统升级、时间校准、数据传输和响应比较快以及数据可以保持最新状态等功能.上面这两张图片简单的讲述了推送的流程:

- 1.首先我们需要将自己设备的UDID和应用的Bundle Identifier发送到苹果的服务器,然后苹果的服务器会返回给我们一个DeviceToken,这个在我看来就是创建推送证书和描述文件的过程.
- 2.我们将包含手机和应用标示的打包文件上传到做推送的服务器上去,当我们从推送服务器的后台发起推送消息的时候,推送服务器会将我们的DeviceToken和需要发送的消息Message发送到苹果的APNS(Apple push Notification Service)服务器.
- 3.当苹果的服务器收到DeviceToken和需要发送的消息Message时,会根据DeviceToken中的UDID查找设备,根据DeviceToken中的Bundle Identfier查找该应用,并将Message发送到该设备上.

下面是以QQ服务器为栗子说明的即时通讯的机制:






图片已经说得够详细明了了,我就不插嘴了,下面开始我们的工程.

二.具体流程

我们创建一个名为TestDemo的工程,我是使用Xcode8.1来开发的,工程名为PushDemo,创建好的工程界面如下(Xcode8)






从Xcode8之后,Xcode提供了自动管理证书的功能,这个用起来很方便,我目前在工程中用到的最多的地方就是创建好一个Demo之后,如果想真机运行的话,那么只需要在Team选择框里选择我的开发账户,接下来下面会出现一个加载提示圈,等它加载完了就可以在真机上运行了,这个过程实际上是Xcode使用你当前的BundleId去该账户的开发这中心创建了对应的AppId和描述文件,但是我们既然是作为一个开发流程的记录,就自己来创建这些东西,所以,我们取消选择Automatically manage signing选项.此时界面如下:







好了,我们要正式开始我们的工作了GO GO GO!
1. 首先我们先去官网创建AppID和描述文件.      

我们是要集成推送的,所以我们需要用到cer文件,这个东西实际上就是苹果给开发者颁发的一个证书,我们需要将它导入到我们的AppId配置里,否则的话是无法集成推送的,还记得安装应该的时候会提示"无法安装为认证发布者的应用"之类的信息么,我猜测这个cer文件就是我们身份的标示,使我们开发的应用可以供人们正常安装使用,关于证书有一篇很详细的帖子,希望了解证书之类信息的看官可以去瞅瞅:http://m.blog.csdn.net/article/details?id=8617788

创建cer文件的流程很简单,打开"钥匙串访问"(虽然很好找,但是还是把图贴出来吧,怕小朋友迷路)













打开钥匙串之后点击"从证书颁发机构请求证书"







邮箱和常用名随便填写,记住下面的选择框选择"存储到磁盘"







点击存储







已经在桌面保存了








到此,我们已经创建好了cer文件,接着我们去开发者中心创建AppId和描述文件

2. 创建AppId和描述文件

首先进入开发者中心,百度搜索Apple Developer,(哎 真的是详细到家了啊,我都人不下去了)
上图







输入开发者账户,登录进去







你将看到这个页面







点击看到:






输入AppId文件名和BundleId






选中下面的PushNotifications






点击Continue:






点击register:






点击Done回到AppId列表页面






在AppId列表页面可以看到我们的AppID了







但是,还没有完成,因为我们是要做推送的,所以需要上传我们的cer文件
,点击我们的AppId,在展开的详情里可以看到:








Push Notification的两个指示灯还是黄色的状态,我们要将它启用,点击Edit,在点开的页面里滑动至底部,记得要选中Push Notification按钮,接着点击上方的开发证书下的创建证书按钮:







点击Continue







点击 choose file:







将我们从开发机构请求的证书传上去,之后点击Register:







点击Register之后的页面,点击download,将其下载到桌面上,download之后记得点击done完成文件创建:







桌面上的文件:







现在我们就完成了给AppID创建开发者证书,然后我们要给它创建发布者证书,点击Done之后回到AppIds列表,如果找不到的话,点击右边的App IDs







点开项目的AppId,此时界面如下,点击最下面的CreateCertificate,开始给AppID创建发布者证书,给AppId创建发布者证书流程跟创建开发者证书是一样的!给AppId创建发布者证书流程跟创建开发者证书是一样的!给AppId创建发布者证书流程跟创建开发者证书是一样的!重要的事情说三遍!!因为我不贴出来创建发布证书的图了,所以各位根据创建开发证书的流程再走一遍就好,同样也要将发布者证书下载到本地.:













当创建好之后在回到这个页面时,应该显示如下所示:







此时本地我们下载的文件如下:







然后将这两个证书拖到钥匙串里,步骤如下:
首先打开钥匙串:












然后先点击:系统-证书,然后将两个文件拖进去,会提示你输入开机密码,输入就好了(建议添加之前先对这个界面截屏,添加完之后可以对比刚刚添加了那些文件)







添加完之后是这个样子,画框的是我们的证书







然后选择左边的"登录"选项,可以看到我们刚才创建的证书






选中第一个证书,然后右键(你懂得右键的意思),选择导出...







选择导出为P12文件,存储在桌面上,获取到P12文件.对这两个证书进行同样的操作.(记得标题有(Develop)的起名为Product文件,第二个证书导出的时候起名为Develop,名字可以自己定,只是为了区别)






然后会提示你输入密码,这里我设置的密码是zx123456,自己设定好一定要记住,一会儿要用.






然后可以在桌面上看到我们导出的P12文件啦







现在我们就完成了所有的证书的创建,可以去环信上创建我们的应用啦.

3.创建真机调试文件以及导入到项目中

因为必须要进行真机测试,而且我们关闭了自动管理证书,就导致Xcode8不会自动帮我们生成证书,所以我们要自己创建真机调试证书并导入到项目中去,流程如下:

创建描述文件:







选择开发模式,下一步:







选择对应的AppID,选择我们刚才创建的AppId:







选择开发团队,我一般都是全选的,下一步:







选择真机调试的机器,全选,下一步:







下一步:







将创建好的描述文件下载下来,放到桌面上:







创建好的描述文件:







首先选择debug模式下载的真机调试描述文件:






选择桌面上刚刚下载的描述文件:







使用同样的步骤,选择Release模式下的真机调试文件,一模一样的操作,不贴图了.两个文件都导入进去之后,插上真机,就可以进行真机调试了.

4.在环信创建我们的应用

首先百度搜索环信,打开他们的官网,先注册账户,注册过的可以跳过了,上图:
注册的时候选择"注册即时通讯云"







注册的时候需要填写各种信息,按照格式填写就好了,填写完之后登陆,点击创建应用







填写应用信息







填写完如下图咯







然后需要上传我们的P12文件,图片很清晰- -,不多说,第一次我选择上传的是生产证书:







第二次上传开发证书:







至此,我们的证书开发也都上传完了,路漫漫其修远兮,开始集成环信到代码里吧

5.集成环信到项目中

首先在这里下载最新的SDK(截至到写本文时最新的SDK为)

http://www.easemob.com/download/im 环信推送SDK下载链接

点击iOS的最新SDK下载,这里下载的是V3.x的SDK







下载到桌面是这个鬼样子







我们只需要将画圈的两个文件夹导进去工程里就好了,其他的用不上







导进去之后文件列表是这样,编译会出错别急,慢慢改.







向项目里添加需要的库







上面的图片是截取的环信官方文档,我添加完是这个样子的:






方便复制库名的文字:
CoreMedia.framework
AudioToolbox.framework
AVFoundation.framework
MobileCoreServices.framework
ImageIO.framework
libc++.dylib
libz.dylib
libstdc++.6.0.9.dylib
libsqlite3.dylib
(如果使用的是 xcode7,后缀为 tbd。)
这一步很重要,因为SDK 不支持 bitcode,所以要将 Build Settings → Linking → Enable Bitcode 中设置 NO。








command+B编译工程,大量爆红.别着急,修改我们的PCH文件就好了
在PCH文件添加
```
#ifdef __OBJC__
    #import <UIKit/UIKit.h>
#endif
```

将我们所有定义和添加的头文件和宏定义,都放在#ifdef __OBJC__和#endif中间
就可以解决这个问题.

然后在项目里打开推送:







6.测试是否集成成功

首先,我们去环信的后台给我们的应用添加一个用户







用户名我设置成了:13051698888  密码设置成了:222222







接着我们要去appledate.m文件里添加东西了,很重要一步,废话不多说,直接贴出来需要配置的代码,直接拿去用0.0,需要添加的东西我在注释里注释的很明白...
记得要导进去头文件
#import "EMSDK.h"

```
@interface AppDelegate ()<EMChatManagerDelegate>

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //AppKey:注册的AppKey,点击"应用概述"可以看到AppKey,粘贴过来就可以。
    //apnsCertName:推送证书名,填写你的开发证书或者发布证书名,就是上传到环信后台的两个中的一个,什么环境下测试使用什么环境的证书。
    EMOptions *options = [EMOptions optionsWithAppkey:@"1192161108178165#testpushdemo"];
    options.apnsCertName = @"Develop";
    [[EMClient sharedClient] initializeSDKWithOptions:options];

    //登录环信 这里使用的是我刚才在环信后台创建的账户名和密码,使用这个账户登录,到时候如果在后台给客户端发消息的话,就可以找到该用户
    [[EMClient sharedClient] loginWithUsername:@"13051698888"
                                      password:@"222222"
                                    completion:^(NSString *aUsername, EMError *aError) {
                                        if (!aError) {
                                            NSLog(@"环信登陆成功");
                                            EMPushOptions *emoptions = [[EMClient sharedClient] pushOptions];
                                            //设置有消息过来时的显示方式:1.显示收到一条消息 2.显示具体消息内容.
                                            //自己可以测试下
                                            emoptions.displayStyle = EMPushDisplayStyleSimpleBanner;
                                            [[EMClient sharedClient] updatePushOptionsToServer];
                                        } else {
                                            NSLog(@"环信登陆失败");
                                        }
                                    }];
    
    
    /**
     注册APNS离线推送  iOS8 注册APNS
     */
    if ([application respondsToSelector:@selector(registerForRemoteNotifications)]) {
        [application registerForRemoteNotifications];
        UIUserNotificationType notificationTypes = UIUserNotificationTypeBadge |
        UIUserNotificationTypeSound |
        UIUserNotificationTypeAlert;
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:notificationTypes categories:nil];
        [application registerUserNotificationSettings:settings];
    }
    else{
        UIRemoteNotificationType notificationTypes = UIRemoteNotificationTypeBadge |
        UIRemoteNotificationTypeSound |
        UIRemoteNotificationTypeAlert;
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:notificationTypes];
    }
    
    //添加监听在线推送消息
   [[EMClient sharedClient].chatManager addDelegate:self delegateQueue:nil];    
    return YES;
}

//监听环信在线推送消息
- (void)messagesDidReceive:(NSArray *)aMessages{
    
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"收到环信通知" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
        [alertView show];
        
        //aMessages是一个对象,包含了发过来的所有信息,怎么提取想要的信息我会在后面贴出来.
}

// 将得到的deviceToken传给SDK
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
    [[EMClient sharedClient] bindDeviceToken:deviceToken];
}

// 注册deviceToken失败
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
    NSLog(@"error -- %@",error);
}

// APP进入后台
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [[EMClient sharedClient] applicationDidEnterBackground:application];
}

// APP将要从后台返回
- (void)applicationWillEnterForeground:(UIApplication *)application
{
    [[EMClient sharedClient] applicationWillEnterForeground:application];
}
```
上面的几个方法在appdelegate里是必须重写的,不然会直接导致推送不成功.其中.需要重点说明的是:

- 只有在应用完全退出被杀掉的状态下,才可以收到环信推送的通知;
- 如果要发送在线的通知,需要在messagesDidReceive方法里获取到环信推送的消息之后给用户发起一个本地通知,这个大家可以自己研究下.
- 通过设置emoptions.displayStyle = EMPushDisplayStyleSimpleBanner;(上面代码有)可以设置有通知过来的时候的显示方式,显示一个提示或者显示完整的消息.
- 上传证书下面填写的应用包名,指的是你的BundleID !!!!我在这里踩了坑,切记!!.

测试推送:
1. 在应用完全退出的情况下(使用在环信注册的账户登录一次,确认登录成功之后再完全退出),选中我们的用户,点击发送消息:







点击发送:







测试结果:








2.程序在线的时候测试推送,还是发送"你好啊",然后我们在messagesDidReceive拦截环信的EMMessage对象,针对EMMessage对象的解析方式如下,完整的抽取环信推送消息的方法:
```
- (void)messagesDidReceive:(NSArray *)aMessages{
    
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"收到环信通知" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
        [alertView show];
    
        for (EMMessage *message in aMessages) {
            EMMessageBody *msgBody = message.body;
            switch (msgBody.type) {
                case EMMessageBodyTypeText:
                {
                    // 收到的文字消息
                    EMTextMessageBody *textBody = (EMTextMessageBody *)msgBody;
                    NSString *txt = textBody.text;
                    NSLog(@"收到的文字是 txt -- %@",txt);
                }
                    break;
                case EMMessageBodyTypeImage:
                {
                    // 得到一个图片消息body
                    EMImageMessageBody *body = ((EMImageMessageBody *)msgBody);
                    NSLog(@"大图remote路径 -- %@"   ,body.remotePath);
                    NSLog(@"大图local路径 -- %@"    ,body.localPath); // // 需要使用sdk提供的下载方法后才会存在
                    NSLog(@"大图的secret -- %@"    ,body.secretKey);
                    NSLog(@"大图的W -- %f ,大图的H -- %f",body.size.width,body.size.height);
                    NSLog(@"大图的下载状态 -- %u",body.downloadStatus);
    
    
                    // 缩略图sdk会自动下载
                    NSLog(@"小图remote路径 -- %@"   ,body.thumbnailRemotePath);
                    NSLog(@"小图local路径 -- %@"    ,body.thumbnailLocalPath);
                    NSLog(@"小图的secret -- %@"    ,body.thumbnailSecretKey);
                    NSLog(@"小图的W -- %f ,大图的H -- %f",body.thumbnailSize.width,body.thumbnailSize.height);
                    NSLog(@"小图的下载状态 -- %u",body.thumbnailDownloadStatus);
                }
                    break;
                case EMMessageBodyTypeLocation:
                {
                    EMLocationMessageBody *body = (EMLocationMessageBody *)msgBody;
                    NSLog(@"纬度-- %f",body.latitude);
                    NSLog(@"经度-- %f",body.longitude);
                    NSLog(@"地址-- %@",body.address);
                }
                    break;
                case EMMessageBodyTypeVoice:
                {
                    // 音频sdk会自动下载
                    EMVoiceMessageBody *body = (EMVoiceMessageBody *)msgBody;
                    NSLog(@"音频remote路径 -- %@"      ,body.remotePath);
                    NSLog(@"音频local路径 -- %@"       ,body.localPath); // 需要使用sdk提供的下载方法后才会存在(音频会自动调用)
                    NSLog(@"音频的secret -- %@"        ,body.secretKey);
                    NSLog(@"音频文件大小 -- %lld"       ,body.fileLength);
                    NSLog(@"音频文件的下载状态 -- %u"   ,body.downloadStatus);
                    NSLog(@"音频的时间长度 -- %u"      ,body.duration);
                }
                    break;
                case EMMessageBodyTypeVideo:
                {
                    EMVideoMessageBody *body = (EMVideoMessageBody *)msgBody;
    
                    NSLog(@"视频remote路径 -- %@"      ,body.remotePath);
                    NSLog(@"视频local路径 -- %@"       ,body.localPath); // 需要使用sdk提供的下载方法后才会存在
                    NSLog(@"视频的secret -- %@"        ,body.secretKey);
                    NSLog(@"视频文件大小 -- %lld"       ,body.fileLength);
                    NSLog(@"视频文件的下载状态 -- %u"   ,body.downloadStatus);
                    NSLog(@"视频的时间长度 -- %u"      ,body.duration);
                    NSLog(@"视频的W -- %f ,视频的H -- %f", body.thumbnailSize.width, body.thumbnailSize.height);
    
                    // 缩略图sdk会自动下载
                    NSLog(@"缩略图的remote路径 -- %@"     ,body.thumbnailRemotePath);
                    NSLog(@"缩略图的local路径 -- %@"      ,body.thumbnailLocalPath);
                    NSLog(@"缩略图的secret -- %@"        ,body.thumbnailSecretKey);
                    NSLog(@"缩略图的下载状态 -- %u"      ,body.thumbnailDownloadStatus);
                }
                    break;
                case EMMessageBodyTypeFile:
                {
                    EMFileMessageBody *body = (EMFileMessageBody *)msgBody;
                    NSLog(@"文件remote路径 -- %@"      ,body.remotePath);
                    NSLog(@"文件local路径 -- %@"       ,body.localPath); // 需要使用sdk提供的下载方法后才会存在
                    NSLog(@"文件的secret -- %@"        ,body.secretKey);
                    NSLog(@"文件文件大小 -- %lld"       ,body.fileLength);
                    NSLog(@"文件文件的下载状态 -- %u"   ,body.downloadStatus);
                }
                    break;
                    
                default:
                    break;
            }
        }
}
```

发送成功之后打印结果如下:
```
2016-12-01 16:03:26.060088 PushDemo[1392:450230] 收到的文字是 txt -- 你好啊
```
三.结语

至此,我们就成功集成了环信推送到我们的项目中.另外提供一些在做推送的时候经常会用到的小方法
- 设置应用图标右上角数字角标.
```
UIApplication *application = [UIApplication sharedApplication]; [application setApplicationIconBadgeNumber:3];
```
补充一个环信坑:
编译通过后,运行的时候爆炸,提示:dyld: Library not loaded: @rpath/Hyphenate.framework/Hyphenate
需要设置Hyphenate.frameword的Embedded Binariew属性








- 如果推送证书那里没看特别明白的话,提供一个创建推送证书的链接:http://www.jianshu.com/p/78282e16db66


- 设置推送过来时候的_apns_昵称:
```
[[EMClient sharedClient] setApnsNickname:@"推送昵称"];
```

一直在抽时间写这篇博客,平常比较忙没有大块的时间来写和记录这些东西,不过东拼西凑,没事写一点最终还是写完了.希望看到这里的小伙伴都可以成功集成环信推送,有问题可以在下面留言,我看到了肯定会回复的.希望围观的小伙伴可以不吝指点这篇博客中出现的错误,不管是文字错误还是逻辑错误等等,我一定会尽快修正,不给后人留坑.....

给出项目gitHub地址:
https://github.com/TheRuningAnt/PushDemo.git  喜欢的话,记得给小星星哈

排版可能有点问题,原博客地址:http://blog.csdn.net/mumubumao ... 23393
  查看全部
这几天项目里又用到了环信的推送,虽然之前做过,但是很久不做还是有很多细节没有注意到,所以还是决定从头开始做一遍,把每一个环节都详细记录下来,同样的把每一个坑也记录下来.方便自己以后做的时候忘记哪个流程了可以在看一遍.我很能理解那种遇到问题网上百度一堆类似答案但是并不好使的情况,所以我会将我在项目中遇到的问题都贴出来,希望能给大家带来些许参考和帮助,

一.推送的原理和流程(着急做推送的可以跳过这一步)
首先给大家推荐一个介绍推送机制很优秀的帖子:http://www.jianshu.com/p/e347f999ed95 ,里面关于本地推送和远程推送的介绍都很详细,至少我看了感觉还是收获很多的.尤其是里面有几张图片不知道是博主在哪里找的,但是真的是一看就透,太赞了,所以我果断盗过来了0.0. 这里我对推送的流程做了一个简单的叙述,力求用最简单的语言能说明整个推送的机制.

先搬过来一张图再说

692194-fc99211b942ffb8c.png


再搬一张:

692194-a1764a5b6ef76592.png



当我们的苹果手机联网的时候,会自动与苹果的服务器建立长连接,长连接的好处有很多,比如系统升级、时间校准、数据传输和响应比较快以及数据可以保持最新状态等功能.上面这两张图片简单的讲述了推送的流程:

- 1.首先我们需要将自己设备的UDID和应用的Bundle Identifier发送到苹果的服务器,然后苹果的服务器会返回给我们一个DeviceToken,这个在我看来就是创建推送证书和描述文件的过程.
- 2.我们将包含手机和应用标示的打包文件上传到做推送的服务器上去,当我们从推送服务器的后台发起推送消息的时候,推送服务器会将我们的DeviceToken和需要发送的消息Message发送到苹果的APNS(Apple push Notification Service)服务器.
- 3.当苹果的服务器收到DeviceToken和需要发送的消息Message时,会根据DeviceToken中的UDID查找设备,根据DeviceToken中的Bundle Identfier查找该应用,并将Message发送到该设备上.

下面是以QQ服务器为栗子说明的即时通讯的机制:

692194-42cd5b5723039e84.png


图片已经说得够详细明了了,我就不插嘴了,下面开始我们的工程.

二.具体流程

我们创建一个名为TestDemo的工程,我是使用Xcode8.1来开发的,工程名为PushDemo,创建好的工程界面如下(Xcode8)

1232108-fecb3186b8c4700d.png


从Xcode8之后,Xcode提供了自动管理证书的功能,这个用起来很方便,我目前在工程中用到的最多的地方就是创建好一个Demo之后,如果想真机运行的话,那么只需要在Team选择框里选择我的开发账户,接下来下面会出现一个加载提示圈,等它加载完了就可以在真机上运行了,这个过程实际上是Xcode使用你当前的BundleId去该账户的开发这中心创建了对应的AppId和描述文件,但是我们既然是作为一个开发流程的记录,就自己来创建这些东西,所以,我们取消选择Automatically manage signing选项.此时界面如下:

1232108-6da09aaa4693b3b3.png



好了,我们要正式开始我们的工作了GO GO GO!
1. 首先我们先去官网创建AppID和描述文件.      

我们是要集成推送的,所以我们需要用到cer文件,这个东西实际上就是苹果给开发者颁发的一个证书,我们需要将它导入到我们的AppId配置里,否则的话是无法集成推送的,还记得安装应该的时候会提示"无法安装为认证发布者的应用"之类的信息么,我猜测这个cer文件就是我们身份的标示,使我们开发的应用可以供人们正常安装使用,关于证书有一篇很详细的帖子,希望了解证书之类信息的看官可以去瞅瞅:http://m.blog.csdn.net/article/details?id=8617788

创建cer文件的流程很简单,打开"钥匙串访问"(虽然很好找,但是还是把图贴出来吧,怕小朋友迷路)

1232108-ab1cf50531874785.png



1232108-6438c3fb50b4aaa5.png



打开钥匙串之后点击"从证书颁发机构请求证书"


1232108-d4a8951b51e6cceb.png


邮箱和常用名随便填写,记住下面的选择框选择"存储到磁盘"

1232108-bda705277e11698e.png



点击存储

1232108-07e46d1757718ea4.png



已经在桌面保存了


1232108-43a584c54d8f6cf2.png



到此,我们已经创建好了cer文件,接着我们去开发者中心创建AppId和描述文件

2. 创建AppId和描述文件

首先进入开发者中心,百度搜索Apple Developer,(哎 真的是详细到家了啊,我都人不下去了)
上图

1232108-cedf60744b970a2e.png



输入开发者账户,登录进去


1232108-2b564af543f98b20.png


你将看到这个页面

1232108-a8daff6248a1238a.png



点击看到:

1232108-e9a6e57aa9930544.png


输入AppId文件名和BundleId

1232108-ae96fe218d56e753.png


选中下面的PushNotifications

1232108-38bf6bb6a67f51d2.png


点击Continue:

1232108-934cf686ea792fe8.png


点击register:

1232108-083327989bcbe786.png


点击Done回到AppId列表页面

1232108-0538ef84dea33c70.png


在AppId列表页面可以看到我们的AppID了

1232108-95b229c6dbadcdac.png



但是,还没有完成,因为我们是要做推送的,所以需要上传我们的cer文件
,点击我们的AppId,在展开的详情里可以看到:

1232108-15f6e6cba67bcf32.png




Push Notification的两个指示灯还是黄色的状态,我们要将它启用,点击Edit,在点开的页面里滑动至底部,记得要选中Push Notification按钮,接着点击上方的开发证书下的创建证书按钮:

1232108-6e60ef33f39c3c3e.png



点击Continue

1232108-20ba8ef5aac404fe.png



点击 choose file:

1232108-a8b6d1f97c9f57a7.png



将我们从开发机构请求的证书传上去,之后点击Register:

1232108-be277d8092ca589a.png



点击Register之后的页面,点击download,将其下载到桌面上,download之后记得点击done完成文件创建:

1232108-70ad59ee048b37de.png



桌面上的文件:

1232108-ea6f4078346a5a1c.png



现在我们就完成了给AppID创建开发者证书,然后我们要给它创建发布者证书,点击Done之后回到AppIds列表,如果找不到的话,点击右边的App IDs

1232108-f3563cf07940ad50.png



点开项目的AppId,此时界面如下,点击最下面的CreateCertificate,开始给AppID创建发布者证书,给AppId创建发布者证书流程跟创建开发者证书是一样的!给AppId创建发布者证书流程跟创建开发者证书是一样的!给AppId创建发布者证书流程跟创建开发者证书是一样的!重要的事情说三遍!!因为我不贴出来创建发布证书的图了,所以各位根据创建开发证书的流程再走一遍就好,同样也要将发布者证书下载到本地.:

1232108-5d146f8fcbf96aa2.png



1232108-f4959adf27635124.png



当创建好之后在回到这个页面时,应该显示如下所示:

1232108-d9e0b2bf3794fad2.png



此时本地我们下载的文件如下:

1232108-651e46a585df0fd2.png



然后将这两个证书拖到钥匙串里,步骤如下:
首先打开钥匙串:

1232108-2ed433418c0ceaf9.png



1232108-4907f4f3f01371e6.png


然后先点击:系统-证书,然后将两个文件拖进去,会提示你输入开机密码,输入就好了(建议添加之前先对这个界面截屏,添加完之后可以对比刚刚添加了那些文件)

1232108-9e9434ee2246e3ce.png



添加完之后是这个样子,画框的是我们的证书

1232108-c71476ca00c853ec.png



然后选择左边的"登录"选项,可以看到我们刚才创建的证书

1232108-b7e1a0917e1bdc6a.png


选中第一个证书,然后右键(你懂得右键的意思),选择导出...

1232108-b020b7d0a48f795d.png



选择导出为P12文件,存储在桌面上,获取到P12文件.对这两个证书进行同样的操作.(记得标题有(Develop)的起名为Product文件,第二个证书导出的时候起名为Develop,名字可以自己定,只是为了区别)

1232108-04d80a4621bc1708.png


然后会提示你输入密码,这里我设置的密码是zx123456,自己设定好一定要记住,一会儿要用.

1232108-409c20593f4f262e.png


然后可以在桌面上看到我们导出的P12文件啦

1232108-964de37f66433eaa.png



现在我们就完成了所有的证书的创建,可以去环信上创建我们的应用啦.

3.创建真机调试文件以及导入到项目中

因为必须要进行真机测试,而且我们关闭了自动管理证书,就导致Xcode8不会自动帮我们生成证书,所以我们要自己创建真机调试证书并导入到项目中去,流程如下:

创建描述文件:

1232108-9dbec2cea23ab8e1.png



选择开发模式,下一步:

1232108-edece2d8c17d8f27.png



选择对应的AppID,选择我们刚才创建的AppId:

1232108-ee9029c89f0c34d2.png



选择开发团队,我一般都是全选的,下一步:

1232108-3744e08d9d10aa55.png



选择真机调试的机器,全选,下一步:

1232108-124184468c7c6531.png



下一步:

1232108-c6c0e50e57add4be.png



将创建好的描述文件下载下来,放到桌面上:

1232108-8a2c9400633c796d.png



创建好的描述文件:

1232108-40bebec424947b9d.png



首先选择debug模式下载的真机调试描述文件:

1232108-a1d8a4c3a0bb0a23.png


选择桌面上刚刚下载的描述文件:

1232108-692279ac01c7d137.png



使用同样的步骤,选择Release模式下的真机调试文件,一模一样的操作,不贴图了.两个文件都导入进去之后,插上真机,就可以进行真机调试了.

4.在环信创建我们的应用

首先百度搜索环信,打开他们的官网,先注册账户,注册过的可以跳过了,上图:
注册的时候选择"注册即时通讯云"

1232108-672cbab760c523f9.png



注册的时候需要填写各种信息,按照格式填写就好了,填写完之后登陆,点击创建应用

1232108-bd67f4f4f35cd764.png



填写应用信息

1232108-4d748bd8c621d0ff.png



填写完如下图咯

1232108-bbdc1fbea11501aa.png



然后需要上传我们的P12文件,图片很清晰- -,不多说,第一次我选择上传的是生产证书:

1232108-6b5a19a243a78839.png



第二次上传开发证书:

1232108-538c02769688cac0.png



至此,我们的证书开发也都上传完了,路漫漫其修远兮,开始集成环信到代码里吧

5.集成环信到项目中

首先在这里下载最新的SDK(截至到写本文时最新的SDK为)

http://www.easemob.com/download/im 环信推送SDK下载链接

点击iOS的最新SDK下载,这里下载的是V3.x的SDK

1232108-279c3c47c46ec724.png



下载到桌面是这个鬼样子

1232108-9d5b7d0ee1c2d404.png



我们只需要将画圈的两个文件夹导进去工程里就好了,其他的用不上

1232108-e8d9522b4f496454.png



导进去之后文件列表是这样,编译会出错别急,慢慢改.

1232108-da727a18407e70d1.png



向项目里添加需要的库

1232108-e0ac523eac1d6042.png



上面的图片是截取的环信官方文档,我添加完是这个样子的:

1232108-5409054190742754.png


方便复制库名的文字:
CoreMedia.framework
AudioToolbox.framework
AVFoundation.framework
MobileCoreServices.framework
ImageIO.framework
libc++.dylib
libz.dylib
libstdc++.6.0.9.dylib
libsqlite3.dylib
(如果使用的是 xcode7,后缀为 tbd。)
这一步很重要,因为SDK 不支持 bitcode,所以要将 Build Settings → Linking → Enable Bitcode 中设置 NO。


1232108-96cd9023e11f17bd.png



command+B编译工程,大量爆红.别着急,修改我们的PCH文件就好了
在PCH文件添加
```
#ifdef __OBJC__
    #import <UIKit/UIKit.h>
#endif
```

将我们所有定义和添加的头文件和宏定义,都放在#ifdef __OBJC__和#endif中间
就可以解决这个问题.

然后在项目里打开推送:

1232108-96cd9023e11f17bd.png



6.测试是否集成成功

首先,我们去环信的后台给我们的应用添加一个用户

1232108-8abe301c76c6c7f4.png



用户名我设置成了:13051698888  密码设置成了:222222

1232108-94c1ef7dbdf3014c.png



接着我们要去appledate.m文件里添加东西了,很重要一步,废话不多说,直接贴出来需要配置的代码,直接拿去用0.0,需要添加的东西我在注释里注释的很明白...
记得要导进去头文件
#import "EMSDK.h"

```
@interface AppDelegate ()<EMChatManagerDelegate>

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //AppKey:注册的AppKey,点击"应用概述"可以看到AppKey,粘贴过来就可以。
    //apnsCertName:推送证书名,填写你的开发证书或者发布证书名,就是上传到环信后台的两个中的一个,什么环境下测试使用什么环境的证书。
    EMOptions *options = [EMOptions optionsWithAppkey:@"1192161108178165#testpushdemo"];
    options.apnsCertName = @"Develop";
    [[EMClient sharedClient] initializeSDKWithOptions:options];

    //登录环信 这里使用的是我刚才在环信后台创建的账户名和密码,使用这个账户登录,到时候如果在后台给客户端发消息的话,就可以找到该用户
    [[EMClient sharedClient] loginWithUsername:@"13051698888"
                                      password:@"222222"
                                    completion:^(NSString *aUsername, EMError *aError) {
                                        if (!aError) {
                                            NSLog(@"环信登陆成功");
                                            EMPushOptions *emoptions = [[EMClient sharedClient] pushOptions];
                                            //设置有消息过来时的显示方式:1.显示收到一条消息 2.显示具体消息内容.
                                            //自己可以测试下
                                            emoptions.displayStyle = EMPushDisplayStyleSimpleBanner;
                                            [[EMClient sharedClient] updatePushOptionsToServer];
                                        } else {
                                            NSLog(@"环信登陆失败");
                                        }
                                    }];
    
    
    /**
     注册APNS离线推送  iOS8 注册APNS
     */
    if ([application respondsToSelector:@selector(registerForRemoteNotifications)]) {
        [application registerForRemoteNotifications];
        UIUserNotificationType notificationTypes = UIUserNotificationTypeBadge |
        UIUserNotificationTypeSound |
        UIUserNotificationTypeAlert;
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:notificationTypes categories:nil];
        [application registerUserNotificationSettings:settings];
    }
    else{
        UIRemoteNotificationType notificationTypes = UIRemoteNotificationTypeBadge |
        UIRemoteNotificationTypeSound |
        UIRemoteNotificationTypeAlert;
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:notificationTypes];
    }
    
    //添加监听在线推送消息
   [[EMClient sharedClient].chatManager addDelegate:self delegateQueue:nil];    
    return YES;
}

//监听环信在线推送消息
- (void)messagesDidReceive:(NSArray *)aMessages{
    
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"收到环信通知" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
        [alertView show];
        
        //aMessages是一个对象,包含了发过来的所有信息,怎么提取想要的信息我会在后面贴出来.
}

// 将得到的deviceToken传给SDK
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
    [[EMClient sharedClient] bindDeviceToken:deviceToken];
}

// 注册deviceToken失败
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
    NSLog(@"error -- %@",error);
}

// APP进入后台
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [[EMClient sharedClient] applicationDidEnterBackground:application];
}

// APP将要从后台返回
- (void)applicationWillEnterForeground:(UIApplication *)application
{
    [[EMClient sharedClient] applicationWillEnterForeground:application];
}
```
上面的几个方法在appdelegate里是必须重写的,不然会直接导致推送不成功.其中.需要重点说明的是:

- 只有在应用完全退出被杀掉的状态下,才可以收到环信推送的通知;
- 如果要发送在线的通知,需要在messagesDidReceive方法里获取到环信推送的消息之后给用户发起一个本地通知,这个大家可以自己研究下.
- 通过设置emoptions.displayStyle = EMPushDisplayStyleSimpleBanner;(上面代码有)可以设置有通知过来的时候的显示方式,显示一个提示或者显示完整的消息.
- 上传证书下面填写的应用包名,指的是你的BundleID !!!!我在这里踩了坑,切记!!.

测试推送:
1. 在应用完全退出的情况下(使用在环信注册的账户登录一次,确认登录成功之后再完全退出),选中我们的用户,点击发送消息:

1232108-8e6a60d144269c67.png



点击发送:

1232108-17f029870d36abef.png



测试结果:

1232108-aa2b808cf5cd1c6d.png




2.程序在线的时候测试推送,还是发送"你好啊",然后我们在messagesDidReceive拦截环信的EMMessage对象,针对EMMessage对象的解析方式如下,完整的抽取环信推送消息的方法:
```
- (void)messagesDidReceive:(NSArray *)aMessages{
    
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"收到环信通知" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
        [alertView show];
    
        for (EMMessage *message in aMessages) {
            EMMessageBody *msgBody = message.body;
            switch (msgBody.type) {
                case EMMessageBodyTypeText:
                {
                    // 收到的文字消息
                    EMTextMessageBody *textBody = (EMTextMessageBody *)msgBody;
                    NSString *txt = textBody.text;
                    NSLog(@"收到的文字是 txt -- %@",txt);
                }
                    break;
                case EMMessageBodyTypeImage:
                {
                    // 得到一个图片消息body
                    EMImageMessageBody *body = ((EMImageMessageBody *)msgBody);
                    NSLog(@"大图remote路径 -- %@"   ,body.remotePath);
                    NSLog(@"大图local路径 -- %@"    ,body.localPath); // // 需要使用sdk提供的下载方法后才会存在
                    NSLog(@"大图的secret -- %@"    ,body.secretKey);
                    NSLog(@"大图的W -- %f ,大图的H -- %f",body.size.width,body.size.height);
                    NSLog(@"大图的下载状态 -- %u",body.downloadStatus);
    
    
                    // 缩略图sdk会自动下载
                    NSLog(@"小图remote路径 -- %@"   ,body.thumbnailRemotePath);
                    NSLog(@"小图local路径 -- %@"    ,body.thumbnailLocalPath);
                    NSLog(@"小图的secret -- %@"    ,body.thumbnailSecretKey);
                    NSLog(@"小图的W -- %f ,大图的H -- %f",body.thumbnailSize.width,body.thumbnailSize.height);
                    NSLog(@"小图的下载状态 -- %u",body.thumbnailDownloadStatus);
                }
                    break;
                case EMMessageBodyTypeLocation:
                {
                    EMLocationMessageBody *body = (EMLocationMessageBody *)msgBody;
                    NSLog(@"纬度-- %f",body.latitude);
                    NSLog(@"经度-- %f",body.longitude);
                    NSLog(@"地址-- %@",body.address);
                }
                    break;
                case EMMessageBodyTypeVoice:
                {
                    // 音频sdk会自动下载
                    EMVoiceMessageBody *body = (EMVoiceMessageBody *)msgBody;
                    NSLog(@"音频remote路径 -- %@"      ,body.remotePath);
                    NSLog(@"音频local路径 -- %@"       ,body.localPath); // 需要使用sdk提供的下载方法后才会存在(音频会自动调用)
                    NSLog(@"音频的secret -- %@"        ,body.secretKey);
                    NSLog(@"音频文件大小 -- %lld"       ,body.fileLength);
                    NSLog(@"音频文件的下载状态 -- %u"   ,body.downloadStatus);
                    NSLog(@"音频的时间长度 -- %u"      ,body.duration);
                }
                    break;
                case EMMessageBodyTypeVideo:
                {
                    EMVideoMessageBody *body = (EMVideoMessageBody *)msgBody;
    
                    NSLog(@"视频remote路径 -- %@"      ,body.remotePath);
                    NSLog(@"视频local路径 -- %@"       ,body.localPath); // 需要使用sdk提供的下载方法后才会存在
                    NSLog(@"视频的secret -- %@"        ,body.secretKey);
                    NSLog(@"视频文件大小 -- %lld"       ,body.fileLength);
                    NSLog(@"视频文件的下载状态 -- %u"   ,body.downloadStatus);
                    NSLog(@"视频的时间长度 -- %u"      ,body.duration);
                    NSLog(@"视频的W -- %f ,视频的H -- %f", body.thumbnailSize.width, body.thumbnailSize.height);
    
                    // 缩略图sdk会自动下载
                    NSLog(@"缩略图的remote路径 -- %@"     ,body.thumbnailRemotePath);
                    NSLog(@"缩略图的local路径 -- %@"      ,body.thumbnailLocalPath);
                    NSLog(@"缩略图的secret -- %@"        ,body.thumbnailSecretKey);
                    NSLog(@"缩略图的下载状态 -- %u"      ,body.thumbnailDownloadStatus);
                }
                    break;
                case EMMessageBodyTypeFile:
                {
                    EMFileMessageBody *body = (EMFileMessageBody *)msgBody;
                    NSLog(@"文件remote路径 -- %@"      ,body.remotePath);
                    NSLog(@"文件local路径 -- %@"       ,body.localPath); // 需要使用sdk提供的下载方法后才会存在
                    NSLog(@"文件的secret -- %@"        ,body.secretKey);
                    NSLog(@"文件文件大小 -- %lld"       ,body.fileLength);
                    NSLog(@"文件文件的下载状态 -- %u"   ,body.downloadStatus);
                }
                    break;
                    
                default:
                    break;
            }
        }
}
```

发送成功之后打印结果如下:
```
2016-12-01 16:03:26.060088 PushDemo[1392:450230] 收到的文字是 txt -- 你好啊
```
三.结语

至此,我们就成功集成了环信推送到我们的项目中.另外提供一些在做推送的时候经常会用到的小方法
- 设置应用图标右上角数字角标.
```
UIApplication *application = [UIApplication sharedApplication]; [application setApplicationIconBadgeNumber:3];
```
补充一个环信坑:
编译通过后,运行的时候爆炸,提示:dyld: Library not loaded: @rpath/Hyphenate.framework/Hyphenate
需要设置Hyphenate.frameword的Embedded Binariew属性


1232108-0167fe66d3cd3151.png



- 如果推送证书那里没看特别明白的话,提供一个创建推送证书的链接:http://www.jianshu.com/p/78282e16db66


- 设置推送过来时候的_apns_昵称:
```
[[EMClient sharedClient] setApnsNickname:@"推送昵称"];
```

一直在抽时间写这篇博客,平常比较忙没有大块的时间来写和记录这些东西,不过东拼西凑,没事写一点最终还是写完了.希望看到这里的小伙伴都可以成功集成环信推送,有问题可以在下面留言,我看到了肯定会回复的.希望围观的小伙伴可以不吝指点这篇博客中出现的错误,不管是文字错误还是逻辑错误等等,我一定会尽快修正,不给后人留坑.....

给出项目gitHub地址:
https://github.com/TheRuningAnt/PushDemo.git  喜欢的话,记得给小星星哈

排版可能有点问题,原博客地址:http://blog.csdn.net/mumubumao ... 23393
 
4
回复

求教:iOS无法收到推送,搞定后双手奉上50块小红包 推送图标 推送证书 推送 EaseUI 环信_iOS

Swift 回复了问题 • 4 人关注 • 2706 次浏览 • 2016-09-02 09:07 • 来自相关话题

0
评论

apns上传的是什么文件? 文件 apns 推送证书

环信专业服务 发表了文章 • 1184 次浏览 • 2015-09-16 10:53 • 来自相关话题

推送证书需要是P12格式的。
推送证书需要是P12格式的。
0
评论

源码下载:全国首个直播答题开源项目了解一下!!!(基于环信即时通讯云) 直播答题 开源项目

beyond 发表了文章 • 863 次浏览 • 2018-03-06 18:10 • 来自相关话题

2018年伊始,全民直播答题浪潮来袭,一度被认为是一个新的互联网风口,王思聪凭借在现象级产品《冲顶大会》上疯狂"撒币"一时风光无二,凭借超高奖金和超低门槛吸引了大量网民参与和市场的目光。正因为直播答题是一种通过极低的成本来推动APP获客、保留存、拉活跃的新模式,各类直播答题APP如雨后春笋般进入大家的视野,越来越多企业希望赶上这波风口,快速搭建一套直播答题系统。作为一名环信生态圈资深开发者,本着对技术的热衷,对环信的眷恋和对党的忠诚,基于环信即时通讯云写了“小信竞答”这个直播答题开源项目,目前项目源码已全部免费开放,希望对有需求的企业和开发者提供一个思路和参考。



 

[b]


[/b]
 
小信竞答技术架构图:



     整个项目分为管理员端,观众端和服务端,首先在服务端预设好题目,由管理员发起直播开始答题,服务端收到指令将12道题目利用环信IM推送到观众端,观众端收到题目开始答题,将答案返回给服务端由服务端进行判断,如果答题正确进入下一题,答题错误判断是否使用复活卡,这里要注意的是需要加一个复活卡的使用次数判断。
 
   在整个答题过程中,管理员端会定时去服务端查询答题结果,等到全部答题结束,点击结束本次答题,服务端将计算好的结果返回并发放奖金,使用环信IM推送将答题结果推给观众端。
 
小信竞答效果图




关于直播间:
   直播间由直播画面和聊天室两个部分组成,“小信竞答”的聊天室使用环信聊天室,集成比较简单,基础版就能支持5000人在线聊天,增值服务版聊天室人数无上限,可以去环信官网注册一个开发者账号,创建应用将APPKEY替换成自己的;环信直播聊天室可以集成所有市场主流CDN厂商的推拉流功能(腾讯,七牛,UCloud,网宿等)。
 
环信直播聊天室特点  
This is Title
 
1、采用支持高并发的异步架构,轻松应对千万级并发请求; 各项基础服务集群化,确保系统高可用性; 系统冗余度高,容量评估体系完善,弹性扩容应对流量峰值;
2、支持各种消息格式:文字、表情、图片、声音、视频、附件、位置、扩展消息;
3、支持实时配置的消息分级策略,确保重要消息优先必达; 
4、支持直播聊天室后台管理及审核功能,提供直播相关数据统计;
5、提供智能反垃圾和自定义敏感词过滤功能;
6、快速集成,demo提供高质量代码示例,可根据运营情况随时扩展;
7、聊天室人数无上限 
小信竞答项目源码: github源码地址
 
写到最后:
   
     小信竞答源码全部开放,仅供学习和参考,如果作为商业用途,按照广电总局对网络直播答题节目管理的,需要 “网络视听许可证、主持人持证、还有通过审批发放的节目备案号”,三证缺一不可,未持有《信息网络传播视听节目许可证》的任何机构和个人,一律不得开办网络直播答题节目。
 
本月底《环信公开课第19期-直播答题开源项目》将线上讲解“小信竞答”实现思路,手把手教您从零开始搭建一个直播答题项目,扫码加入公开课微信群与大牛面对面交流。




  查看全部
   2018年伊始,全民直播答题浪潮来袭,一度被认为是一个新的互联网风口,王思聪凭借在现象级产品《冲顶大会》上疯狂"撒币"一时风光无二,凭借超高奖金和超低门槛吸引了大量网民参与和市场的目光。正因为直播答题是一种通过极低的成本来推动APP获客、保留存、拉活跃的新模式,各类直播答题APP如雨后春笋般进入大家的视野,越来越多企业希望赶上这波风口,快速搭建一套直播答题系统。作为一名环信生态圈资深开发者,本着对技术的热衷,对环信的眷恋和对党的忠诚,基于环信即时通讯云写了“小信竞答”这个直播答题开源项目,目前项目源码已全部免费开放,希望对有需求的企业和开发者提供一个思路和参考。



 

[b]
微信图片_20180316190105.jpg
[/b]
 
小信竞答技术架构图:
theFlowChart.png

     整个项目分为管理员端,观众端和服务端,首先在服务端预设好题目,由管理员发起直播开始答题,服务端收到指令将12道题目利用环信IM推送到观众端,观众端收到题目开始答题,将答案返回给服务端由服务端进行判断,如果答题正确进入下一题,答题错误判断是否使用复活卡,这里要注意的是需要加一个复活卡的使用次数判断。
 
   在整个答题过程中,管理员端会定时去服务端查询答题结果,等到全部答题结束,点击结束本次答题,服务端将计算好的结果返回并发放奖金,使用环信IM推送将答题结果推给观众端。
 
小信竞答效果图

微信图片_20180316190206.jpg


关于直播间:
   直播间由直播画面和聊天室两个部分组成,“小信竞答”的聊天室使用环信聊天室,集成比较简单,基础版就能支持5000人在线聊天,增值服务版聊天室人数无上限,可以去环信官网注册一个开发者账号,创建应用将APPKEY替换成自己的;环信直播聊天室可以集成所有市场主流CDN厂商的推拉流功能(腾讯,七牛,UCloud,网宿等)。
 
环信直播聊天室特点  
This is Title
 
1、采用支持高并发的异步架构,轻松应对千万级并发请求; 各项基础服务集群化,确保系统高可用性; 系统冗余度高,容量评估体系完善,弹性扩容应对流量峰值;
2、支持各种消息格式:文字、表情、图片、声音、视频、附件、位置、扩展消息;
3、支持实时配置的消息分级策略,确保重要消息优先必达; 
4、支持直播聊天室后台管理及审核功能,提供直播相关数据统计;
5、提供智能反垃圾和自定义敏感词过滤功能;
6、快速集成,demo提供高质量代码示例,可根据运营情况随时扩展;
7、聊天室人数无上限 
小信竞答项目源码: github源码地址
 
写到最后:
   
     小信竞答源码全部开放,仅供学习和参考,如果作为商业用途,按照广电总局对网络直播答题节目管理的,需要 “网络视听许可证、主持人持证、还有通过审批发放的节目备案号”,三证缺一不可,未持有《信息网络传播视听节目许可证》的任何机构和个人,一律不得开办网络直播答题节目。
 
本月底《环信公开课第19期-直播答题开源项目》将线上讲解“小信竞答”实现思路,手把手教您从零开始搭建一个直播答题项目,扫码加入公开课微信群与大牛面对面交流。
微信图片_20180316190334.jpg

 
10
评论

【新手快速入门】集成环信常见问题+解决方案汇总 常见问题

dujiepeng 发表了文章 • 11057 次浏览 • 2017-05-22 15:51 • 来自相关话题

   这里整理了集成环信的常见问题和一些功能的实现思路,希望能帮助到大家。感谢热心的开发者贡献,大家在观看过程中有不明白的地方欢迎直接跟帖咨询。
 
ios篇
APNs证书创建和上传到环信后台头像昵称的简述和处理方案音视频离线推送Demo实现环信服务器聊天记录保存多久?离线收不到好友请求IOS中环信聊天窗口如何实现文件发送和预览的功能ios集成常见问题环信推送的一些常见问题实现名片|红包|话题聊天室等自定义cell
 
Android篇
Android sdk 的两种导入方式环信3.0SDK集成小米推送教程EaseUI库中V4、v7包冲突解决方案Android EaseUI里的百度地图替换为高德地图android扩展消息(名片集成)关于会话列表的置顶聊天java.lang.UnsatisfiedLinkError: 的问题android 端 app 后台被杀死收不到消息的解决方案
昵称头像篇
android中如何显示开发者服务器上的昵称和头像 Android中显示头像(接上一篇文章看)环信(Android)设置头像和昵称的方法(最简单暴力的基于环信demo的集成)IOS中如何显示开发者服务器上的昵称和头像【环信公开课第12期视频回放】-所有关于环信IM昵称头像的问题听这课就够了
 
直播篇
一言不合你就搞个直播APP
 
客服集成
IM-SDK和客服SDK并存开发指南—Android篇IM-SDK和客服SDK并存开发指南—iOS篇
 
开源项目
Android简版demoios简版demo凡信2.0:超仿微信的开源项目 凡信3.0:携直播和红包而来高仿微信:Github 3,515 Star方圆十里:环信编程大赛冠军项目泛聊:定一个小目标写一个QQSlack聊天机器人:一天时间做一个聊天机器人TV视频通话:在电视上视频通话视频通话:Android手机视频通话酷信:ios高仿微信公众号助手:与订阅用户聊天沟通
 
持续更新ing...小伙伴们还有什么想知道欢迎跟帖提出。
  查看全部
   这里整理了集成环信的常见问题和一些功能的实现思路,希望能帮助到大家。感谢热心的开发者贡献,大家在观看过程中有不明白的地方欢迎直接跟帖咨询。
 
ios篇

 
Android篇

昵称头像篇

 
直播篇
  1. 一言不合你就搞个直播APP

 
客服集成
  1. IM-SDK和客服SDK并存开发指南—Android篇
  2. IM-SDK和客服SDK并存开发指南—iOS篇

 
开源项目

 
持续更新ing...小伙伴们还有什么想知道欢迎跟帖提出。
 
8
回复

收集基于环信SDK开发的开源项目 开源项目

JuN_Yong Wang 回复了问题 • 10 人关注 • 6926 次浏览 • 2018-02-07 11:49 • 来自相关话题

0
评论

源码下载:全国首个直播答题开源项目了解一下!!!(基于环信即时通讯云) 直播答题 开源项目

beyond 发表了文章 • 863 次浏览 • 2018-03-06 18:10 • 来自相关话题

2018年伊始,全民直播答题浪潮来袭,一度被认为是一个新的互联网风口,王思聪凭借在现象级产品《冲顶大会》上疯狂"撒币"一时风光无二,凭借超高奖金和超低门槛吸引了大量网民参与和市场的目光。正因为直播答题是一种通过极低的成本来推动APP获客、保留存、拉活跃的新模式,各类直播答题APP如雨后春笋般进入大家的视野,越来越多企业希望赶上这波风口,快速搭建一套直播答题系统。作为一名环信生态圈资深开发者,本着对技术的热衷,对环信的眷恋和对党的忠诚,基于环信即时通讯云写了“小信竞答”这个直播答题开源项目,目前项目源码已全部免费开放,希望对有需求的企业和开发者提供一个思路和参考。



 

[b]


[/b]
 
小信竞答技术架构图:



     整个项目分为管理员端,观众端和服务端,首先在服务端预设好题目,由管理员发起直播开始答题,服务端收到指令将12道题目利用环信IM推送到观众端,观众端收到题目开始答题,将答案返回给服务端由服务端进行判断,如果答题正确进入下一题,答题错误判断是否使用复活卡,这里要注意的是需要加一个复活卡的使用次数判断。
 
   在整个答题过程中,管理员端会定时去服务端查询答题结果,等到全部答题结束,点击结束本次答题,服务端将计算好的结果返回并发放奖金,使用环信IM推送将答题结果推给观众端。
 
小信竞答效果图




关于直播间:
   直播间由直播画面和聊天室两个部分组成,“小信竞答”的聊天室使用环信聊天室,集成比较简单,基础版就能支持5000人在线聊天,增值服务版聊天室人数无上限,可以去环信官网注册一个开发者账号,创建应用将APPKEY替换成自己的;环信直播聊天室可以集成所有市场主流CDN厂商的推拉流功能(腾讯,七牛,UCloud,网宿等)。
 
环信直播聊天室特点  
This is Title
 
1、采用支持高并发的异步架构,轻松应对千万级并发请求; 各项基础服务集群化,确保系统高可用性; 系统冗余度高,容量评估体系完善,弹性扩容应对流量峰值;
2、支持各种消息格式:文字、表情、图片、声音、视频、附件、位置、扩展消息;
3、支持实时配置的消息分级策略,确保重要消息优先必达; 
4、支持直播聊天室后台管理及审核功能,提供直播相关数据统计;
5、提供智能反垃圾和自定义敏感词过滤功能;
6、快速集成,demo提供高质量代码示例,可根据运营情况随时扩展;
7、聊天室人数无上限 
小信竞答项目源码: github源码地址
 
写到最后:
   
     小信竞答源码全部开放,仅供学习和参考,如果作为商业用途,按照广电总局对网络直播答题节目管理的,需要 “网络视听许可证、主持人持证、还有通过审批发放的节目备案号”,三证缺一不可,未持有《信息网络传播视听节目许可证》的任何机构和个人,一律不得开办网络直播答题节目。
 
本月底《环信公开课第19期-直播答题开源项目》将线上讲解“小信竞答”实现思路,手把手教您从零开始搭建一个直播答题项目,扫码加入公开课微信群与大牛面对面交流。




  查看全部
   2018年伊始,全民直播答题浪潮来袭,一度被认为是一个新的互联网风口,王思聪凭借在现象级产品《冲顶大会》上疯狂"撒币"一时风光无二,凭借超高奖金和超低门槛吸引了大量网民参与和市场的目光。正因为直播答题是一种通过极低的成本来推动APP获客、保留存、拉活跃的新模式,各类直播答题APP如雨后春笋般进入大家的视野,越来越多企业希望赶上这波风口,快速搭建一套直播答题系统。作为一名环信生态圈资深开发者,本着对技术的热衷,对环信的眷恋和对党的忠诚,基于环信即时通讯云写了“小信竞答”这个直播答题开源项目,目前项目源码已全部免费开放,希望对有需求的企业和开发者提供一个思路和参考。



 

[b]
微信图片_20180316190105.jpg
[/b]
 
小信竞答技术架构图:
theFlowChart.png

     整个项目分为管理员端,观众端和服务端,首先在服务端预设好题目,由管理员发起直播开始答题,服务端收到指令将12道题目利用环信IM推送到观众端,观众端收到题目开始答题,将答案返回给服务端由服务端进行判断,如果答题正确进入下一题,答题错误判断是否使用复活卡,这里要注意的是需要加一个复活卡的使用次数判断。
 
   在整个答题过程中,管理员端会定时去服务端查询答题结果,等到全部答题结束,点击结束本次答题,服务端将计算好的结果返回并发放奖金,使用环信IM推送将答题结果推给观众端。
 
小信竞答效果图

微信图片_20180316190206.jpg


关于直播间:
   直播间由直播画面和聊天室两个部分组成,“小信竞答”的聊天室使用环信聊天室,集成比较简单,基础版就能支持5000人在线聊天,增值服务版聊天室人数无上限,可以去环信官网注册一个开发者账号,创建应用将APPKEY替换成自己的;环信直播聊天室可以集成所有市场主流CDN厂商的推拉流功能(腾讯,七牛,UCloud,网宿等)。
 
环信直播聊天室特点  
This is Title
 
1、采用支持高并发的异步架构,轻松应对千万级并发请求; 各项基础服务集群化,确保系统高可用性; 系统冗余度高,容量评估体系完善,弹性扩容应对流量峰值;
2、支持各种消息格式:文字、表情、图片、声音、视频、附件、位置、扩展消息;
3、支持实时配置的消息分级策略,确保重要消息优先必达; 
4、支持直播聊天室后台管理及审核功能,提供直播相关数据统计;
5、提供智能反垃圾和自定义敏感词过滤功能;
6、快速集成,demo提供高质量代码示例,可根据运营情况随时扩展;
7、聊天室人数无上限 
小信竞答项目源码: github源码地址
 
写到最后:
   
     小信竞答源码全部开放,仅供学习和参考,如果作为商业用途,按照广电总局对网络直播答题节目管理的,需要 “网络视听许可证、主持人持证、还有通过审批发放的节目备案号”,三证缺一不可,未持有《信息网络传播视听节目许可证》的任何机构和个人,一律不得开办网络直播答题节目。
 
本月底《环信公开课第19期-直播答题开源项目》将线上讲解“小信竞答”实现思路,手把手教您从零开始搭建一个直播答题项目,扫码加入公开课微信群与大牛面对面交流。
微信图片_20180316190334.jpg

 
8
回复

收集基于环信SDK开发的开源项目 开源项目

回复

JuN_Yong Wang 回复了问题 • 10 人关注 • 6926 次浏览 • 2018-02-07 11:49 • 来自相关话题

10
评论

【新手快速入门】集成环信常见问题+解决方案汇总 常见问题

dujiepeng 发表了文章 • 11057 次浏览 • 2017-05-22 15:51 • 来自相关话题

   这里整理了集成环信的常见问题和一些功能的实现思路,希望能帮助到大家。感谢热心的开发者贡献,大家在观看过程中有不明白的地方欢迎直接跟帖咨询。
 
ios篇
APNs证书创建和上传到环信后台头像昵称的简述和处理方案音视频离线推送Demo实现环信服务器聊天记录保存多久?离线收不到好友请求IOS中环信聊天窗口如何实现文件发送和预览的功能ios集成常见问题环信推送的一些常见问题实现名片|红包|话题聊天室等自定义cell
 
Android篇
Android sdk 的两种导入方式环信3.0SDK集成小米推送教程EaseUI库中V4、v7包冲突解决方案Android EaseUI里的百度地图替换为高德地图android扩展消息(名片集成)关于会话列表的置顶聊天java.lang.UnsatisfiedLinkError: 的问题android 端 app 后台被杀死收不到消息的解决方案
昵称头像篇
android中如何显示开发者服务器上的昵称和头像 Android中显示头像(接上一篇文章看)环信(Android)设置头像和昵称的方法(最简单暴力的基于环信demo的集成)IOS中如何显示开发者服务器上的昵称和头像【环信公开课第12期视频回放】-所有关于环信IM昵称头像的问题听这课就够了
 
直播篇
一言不合你就搞个直播APP
 
客服集成
IM-SDK和客服SDK并存开发指南—Android篇IM-SDK和客服SDK并存开发指南—iOS篇
 
开源项目
Android简版demoios简版demo凡信2.0:超仿微信的开源项目 凡信3.0:携直播和红包而来高仿微信:Github 3,515 Star方圆十里:环信编程大赛冠军项目泛聊:定一个小目标写一个QQSlack聊天机器人:一天时间做一个聊天机器人TV视频通话:在电视上视频通话视频通话:Android手机视频通话酷信:ios高仿微信公众号助手:与订阅用户聊天沟通
 
持续更新ing...小伙伴们还有什么想知道欢迎跟帖提出。
  查看全部
   这里整理了集成环信的常见问题和一些功能的实现思路,希望能帮助到大家。感谢热心的开发者贡献,大家在观看过程中有不明白的地方欢迎直接跟帖咨询。
 
ios篇

 
Android篇

昵称头像篇

 
直播篇
  1. 一言不合你就搞个直播APP

 
客服集成
  1. IM-SDK和客服SDK并存开发指南—Android篇
  2. IM-SDK和客服SDK并存开发指南—iOS篇

 
开源项目

 
持续更新ing...小伙伴们还有什么想知道欢迎跟帖提出。
 
0
回复

android消息推送 非华为小米怎么配置 环信_Android 推送 android 推送证书 推送证书管理

回复

xuzheng 发起了问题 • 1 人关注 • 96 次浏览 • 2018-04-13 11:05 • 来自相关话题

4
回复

求教:iOS无法收到推送,搞定后双手奉上50块小红包 推送图标 推送证书 推送 EaseUI 环信_iOS

回复

Swift 回复了问题 • 4 人关注 • 2706 次浏览 • 2016-09-02 09:07 • 来自相关话题

0
评论

源码下载:全国首个直播答题开源项目了解一下!!!(基于环信即时通讯云) 直播答题 开源项目

beyond 发表了文章 • 863 次浏览 • 2018-03-06 18:10 • 来自相关话题

2018年伊始,全民直播答题浪潮来袭,一度被认为是一个新的互联网风口,王思聪凭借在现象级产品《冲顶大会》上疯狂"撒币"一时风光无二,凭借超高奖金和超低门槛吸引了大量网民参与和市场的目光。正因为直播答题是一种通过极低的成本来推动APP获客、保留存、拉活跃的新模式,各类直播答题APP如雨后春笋般进入大家的视野,越来越多企业希望赶上这波风口,快速搭建一套直播答题系统。作为一名环信生态圈资深开发者,本着对技术的热衷,对环信的眷恋和对党的忠诚,基于环信即时通讯云写了“小信竞答”这个直播答题开源项目,目前项目源码已全部免费开放,希望对有需求的企业和开发者提供一个思路和参考。



 

[b]


[/b]
 
小信竞答技术架构图:



     整个项目分为管理员端,观众端和服务端,首先在服务端预设好题目,由管理员发起直播开始答题,服务端收到指令将12道题目利用环信IM推送到观众端,观众端收到题目开始答题,将答案返回给服务端由服务端进行判断,如果答题正确进入下一题,答题错误判断是否使用复活卡,这里要注意的是需要加一个复活卡的使用次数判断。
 
   在整个答题过程中,管理员端会定时去服务端查询答题结果,等到全部答题结束,点击结束本次答题,服务端将计算好的结果返回并发放奖金,使用环信IM推送将答题结果推给观众端。
 
小信竞答效果图




关于直播间:
   直播间由直播画面和聊天室两个部分组成,“小信竞答”的聊天室使用环信聊天室,集成比较简单,基础版就能支持5000人在线聊天,增值服务版聊天室人数无上限,可以去环信官网注册一个开发者账号,创建应用将APPKEY替换成自己的;环信直播聊天室可以集成所有市场主流CDN厂商的推拉流功能(腾讯,七牛,UCloud,网宿等)。
 
环信直播聊天室特点  
This is Title
 
1、采用支持高并发的异步架构,轻松应对千万级并发请求; 各项基础服务集群化,确保系统高可用性; 系统冗余度高,容量评估体系完善,弹性扩容应对流量峰值;
2、支持各种消息格式:文字、表情、图片、声音、视频、附件、位置、扩展消息;
3、支持实时配置的消息分级策略,确保重要消息优先必达; 
4、支持直播聊天室后台管理及审核功能,提供直播相关数据统计;
5、提供智能反垃圾和自定义敏感词过滤功能;
6、快速集成,demo提供高质量代码示例,可根据运营情况随时扩展;
7、聊天室人数无上限 
小信竞答项目源码: github源码地址
 
写到最后:
   
     小信竞答源码全部开放,仅供学习和参考,如果作为商业用途,按照广电总局对网络直播答题节目管理的,需要 “网络视听许可证、主持人持证、还有通过审批发放的节目备案号”,三证缺一不可,未持有《信息网络传播视听节目许可证》的任何机构和个人,一律不得开办网络直播答题节目。
 
本月底《环信公开课第19期-直播答题开源项目》将线上讲解“小信竞答”实现思路,手把手教您从零开始搭建一个直播答题项目,扫码加入公开课微信群与大牛面对面交流。




  查看全部
   2018年伊始,全民直播答题浪潮来袭,一度被认为是一个新的互联网风口,王思聪凭借在现象级产品《冲顶大会》上疯狂"撒币"一时风光无二,凭借超高奖金和超低门槛吸引了大量网民参与和市场的目光。正因为直播答题是一种通过极低的成本来推动APP获客、保留存、拉活跃的新模式,各类直播答题APP如雨后春笋般进入大家的视野,越来越多企业希望赶上这波风口,快速搭建一套直播答题系统。作为一名环信生态圈资深开发者,本着对技术的热衷,对环信的眷恋和对党的忠诚,基于环信即时通讯云写了“小信竞答”这个直播答题开源项目,目前项目源码已全部免费开放,希望对有需求的企业和开发者提供一个思路和参考。



 

[b]
微信图片_20180316190105.jpg
[/b]
 
小信竞答技术架构图:
theFlowChart.png

     整个项目分为管理员端,观众端和服务端,首先在服务端预设好题目,由管理员发起直播开始答题,服务端收到指令将12道题目利用环信IM推送到观众端,观众端收到题目开始答题,将答案返回给服务端由服务端进行判断,如果答题正确进入下一题,答题错误判断是否使用复活卡,这里要注意的是需要加一个复活卡的使用次数判断。
 
   在整个答题过程中,管理员端会定时去服务端查询答题结果,等到全部答题结束,点击结束本次答题,服务端将计算好的结果返回并发放奖金,使用环信IM推送将答题结果推给观众端。
 
小信竞答效果图

微信图片_20180316190206.jpg


关于直播间:
   直播间由直播画面和聊天室两个部分组成,“小信竞答”的聊天室使用环信聊天室,集成比较简单,基础版就能支持5000人在线聊天,增值服务版聊天室人数无上限,可以去环信官网注册一个开发者账号,创建应用将APPKEY替换成自己的;环信直播聊天室可以集成所有市场主流CDN厂商的推拉流功能(腾讯,七牛,UCloud,网宿等)。
 
环信直播聊天室特点  
This is Title
 
1、采用支持高并发的异步架构,轻松应对千万级并发请求; 各项基础服务集群化,确保系统高可用性; 系统冗余度高,容量评估体系完善,弹性扩容应对流量峰值;
2、支持各种消息格式:文字、表情、图片、声音、视频、附件、位置、扩展消息;
3、支持实时配置的消息分级策略,确保重要消息优先必达; 
4、支持直播聊天室后台管理及审核功能,提供直播相关数据统计;
5、提供智能反垃圾和自定义敏感词过滤功能;
6、快速集成,demo提供高质量代码示例,可根据运营情况随时扩展;
7、聊天室人数无上限 
小信竞答项目源码: github源码地址
 
写到最后:
   
     小信竞答源码全部开放,仅供学习和参考,如果作为商业用途,按照广电总局对网络直播答题节目管理的,需要 “网络视听许可证、主持人持证、还有通过审批发放的节目备案号”,三证缺一不可,未持有《信息网络传播视听节目许可证》的任何机构和个人,一律不得开办网络直播答题节目。
 
本月底《环信公开课第19期-直播答题开源项目》将线上讲解“小信竞答”实现思路,手把手教您从零开始搭建一个直播答题项目,扫码加入公开课微信群与大牛面对面交流。
微信图片_20180316190334.jpg

 
8
回复

收集基于环信SDK开发的开源项目 开源项目

回复

JuN_Yong Wang 回复了问题 • 10 人关注 • 6926 次浏览 • 2018-02-07 11:49 • 来自相关话题

10
评论

【新手快速入门】集成环信常见问题+解决方案汇总 常见问题

dujiepeng 发表了文章 • 11057 次浏览 • 2017-05-22 15:51 • 来自相关话题

   这里整理了集成环信的常见问题和一些功能的实现思路,希望能帮助到大家。感谢热心的开发者贡献,大家在观看过程中有不明白的地方欢迎直接跟帖咨询。
 
ios篇
APNs证书创建和上传到环信后台头像昵称的简述和处理方案音视频离线推送Demo实现环信服务器聊天记录保存多久?离线收不到好友请求IOS中环信聊天窗口如何实现文件发送和预览的功能ios集成常见问题环信推送的一些常见问题实现名片|红包|话题聊天室等自定义cell
 
Android篇
Android sdk 的两种导入方式环信3.0SDK集成小米推送教程EaseUI库中V4、v7包冲突解决方案Android EaseUI里的百度地图替换为高德地图android扩展消息(名片集成)关于会话列表的置顶聊天java.lang.UnsatisfiedLinkError: 的问题android 端 app 后台被杀死收不到消息的解决方案
昵称头像篇
android中如何显示开发者服务器上的昵称和头像 Android中显示头像(接上一篇文章看)环信(Android)设置头像和昵称的方法(最简单暴力的基于环信demo的集成)IOS中如何显示开发者服务器上的昵称和头像【环信公开课第12期视频回放】-所有关于环信IM昵称头像的问题听这课就够了
 
直播篇
一言不合你就搞个直播APP
 
客服集成
IM-SDK和客服SDK并存开发指南—Android篇IM-SDK和客服SDK并存开发指南—iOS篇
 
开源项目
Android简版demoios简版demo凡信2.0:超仿微信的开源项目 凡信3.0:携直播和红包而来高仿微信:Github 3,515 Star方圆十里:环信编程大赛冠军项目泛聊:定一个小目标写一个QQSlack聊天机器人:一天时间做一个聊天机器人TV视频通话:在电视上视频通话视频通话:Android手机视频通话酷信:ios高仿微信公众号助手:与订阅用户聊天沟通
 
持续更新ing...小伙伴们还有什么想知道欢迎跟帖提出。
  查看全部
   这里整理了集成环信的常见问题和一些功能的实现思路,希望能帮助到大家。感谢热心的开发者贡献,大家在观看过程中有不明白的地方欢迎直接跟帖咨询。
 
ios篇

 
Android篇

昵称头像篇

 
直播篇
  1. 一言不合你就搞个直播APP

 
客服集成
  1. IM-SDK和客服SDK并存开发指南—Android篇
  2. IM-SDK和客服SDK并存开发指南—iOS篇

 
开源项目

 
持续更新ing...小伙伴们还有什么想知道欢迎跟帖提出。
 
1
评论

【环信征文】| iOS集成环信推送,最详细流程(证书创建、环信集成、测试) 环信iOS 环信iOS真机调试 环信 JPush 推送 iOS 推送证书

奔跑的虫子 发表了文章 • 256 次浏览 • 2018-01-31 10:41 • 来自相关话题

这几天项目里又用到了环信的推送,虽然之前做过,但是很久不做还是有很多细节没有注意到,所以还是决定从头开始做一遍,把每一个环节都详细记录下来,同样的把每一个坑也记录下来.方便自己以后做的时候忘记哪个流程了可以在看一遍.我很能理解那种遇到问题网上百度一堆类似答案但是并不好使的情况,所以我会将我在项目中遇到的问题都贴出来,希望能给大家带来些许参考和帮助,

一.推送的原理和流程(着急做推送的可以跳过这一步)
首先给大家推荐一个介绍推送机制很优秀的帖子:http://www.jianshu.com/p/e347f999ed95 ,里面关于本地推送和远程推送的介绍都很详细,至少我看了感觉还是收获很多的.尤其是里面有几张图片不知道是博主在哪里找的,但是真的是一看就透,太赞了,所以我果断盗过来了0.0. 这里我对推送的流程做了一个简单的叙述,力求用最简单的语言能说明整个推送的机制.

先搬过来一张图再说






再搬一张:







当我们的苹果手机联网的时候,会自动与苹果的服务器建立长连接,长连接的好处有很多,比如系统升级、时间校准、数据传输和响应比较快以及数据可以保持最新状态等功能.上面这两张图片简单的讲述了推送的流程:

- 1.首先我们需要将自己设备的UDID和应用的Bundle Identifier发送到苹果的服务器,然后苹果的服务器会返回给我们一个DeviceToken,这个在我看来就是创建推送证书和描述文件的过程.
- 2.我们将包含手机和应用标示的打包文件上传到做推送的服务器上去,当我们从推送服务器的后台发起推送消息的时候,推送服务器会将我们的DeviceToken和需要发送的消息Message发送到苹果的APNS(Apple push Notification Service)服务器.
- 3.当苹果的服务器收到DeviceToken和需要发送的消息Message时,会根据DeviceToken中的UDID查找设备,根据DeviceToken中的Bundle Identfier查找该应用,并将Message发送到该设备上.

下面是以QQ服务器为栗子说明的即时通讯的机制:






图片已经说得够详细明了了,我就不插嘴了,下面开始我们的工程.

二.具体流程

我们创建一个名为TestDemo的工程,我是使用Xcode8.1来开发的,工程名为PushDemo,创建好的工程界面如下(Xcode8)






从Xcode8之后,Xcode提供了自动管理证书的功能,这个用起来很方便,我目前在工程中用到的最多的地方就是创建好一个Demo之后,如果想真机运行的话,那么只需要在Team选择框里选择我的开发账户,接下来下面会出现一个加载提示圈,等它加载完了就可以在真机上运行了,这个过程实际上是Xcode使用你当前的BundleId去该账户的开发这中心创建了对应的AppId和描述文件,但是我们既然是作为一个开发流程的记录,就自己来创建这些东西,所以,我们取消选择Automatically manage signing选项.此时界面如下:







好了,我们要正式开始我们的工作了GO GO GO!
1. 首先我们先去官网创建AppID和描述文件.      

我们是要集成推送的,所以我们需要用到cer文件,这个东西实际上就是苹果给开发者颁发的一个证书,我们需要将它导入到我们的AppId配置里,否则的话是无法集成推送的,还记得安装应该的时候会提示"无法安装为认证发布者的应用"之类的信息么,我猜测这个cer文件就是我们身份的标示,使我们开发的应用可以供人们正常安装使用,关于证书有一篇很详细的帖子,希望了解证书之类信息的看官可以去瞅瞅:http://m.blog.csdn.net/article/details?id=8617788

创建cer文件的流程很简单,打开"钥匙串访问"(虽然很好找,但是还是把图贴出来吧,怕小朋友迷路)













打开钥匙串之后点击"从证书颁发机构请求证书"







邮箱和常用名随便填写,记住下面的选择框选择"存储到磁盘"







点击存储







已经在桌面保存了








到此,我们已经创建好了cer文件,接着我们去开发者中心创建AppId和描述文件

2. 创建AppId和描述文件

首先进入开发者中心,百度搜索Apple Developer,(哎 真的是详细到家了啊,我都人不下去了)
上图







输入开发者账户,登录进去







你将看到这个页面







点击看到:






输入AppId文件名和BundleId






选中下面的PushNotifications






点击Continue:






点击register:






点击Done回到AppId列表页面






在AppId列表页面可以看到我们的AppID了







但是,还没有完成,因为我们是要做推送的,所以需要上传我们的cer文件
,点击我们的AppId,在展开的详情里可以看到:








Push Notification的两个指示灯还是黄色的状态,我们要将它启用,点击Edit,在点开的页面里滑动至底部,记得要选中Push Notification按钮,接着点击上方的开发证书下的创建证书按钮:







点击Continue







点击 choose file:







将我们从开发机构请求的证书传上去,之后点击Register:







点击Register之后的页面,点击download,将其下载到桌面上,download之后记得点击done完成文件创建:







桌面上的文件:







现在我们就完成了给AppID创建开发者证书,然后我们要给它创建发布者证书,点击Done之后回到AppIds列表,如果找不到的话,点击右边的App IDs







点开项目的AppId,此时界面如下,点击最下面的CreateCertificate,开始给AppID创建发布者证书,给AppId创建发布者证书流程跟创建开发者证书是一样的!给AppId创建发布者证书流程跟创建开发者证书是一样的!给AppId创建发布者证书流程跟创建开发者证书是一样的!重要的事情说三遍!!因为我不贴出来创建发布证书的图了,所以各位根据创建开发证书的流程再走一遍就好,同样也要将发布者证书下载到本地.:













当创建好之后在回到这个页面时,应该显示如下所示:







此时本地我们下载的文件如下:







然后将这两个证书拖到钥匙串里,步骤如下:
首先打开钥匙串:












然后先点击:系统-证书,然后将两个文件拖进去,会提示你输入开机密码,输入就好了(建议添加之前先对这个界面截屏,添加完之后可以对比刚刚添加了那些文件)







添加完之后是这个样子,画框的是我们的证书







然后选择左边的"登录"选项,可以看到我们刚才创建的证书






选中第一个证书,然后右键(你懂得右键的意思),选择导出...







选择导出为P12文件,存储在桌面上,获取到P12文件.对这两个证书进行同样的操作.(记得标题有(Develop)的起名为Product文件,第二个证书导出的时候起名为Develop,名字可以自己定,只是为了区别)






然后会提示你输入密码,这里我设置的密码是zx123456,自己设定好一定要记住,一会儿要用.






然后可以在桌面上看到我们导出的P12文件啦







现在我们就完成了所有的证书的创建,可以去环信上创建我们的应用啦.

3.创建真机调试文件以及导入到项目中

因为必须要进行真机测试,而且我们关闭了自动管理证书,就导致Xcode8不会自动帮我们生成证书,所以我们要自己创建真机调试证书并导入到项目中去,流程如下:

创建描述文件:







选择开发模式,下一步:







选择对应的AppID,选择我们刚才创建的AppId:







选择开发团队,我一般都是全选的,下一步:







选择真机调试的机器,全选,下一步:







下一步:







将创建好的描述文件下载下来,放到桌面上:







创建好的描述文件:







首先选择debug模式下载的真机调试描述文件:






选择桌面上刚刚下载的描述文件:







使用同样的步骤,选择Release模式下的真机调试文件,一模一样的操作,不贴图了.两个文件都导入进去之后,插上真机,就可以进行真机调试了.

4.在环信创建我们的应用

首先百度搜索环信,打开他们的官网,先注册账户,注册过的可以跳过了,上图:
注册的时候选择"注册即时通讯云"







注册的时候需要填写各种信息,按照格式填写就好了,填写完之后登陆,点击创建应用







填写应用信息







填写完如下图咯







然后需要上传我们的P12文件,图片很清晰- -,不多说,第一次我选择上传的是生产证书:







第二次上传开发证书:







至此,我们的证书开发也都上传完了,路漫漫其修远兮,开始集成环信到代码里吧

5.集成环信到项目中

首先在这里下载最新的SDK(截至到写本文时最新的SDK为)

http://www.easemob.com/download/im 环信推送SDK下载链接

点击iOS的最新SDK下载,这里下载的是V3.x的SDK







下载到桌面是这个鬼样子







我们只需要将画圈的两个文件夹导进去工程里就好了,其他的用不上







导进去之后文件列表是这样,编译会出错别急,慢慢改.







向项目里添加需要的库







上面的图片是截取的环信官方文档,我添加完是这个样子的:






方便复制库名的文字:
CoreMedia.framework
AudioToolbox.framework
AVFoundation.framework
MobileCoreServices.framework
ImageIO.framework
libc++.dylib
libz.dylib
libstdc++.6.0.9.dylib
libsqlite3.dylib
(如果使用的是 xcode7,后缀为 tbd。)
这一步很重要,因为SDK 不支持 bitcode,所以要将 Build Settings → Linking → Enable Bitcode 中设置 NO。








command+B编译工程,大量爆红.别着急,修改我们的PCH文件就好了
在PCH文件添加
```
#ifdef __OBJC__
    #import <UIKit/UIKit.h>
#endif
```

将我们所有定义和添加的头文件和宏定义,都放在#ifdef __OBJC__和#endif中间
就可以解决这个问题.

然后在项目里打开推送:







6.测试是否集成成功

首先,我们去环信的后台给我们的应用添加一个用户







用户名我设置成了:13051698888  密码设置成了:222222







接着我们要去appledate.m文件里添加东西了,很重要一步,废话不多说,直接贴出来需要配置的代码,直接拿去用0.0,需要添加的东西我在注释里注释的很明白...
记得要导进去头文件
#import "EMSDK.h"

```
@interface AppDelegate ()<EMChatManagerDelegate>

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //AppKey:注册的AppKey,点击"应用概述"可以看到AppKey,粘贴过来就可以。
    //apnsCertName:推送证书名,填写你的开发证书或者发布证书名,就是上传到环信后台的两个中的一个,什么环境下测试使用什么环境的证书。
    EMOptions *options = [EMOptions optionsWithAppkey:@"1192161108178165#testpushdemo"];
    options.apnsCertName = @"Develop";
    [[EMClient sharedClient] initializeSDKWithOptions:options];

    //登录环信 这里使用的是我刚才在环信后台创建的账户名和密码,使用这个账户登录,到时候如果在后台给客户端发消息的话,就可以找到该用户
    [[EMClient sharedClient] loginWithUsername:@"13051698888"
                                      password:@"222222"
                                    completion:^(NSString *aUsername, EMError *aError) {
                                        if (!aError) {
                                            NSLog(@"环信登陆成功");
                                            EMPushOptions *emoptions = [[EMClient sharedClient] pushOptions];
                                            //设置有消息过来时的显示方式:1.显示收到一条消息 2.显示具体消息内容.
                                            //自己可以测试下
                                            emoptions.displayStyle = EMPushDisplayStyleSimpleBanner;
                                            [[EMClient sharedClient] updatePushOptionsToServer];
                                        } else {
                                            NSLog(@"环信登陆失败");
                                        }
                                    }];
    
    
    /**
     注册APNS离线推送  iOS8 注册APNS
     */
    if ([application respondsToSelector:@selector(registerForRemoteNotifications)]) {
        [application registerForRemoteNotifications];
        UIUserNotificationType notificationTypes = UIUserNotificationTypeBadge |
        UIUserNotificationTypeSound |
        UIUserNotificationTypeAlert;
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:notificationTypes categories:nil];
        [application registerUserNotificationSettings:settings];
    }
    else{
        UIRemoteNotificationType notificationTypes = UIRemoteNotificationTypeBadge |
        UIRemoteNotificationTypeSound |
        UIRemoteNotificationTypeAlert;
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:notificationTypes];
    }
    
    //添加监听在线推送消息
   [[EMClient sharedClient].chatManager addDelegate:self delegateQueue:nil];    
    return YES;
}

//监听环信在线推送消息
- (void)messagesDidReceive:(NSArray *)aMessages{
    
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"收到环信通知" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
        [alertView show];
        
        //aMessages是一个对象,包含了发过来的所有信息,怎么提取想要的信息我会在后面贴出来.
}

// 将得到的deviceToken传给SDK
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
    [[EMClient sharedClient] bindDeviceToken:deviceToken];
}

// 注册deviceToken失败
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
    NSLog(@"error -- %@",error);
}

// APP进入后台
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [[EMClient sharedClient] applicationDidEnterBackground:application];
}

// APP将要从后台返回
- (void)applicationWillEnterForeground:(UIApplication *)application
{
    [[EMClient sharedClient] applicationWillEnterForeground:application];
}
```
上面的几个方法在appdelegate里是必须重写的,不然会直接导致推送不成功.其中.需要重点说明的是:

- 只有在应用完全退出被杀掉的状态下,才可以收到环信推送的通知;
- 如果要发送在线的通知,需要在messagesDidReceive方法里获取到环信推送的消息之后给用户发起一个本地通知,这个大家可以自己研究下.
- 通过设置emoptions.displayStyle = EMPushDisplayStyleSimpleBanner;(上面代码有)可以设置有通知过来的时候的显示方式,显示一个提示或者显示完整的消息.
- 上传证书下面填写的应用包名,指的是你的BundleID !!!!我在这里踩了坑,切记!!.

测试推送:
1. 在应用完全退出的情况下(使用在环信注册的账户登录一次,确认登录成功之后再完全退出),选中我们的用户,点击发送消息:







点击发送:







测试结果:








2.程序在线的时候测试推送,还是发送"你好啊",然后我们在messagesDidReceive拦截环信的EMMessage对象,针对EMMessage对象的解析方式如下,完整的抽取环信推送消息的方法:
```
- (void)messagesDidReceive:(NSArray *)aMessages{
    
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"收到环信通知" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
        [alertView show];
    
        for (EMMessage *message in aMessages) {
            EMMessageBody *msgBody = message.body;
            switch (msgBody.type) {
                case EMMessageBodyTypeText:
                {
                    // 收到的文字消息
                    EMTextMessageBody *textBody = (EMTextMessageBody *)msgBody;
                    NSString *txt = textBody.text;
                    NSLog(@"收到的文字是 txt -- %@",txt);
                }
                    break;
                case EMMessageBodyTypeImage:
                {
                    // 得到一个图片消息body
                    EMImageMessageBody *body = ((EMImageMessageBody *)msgBody);
                    NSLog(@"大图remote路径 -- %@"   ,body.remotePath);
                    NSLog(@"大图local路径 -- %@"    ,body.localPath); // // 需要使用sdk提供的下载方法后才会存在
                    NSLog(@"大图的secret -- %@"    ,body.secretKey);
                    NSLog(@"大图的W -- %f ,大图的H -- %f",body.size.width,body.size.height);
                    NSLog(@"大图的下载状态 -- %u",body.downloadStatus);
    
    
                    // 缩略图sdk会自动下载
                    NSLog(@"小图remote路径 -- %@"   ,body.thumbnailRemotePath);
                    NSLog(@"小图local路径 -- %@"    ,body.thumbnailLocalPath);
                    NSLog(@"小图的secret -- %@"    ,body.thumbnailSecretKey);
                    NSLog(@"小图的W -- %f ,大图的H -- %f",body.thumbnailSize.width,body.thumbnailSize.height);
                    NSLog(@"小图的下载状态 -- %u",body.thumbnailDownloadStatus);
                }
                    break;
                case EMMessageBodyTypeLocation:
                {
                    EMLocationMessageBody *body = (EMLocationMessageBody *)msgBody;
                    NSLog(@"纬度-- %f",body.latitude);
                    NSLog(@"经度-- %f",body.longitude);
                    NSLog(@"地址-- %@",body.address);
                }
                    break;
                case EMMessageBodyTypeVoice:
                {
                    // 音频sdk会自动下载
                    EMVoiceMessageBody *body = (EMVoiceMessageBody *)msgBody;
                    NSLog(@"音频remote路径 -- %@"      ,body.remotePath);
                    NSLog(@"音频local路径 -- %@"       ,body.localPath); // 需要使用sdk提供的下载方法后才会存在(音频会自动调用)
                    NSLog(@"音频的secret -- %@"        ,body.secretKey);
                    NSLog(@"音频文件大小 -- %lld"       ,body.fileLength);
                    NSLog(@"音频文件的下载状态 -- %u"   ,body.downloadStatus);
                    NSLog(@"音频的时间长度 -- %u"      ,body.duration);
                }
                    break;
                case EMMessageBodyTypeVideo:
                {
                    EMVideoMessageBody *body = (EMVideoMessageBody *)msgBody;
    
                    NSLog(@"视频remote路径 -- %@"      ,body.remotePath);
                    NSLog(@"视频local路径 -- %@"       ,body.localPath); // 需要使用sdk提供的下载方法后才会存在
                    NSLog(@"视频的secret -- %@"        ,body.secretKey);
                    NSLog(@"视频文件大小 -- %lld"       ,body.fileLength);
                    NSLog(@"视频文件的下载状态 -- %u"   ,body.downloadStatus);
                    NSLog(@"视频的时间长度 -- %u"      ,body.duration);
                    NSLog(@"视频的W -- %f ,视频的H -- %f", body.thumbnailSize.width, body.thumbnailSize.height);
    
                    // 缩略图sdk会自动下载
                    NSLog(@"缩略图的remote路径 -- %@"     ,body.thumbnailRemotePath);
                    NSLog(@"缩略图的local路径 -- %@"      ,body.thumbnailLocalPath);
                    NSLog(@"缩略图的secret -- %@"        ,body.thumbnailSecretKey);
                    NSLog(@"缩略图的下载状态 -- %u"      ,body.thumbnailDownloadStatus);
                }
                    break;
                case EMMessageBodyTypeFile:
                {
                    EMFileMessageBody *body = (EMFileMessageBody *)msgBody;
                    NSLog(@"文件remote路径 -- %@"      ,body.remotePath);
                    NSLog(@"文件local路径 -- %@"       ,body.localPath); // 需要使用sdk提供的下载方法后才会存在
                    NSLog(@"文件的secret -- %@"        ,body.secretKey);
                    NSLog(@"文件文件大小 -- %lld"       ,body.fileLength);
                    NSLog(@"文件文件的下载状态 -- %u"   ,body.downloadStatus);
                }
                    break;
                    
                default:
                    break;
            }
        }
}
```

发送成功之后打印结果如下:
```
2016-12-01 16:03:26.060088 PushDemo[1392:450230] 收到的文字是 txt -- 你好啊
```
三.结语

至此,我们就成功集成了环信推送到我们的项目中.另外提供一些在做推送的时候经常会用到的小方法
- 设置应用图标右上角数字角标.
```
UIApplication *application = [UIApplication sharedApplication]; [application setApplicationIconBadgeNumber:3];
```
补充一个环信坑:
编译通过后,运行的时候爆炸,提示:dyld: Library not loaded: @rpath/Hyphenate.framework/Hyphenate
需要设置Hyphenate.frameword的Embedded Binariew属性








- 如果推送证书那里没看特别明白的话,提供一个创建推送证书的链接:http://www.jianshu.com/p/78282e16db66


- 设置推送过来时候的_apns_昵称:
```
[[EMClient sharedClient] setApnsNickname:@"推送昵称"];
```

一直在抽时间写这篇博客,平常比较忙没有大块的时间来写和记录这些东西,不过东拼西凑,没事写一点最终还是写完了.希望看到这里的小伙伴都可以成功集成环信推送,有问题可以在下面留言,我看到了肯定会回复的.希望围观的小伙伴可以不吝指点这篇博客中出现的错误,不管是文字错误还是逻辑错误等等,我一定会尽快修正,不给后人留坑.....

给出项目gitHub地址:
https://github.com/TheRuningAnt/PushDemo.git  喜欢的话,记得给小星星哈

排版可能有点问题,原博客地址:http://blog.csdn.net/mumubumao ... 23393
  查看全部
这几天项目里又用到了环信的推送,虽然之前做过,但是很久不做还是有很多细节没有注意到,所以还是决定从头开始做一遍,把每一个环节都详细记录下来,同样的把每一个坑也记录下来.方便自己以后做的时候忘记哪个流程了可以在看一遍.我很能理解那种遇到问题网上百度一堆类似答案但是并不好使的情况,所以我会将我在项目中遇到的问题都贴出来,希望能给大家带来些许参考和帮助,

一.推送的原理和流程(着急做推送的可以跳过这一步)
首先给大家推荐一个介绍推送机制很优秀的帖子:http://www.jianshu.com/p/e347f999ed95 ,里面关于本地推送和远程推送的介绍都很详细,至少我看了感觉还是收获很多的.尤其是里面有几张图片不知道是博主在哪里找的,但是真的是一看就透,太赞了,所以我果断盗过来了0.0. 这里我对推送的流程做了一个简单的叙述,力求用最简单的语言能说明整个推送的机制.

先搬过来一张图再说

692194-fc99211b942ffb8c.png


再搬一张:

692194-a1764a5b6ef76592.png



当我们的苹果手机联网的时候,会自动与苹果的服务器建立长连接,长连接的好处有很多,比如系统升级、时间校准、数据传输和响应比较快以及数据可以保持最新状态等功能.上面这两张图片简单的讲述了推送的流程:

- 1.首先我们需要将自己设备的UDID和应用的Bundle Identifier发送到苹果的服务器,然后苹果的服务器会返回给我们一个DeviceToken,这个在我看来就是创建推送证书和描述文件的过程.
- 2.我们将包含手机和应用标示的打包文件上传到做推送的服务器上去,当我们从推送服务器的后台发起推送消息的时候,推送服务器会将我们的DeviceToken和需要发送的消息Message发送到苹果的APNS(Apple push Notification Service)服务器.
- 3.当苹果的服务器收到DeviceToken和需要发送的消息Message时,会根据DeviceToken中的UDID查找设备,根据DeviceToken中的Bundle Identfier查找该应用,并将Message发送到该设备上.

下面是以QQ服务器为栗子说明的即时通讯的机制:

692194-42cd5b5723039e84.png


图片已经说得够详细明了了,我就不插嘴了,下面开始我们的工程.

二.具体流程

我们创建一个名为TestDemo的工程,我是使用Xcode8.1来开发的,工程名为PushDemo,创建好的工程界面如下(Xcode8)

1232108-fecb3186b8c4700d.png


从Xcode8之后,Xcode提供了自动管理证书的功能,这个用起来很方便,我目前在工程中用到的最多的地方就是创建好一个Demo之后,如果想真机运行的话,那么只需要在Team选择框里选择我的开发账户,接下来下面会出现一个加载提示圈,等它加载完了就可以在真机上运行了,这个过程实际上是Xcode使用你当前的BundleId去该账户的开发这中心创建了对应的AppId和描述文件,但是我们既然是作为一个开发流程的记录,就自己来创建这些东西,所以,我们取消选择Automatically manage signing选项.此时界面如下:

1232108-6da09aaa4693b3b3.png



好了,我们要正式开始我们的工作了GO GO GO!
1. 首先我们先去官网创建AppID和描述文件.      

我们是要集成推送的,所以我们需要用到cer文件,这个东西实际上就是苹果给开发者颁发的一个证书,我们需要将它导入到我们的AppId配置里,否则的话是无法集成推送的,还记得安装应该的时候会提示"无法安装为认证发布者的应用"之类的信息么,我猜测这个cer文件就是我们身份的标示,使我们开发的应用可以供人们正常安装使用,关于证书有一篇很详细的帖子,希望了解证书之类信息的看官可以去瞅瞅:http://m.blog.csdn.net/article/details?id=8617788

创建cer文件的流程很简单,打开"钥匙串访问"(虽然很好找,但是还是把图贴出来吧,怕小朋友迷路)

1232108-ab1cf50531874785.png



1232108-6438c3fb50b4aaa5.png



打开钥匙串之后点击"从证书颁发机构请求证书"


1232108-d4a8951b51e6cceb.png


邮箱和常用名随便填写,记住下面的选择框选择"存储到磁盘"

1232108-bda705277e11698e.png



点击存储

1232108-07e46d1757718ea4.png



已经在桌面保存了


1232108-43a584c54d8f6cf2.png



到此,我们已经创建好了cer文件,接着我们去开发者中心创建AppId和描述文件

2. 创建AppId和描述文件

首先进入开发者中心,百度搜索Apple Developer,(哎 真的是详细到家了啊,我都人不下去了)
上图

1232108-cedf60744b970a2e.png



输入开发者账户,登录进去


1232108-2b564af543f98b20.png


你将看到这个页面

1232108-a8daff6248a1238a.png



点击看到:

1232108-e9a6e57aa9930544.png


输入AppId文件名和BundleId

1232108-ae96fe218d56e753.png


选中下面的PushNotifications

1232108-38bf6bb6a67f51d2.png


点击Continue:

1232108-934cf686ea792fe8.png


点击register:

1232108-083327989bcbe786.png


点击Done回到AppId列表页面

1232108-0538ef84dea33c70.png


在AppId列表页面可以看到我们的AppID了

1232108-95b229c6dbadcdac.png



但是,还没有完成,因为我们是要做推送的,所以需要上传我们的cer文件
,点击我们的AppId,在展开的详情里可以看到:

1232108-15f6e6cba67bcf32.png




Push Notification的两个指示灯还是黄色的状态,我们要将它启用,点击Edit,在点开的页面里滑动至底部,记得要选中Push Notification按钮,接着点击上方的开发证书下的创建证书按钮:

1232108-6e60ef33f39c3c3e.png



点击Continue

1232108-20ba8ef5aac404fe.png



点击 choose file:

1232108-a8b6d1f97c9f57a7.png



将我们从开发机构请求的证书传上去,之后点击Register:

1232108-be277d8092ca589a.png



点击Register之后的页面,点击download,将其下载到桌面上,download之后记得点击done完成文件创建:

1232108-70ad59ee048b37de.png



桌面上的文件:

1232108-ea6f4078346a5a1c.png



现在我们就完成了给AppID创建开发者证书,然后我们要给它创建发布者证书,点击Done之后回到AppIds列表,如果找不到的话,点击右边的App IDs

1232108-f3563cf07940ad50.png



点开项目的AppId,此时界面如下,点击最下面的CreateCertificate,开始给AppID创建发布者证书,给AppId创建发布者证书流程跟创建开发者证书是一样的!给AppId创建发布者证书流程跟创建开发者证书是一样的!给AppId创建发布者证书流程跟创建开发者证书是一样的!重要的事情说三遍!!因为我不贴出来创建发布证书的图了,所以各位根据创建开发证书的流程再走一遍就好,同样也要将发布者证书下载到本地.:

1232108-5d146f8fcbf96aa2.png



1232108-f4959adf27635124.png



当创建好之后在回到这个页面时,应该显示如下所示:

1232108-d9e0b2bf3794fad2.png



此时本地我们下载的文件如下:

1232108-651e46a585df0fd2.png



然后将这两个证书拖到钥匙串里,步骤如下:
首先打开钥匙串:

1232108-2ed433418c0ceaf9.png



1232108-4907f4f3f01371e6.png


然后先点击:系统-证书,然后将两个文件拖进去,会提示你输入开机密码,输入就好了(建议添加之前先对这个界面截屏,添加完之后可以对比刚刚添加了那些文件)

1232108-9e9434ee2246e3ce.png



添加完之后是这个样子,画框的是我们的证书

1232108-c71476ca00c853ec.png



然后选择左边的"登录"选项,可以看到我们刚才创建的证书

1232108-b7e1a0917e1bdc6a.png


选中第一个证书,然后右键(你懂得右键的意思),选择导出...

1232108-b020b7d0a48f795d.png



选择导出为P12文件,存储在桌面上,获取到P12文件.对这两个证书进行同样的操作.(记得标题有(Develop)的起名为Product文件,第二个证书导出的时候起名为Develop,名字可以自己定,只是为了区别)

1232108-04d80a4621bc1708.png


然后会提示你输入密码,这里我设置的密码是zx123456,自己设定好一定要记住,一会儿要用.

1232108-409c20593f4f262e.png


然后可以在桌面上看到我们导出的P12文件啦

1232108-964de37f66433eaa.png



现在我们就完成了所有的证书的创建,可以去环信上创建我们的应用啦.

3.创建真机调试文件以及导入到项目中

因为必须要进行真机测试,而且我们关闭了自动管理证书,就导致Xcode8不会自动帮我们生成证书,所以我们要自己创建真机调试证书并导入到项目中去,流程如下:

创建描述文件:

1232108-9dbec2cea23ab8e1.png



选择开发模式,下一步:

1232108-edece2d8c17d8f27.png



选择对应的AppID,选择我们刚才创建的AppId:

1232108-ee9029c89f0c34d2.png



选择开发团队,我一般都是全选的,下一步:

1232108-3744e08d9d10aa55.png



选择真机调试的机器,全选,下一步:

1232108-124184468c7c6531.png



下一步:

1232108-c6c0e50e57add4be.png



将创建好的描述文件下载下来,放到桌面上:

1232108-8a2c9400633c796d.png



创建好的描述文件:

1232108-40bebec424947b9d.png



首先选择debug模式下载的真机调试描述文件:

1232108-a1d8a4c3a0bb0a23.png


选择桌面上刚刚下载的描述文件:

1232108-692279ac01c7d137.png



使用同样的步骤,选择Release模式下的真机调试文件,一模一样的操作,不贴图了.两个文件都导入进去之后,插上真机,就可以进行真机调试了.

4.在环信创建我们的应用

首先百度搜索环信,打开他们的官网,先注册账户,注册过的可以跳过了,上图:
注册的时候选择"注册即时通讯云"

1232108-672cbab760c523f9.png



注册的时候需要填写各种信息,按照格式填写就好了,填写完之后登陆,点击创建应用

1232108-bd67f4f4f35cd764.png



填写应用信息

1232108-4d748bd8c621d0ff.png



填写完如下图咯

1232108-bbdc1fbea11501aa.png



然后需要上传我们的P12文件,图片很清晰- -,不多说,第一次我选择上传的是生产证书:

1232108-6b5a19a243a78839.png



第二次上传开发证书:

1232108-538c02769688cac0.png



至此,我们的证书开发也都上传完了,路漫漫其修远兮,开始集成环信到代码里吧

5.集成环信到项目中

首先在这里下载最新的SDK(截至到写本文时最新的SDK为)

http://www.easemob.com/download/im 环信推送SDK下载链接

点击iOS的最新SDK下载,这里下载的是V3.x的SDK

1232108-279c3c47c46ec724.png



下载到桌面是这个鬼样子

1232108-9d5b7d0ee1c2d404.png



我们只需要将画圈的两个文件夹导进去工程里就好了,其他的用不上

1232108-e8d9522b4f496454.png



导进去之后文件列表是这样,编译会出错别急,慢慢改.

1232108-da727a18407e70d1.png



向项目里添加需要的库

1232108-e0ac523eac1d6042.png



上面的图片是截取的环信官方文档,我添加完是这个样子的:

1232108-5409054190742754.png


方便复制库名的文字:
CoreMedia.framework
AudioToolbox.framework
AVFoundation.framework
MobileCoreServices.framework
ImageIO.framework
libc++.dylib
libz.dylib
libstdc++.6.0.9.dylib
libsqlite3.dylib
(如果使用的是 xcode7,后缀为 tbd。)
这一步很重要,因为SDK 不支持 bitcode,所以要将 Build Settings → Linking → Enable Bitcode 中设置 NO。


1232108-96cd9023e11f17bd.png



command+B编译工程,大量爆红.别着急,修改我们的PCH文件就好了
在PCH文件添加
```
#ifdef __OBJC__
    #import <UIKit/UIKit.h>
#endif
```

将我们所有定义和添加的头文件和宏定义,都放在#ifdef __OBJC__和#endif中间
就可以解决这个问题.

然后在项目里打开推送:

1232108-96cd9023e11f17bd.png



6.测试是否集成成功

首先,我们去环信的后台给我们的应用添加一个用户

1232108-8abe301c76c6c7f4.png



用户名我设置成了:13051698888  密码设置成了:222222

1232108-94c1ef7dbdf3014c.png



接着我们要去appledate.m文件里添加东西了,很重要一步,废话不多说,直接贴出来需要配置的代码,直接拿去用0.0,需要添加的东西我在注释里注释的很明白...
记得要导进去头文件
#import "EMSDK.h"

```
@interface AppDelegate ()<EMChatManagerDelegate>

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //AppKey:注册的AppKey,点击"应用概述"可以看到AppKey,粘贴过来就可以。
    //apnsCertName:推送证书名,填写你的开发证书或者发布证书名,就是上传到环信后台的两个中的一个,什么环境下测试使用什么环境的证书。
    EMOptions *options = [EMOptions optionsWithAppkey:@"1192161108178165#testpushdemo"];
    options.apnsCertName = @"Develop";
    [[EMClient sharedClient] initializeSDKWithOptions:options];

    //登录环信 这里使用的是我刚才在环信后台创建的账户名和密码,使用这个账户登录,到时候如果在后台给客户端发消息的话,就可以找到该用户
    [[EMClient sharedClient] loginWithUsername:@"13051698888"
                                      password:@"222222"
                                    completion:^(NSString *aUsername, EMError *aError) {
                                        if (!aError) {
                                            NSLog(@"环信登陆成功");
                                            EMPushOptions *emoptions = [[EMClient sharedClient] pushOptions];
                                            //设置有消息过来时的显示方式:1.显示收到一条消息 2.显示具体消息内容.
                                            //自己可以测试下
                                            emoptions.displayStyle = EMPushDisplayStyleSimpleBanner;
                                            [[EMClient sharedClient] updatePushOptionsToServer];
                                        } else {
                                            NSLog(@"环信登陆失败");
                                        }
                                    }];
    
    
    /**
     注册APNS离线推送  iOS8 注册APNS
     */
    if ([application respondsToSelector:@selector(registerForRemoteNotifications)]) {
        [application registerForRemoteNotifications];
        UIUserNotificationType notificationTypes = UIUserNotificationTypeBadge |
        UIUserNotificationTypeSound |
        UIUserNotificationTypeAlert;
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:notificationTypes categories:nil];
        [application registerUserNotificationSettings:settings];
    }
    else{
        UIRemoteNotificationType notificationTypes = UIRemoteNotificationTypeBadge |
        UIRemoteNotificationTypeSound |
        UIRemoteNotificationTypeAlert;
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:notificationTypes];
    }
    
    //添加监听在线推送消息
   [[EMClient sharedClient].chatManager addDelegate:self delegateQueue:nil];    
    return YES;
}

//监听环信在线推送消息
- (void)messagesDidReceive:(NSArray *)aMessages{
    
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"收到环信通知" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
        [alertView show];
        
        //aMessages是一个对象,包含了发过来的所有信息,怎么提取想要的信息我会在后面贴出来.
}

// 将得到的deviceToken传给SDK
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
    [[EMClient sharedClient] bindDeviceToken:deviceToken];
}

// 注册deviceToken失败
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
    NSLog(@"error -- %@",error);
}

// APP进入后台
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [[EMClient sharedClient] applicationDidEnterBackground:application];
}

// APP将要从后台返回
- (void)applicationWillEnterForeground:(UIApplication *)application
{
    [[EMClient sharedClient] applicationWillEnterForeground:application];
}
```
上面的几个方法在appdelegate里是必须重写的,不然会直接导致推送不成功.其中.需要重点说明的是:

- 只有在应用完全退出被杀掉的状态下,才可以收到环信推送的通知;
- 如果要发送在线的通知,需要在messagesDidReceive方法里获取到环信推送的消息之后给用户发起一个本地通知,这个大家可以自己研究下.
- 通过设置emoptions.displayStyle = EMPushDisplayStyleSimpleBanner;(上面代码有)可以设置有通知过来的时候的显示方式,显示一个提示或者显示完整的消息.
- 上传证书下面填写的应用包名,指的是你的BundleID !!!!我在这里踩了坑,切记!!.

测试推送:
1. 在应用完全退出的情况下(使用在环信注册的账户登录一次,确认登录成功之后再完全退出),选中我们的用户,点击发送消息:

1232108-8e6a60d144269c67.png



点击发送:

1232108-17f029870d36abef.png



测试结果:

1232108-aa2b808cf5cd1c6d.png




2.程序在线的时候测试推送,还是发送"你好啊",然后我们在messagesDidReceive拦截环信的EMMessage对象,针对EMMessage对象的解析方式如下,完整的抽取环信推送消息的方法:
```
- (void)messagesDidReceive:(NSArray *)aMessages{
    
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"收到环信通知" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
        [alertView show];
    
        for (EMMessage *message in aMessages) {
            EMMessageBody *msgBody = message.body;
            switch (msgBody.type) {
                case EMMessageBodyTypeText:
                {
                    // 收到的文字消息
                    EMTextMessageBody *textBody = (EMTextMessageBody *)msgBody;
                    NSString *txt = textBody.text;
                    NSLog(@"收到的文字是 txt -- %@",txt);
                }
                    break;
                case EMMessageBodyTypeImage:
                {
                    // 得到一个图片消息body
                    EMImageMessageBody *body = ((EMImageMessageBody *)msgBody);
                    NSLog(@"大图remote路径 -- %@"   ,body.remotePath);
                    NSLog(@"大图local路径 -- %@"    ,body.localPath); // // 需要使用sdk提供的下载方法后才会存在
                    NSLog(@"大图的secret -- %@"    ,body.secretKey);
                    NSLog(@"大图的W -- %f ,大图的H -- %f",body.size.width,body.size.height);
                    NSLog(@"大图的下载状态 -- %u",body.downloadStatus);
    
    
                    // 缩略图sdk会自动下载
                    NSLog(@"小图remote路径 -- %@"   ,body.thumbnailRemotePath);
                    NSLog(@"小图local路径 -- %@"    ,body.thumbnailLocalPath);
                    NSLog(@"小图的secret -- %@"    ,body.thumbnailSecretKey);
                    NSLog(@"小图的W -- %f ,大图的H -- %f",body.thumbnailSize.width,body.thumbnailSize.height);
                    NSLog(@"小图的下载状态 -- %u",body.thumbnailDownloadStatus);
                }
                    break;
                case EMMessageBodyTypeLocation:
                {
                    EMLocationMessageBody *body = (EMLocationMessageBody *)msgBody;
                    NSLog(@"纬度-- %f",body.latitude);
                    NSLog(@"经度-- %f",body.longitude);
                    NSLog(@"地址-- %@",body.address);
                }
                    break;
                case EMMessageBodyTypeVoice:
                {
                    // 音频sdk会自动下载
                    EMVoiceMessageBody *body = (EMVoiceMessageBody *)msgBody;
                    NSLog(@"音频remote路径 -- %@"      ,body.remotePath);
                    NSLog(@"音频local路径 -- %@"       ,body.localPath); // 需要使用sdk提供的下载方法后才会存在(音频会自动调用)
                    NSLog(@"音频的secret -- %@"        ,body.secretKey);
                    NSLog(@"音频文件大小 -- %lld"       ,body.fileLength);
                    NSLog(@"音频文件的下载状态 -- %u"   ,body.downloadStatus);
                    NSLog(@"音频的时间长度 -- %u"      ,body.duration);
                }
                    break;
                case EMMessageBodyTypeVideo:
                {
                    EMVideoMessageBody *body = (EMVideoMessageBody *)msgBody;
    
                    NSLog(@"视频remote路径 -- %@"      ,body.remotePath);
                    NSLog(@"视频local路径 -- %@"       ,body.localPath); // 需要使用sdk提供的下载方法后才会存在
                    NSLog(@"视频的secret -- %@"        ,body.secretKey);
                    NSLog(@"视频文件大小 -- %lld"       ,body.fileLength);
                    NSLog(@"视频文件的下载状态 -- %u"   ,body.downloadStatus);
                    NSLog(@"视频的时间长度 -- %u"      ,body.duration);
                    NSLog(@"视频的W -- %f ,视频的H -- %f", body.thumbnailSize.width, body.thumbnailSize.height);
    
                    // 缩略图sdk会自动下载
                    NSLog(@"缩略图的remote路径 -- %@"     ,body.thumbnailRemotePath);
                    NSLog(@"缩略图的local路径 -- %@"      ,body.thumbnailLocalPath);
                    NSLog(@"缩略图的secret -- %@"        ,body.thumbnailSecretKey);
                    NSLog(@"缩略图的下载状态 -- %u"      ,body.thumbnailDownloadStatus);
                }
                    break;
                case EMMessageBodyTypeFile:
                {
                    EMFileMessageBody *body = (EMFileMessageBody *)msgBody;
                    NSLog(@"文件remote路径 -- %@"      ,body.remotePath);
                    NSLog(@"文件local路径 -- %@"       ,body.localPath); // 需要使用sdk提供的下载方法后才会存在
                    NSLog(@"文件的secret -- %@"        ,body.secretKey);
                    NSLog(@"文件文件大小 -- %lld"       ,body.fileLength);
                    NSLog(@"文件文件的下载状态 -- %u"   ,body.downloadStatus);
                }
                    break;
                    
                default:
                    break;
            }
        }
}
```

发送成功之后打印结果如下:
```
2016-12-01 16:03:26.060088 PushDemo[1392:450230] 收到的文字是 txt -- 你好啊
```
三.结语

至此,我们就成功集成了环信推送到我们的项目中.另外提供一些在做推送的时候经常会用到的小方法
- 设置应用图标右上角数字角标.
```
UIApplication *application = [UIApplication sharedApplication]; [application setApplicationIconBadgeNumber:3];
```
补充一个环信坑:
编译通过后,运行的时候爆炸,提示:dyld: Library not loaded: @rpath/Hyphenate.framework/Hyphenate
需要设置Hyphenate.frameword的Embedded Binariew属性


1232108-0167fe66d3cd3151.png



- 如果推送证书那里没看特别明白的话,提供一个创建推送证书的链接:http://www.jianshu.com/p/78282e16db66


- 设置推送过来时候的_apns_昵称:
```
[[EMClient sharedClient] setApnsNickname:@"推送昵称"];
```

一直在抽时间写这篇博客,平常比较忙没有大块的时间来写和记录这些东西,不过东拼西凑,没事写一点最终还是写完了.希望看到这里的小伙伴都可以成功集成环信推送,有问题可以在下面留言,我看到了肯定会回复的.希望围观的小伙伴可以不吝指点这篇博客中出现的错误,不管是文字错误还是逻辑错误等等,我一定会尽快修正,不给后人留坑.....

给出项目gitHub地址:
https://github.com/TheRuningAnt/PushDemo.git  喜欢的话,记得给小星星哈

排版可能有点问题,原博客地址:http://blog.csdn.net/mumubumao ... 23393
 
0
评论

apns上传的是什么文件? 文件 apns 推送证书

环信专业服务 发表了文章 • 1184 次浏览 • 2015-09-16 10:53 • 来自相关话题

推送证书需要是P12格式的。
推送证书需要是P12格式的。