Ping++ 「变现时代」大会
「变」意味着「变化」,「现」代表着「当下」。所谓「与时迁移,应物变化,设策之机也」,企业们不仅要活在当下,更要拥抱变化。
值此年关,Ping++ 携手各界合作伙伴,邀请到那些勇于自我颠覆、创新商业模式的企业家们,分享他们这一年来对于商业模式、企业转型、业务增长上的见解与心得。
为了简单温暖的支付体验,Ping++ 惟愿伴你一路同行。
大会议程
时间:2016 年 12 月 17 日 13:00 - 17:00
地址:北京市朝阳区太阳宫北街 2 号院 1 号楼, LAVIN 玫瑰里·太阳公元·心之芳庭
(地铁乘坐城铁10号线、13号线到芍药居站下车即到)
13:00 - 13:30 入场签到
13:30 - 13:40 开场致辞
13:40 - 14:10 分主题 · 流量 | 在行 & 分答联合创始人 杨璐
14:15 - 14:45 分主题 · 内容 | 什么值得买 CEO 那昕
14:50 - 15:20 分主题 · 平台 | 掌合天下市场 VP 张龙飞
15:25 - 15:55 分主题 · 共享 | ofo 共享单车联合创始人 张巳丁
16:00 - 16:30 分主题 · 开放 | Ping++ 聚合支付 CEO 金亦冶
16:30 - 17:00 茶歇 & 交流
注:以上议程有可能变动,以现场实际议程为准
嘉宾介绍
杨璐
在行&分答联合创始人,市场 VP
嘉宾简介:
在进入在行&分答前,杨璐拥有 12 年的广告从业经验。八年的奥美工作经验,每年服务过亿投放量的客户,练就了扎实的专业基础和团队管理能力,成为奥美亚太地区最年轻的客户群总监。加入在行后,与团队上线了 2016 年互联网界最吸引人瞩目的付费语音问答产品——分答。分答上线后 42 天成功融资 2500 万美金,估值上亿美金。
那昕
什么值得买 CEO
嘉宾简介:
曾任京东智能集团副总裁并推出京东硬件平台“JD+”计划,于 2015 年 6 月受创始人隋国栋邀请加入什么值得买。什么值得买(SMZDM.COM)成立于 2010 年 6 月 30 日,是一家集导购、媒体、工具、社区属性为一体的消费领域门户型网站,因其中立、专业而在众多网友中树立了良好口碑,为消费者提供决策建议。
张龙飞
掌合天下市场 VP
嘉宾简介:
资深互联网/电子商务从业者,曾先后服务过 263 网络集团、中国数码集团、学大教育集团以及国内最大的电子商务新闻门户亿邦动力网,熟悉电子商务行业、精通互联网市场营销。拥有 10 年的互联网行业工作经验,现任掌合天下市场营销中心负责人。掌合天下成立于 2013 年,是一家专注于快消品供应链的电子商务平台,依托独创的“城市合伙人”模式和专业的快消互联网运营经验,为供货商和超市提供便捷,透明,安全的一站式 B2B 综合服务,现业务已覆盖全国的 27 省及自治区的 600 多个城市,并于今年 10 月完成 7 亿元的 B 轮融资。
张巳丁
ofo 共享单车联合创始人
嘉宾简介:
重度骑行爱好者和极限运动爱好者。北大考古 2013 届本科,2015 届文化遗产硕士。ofo 是全球首个无桩共享单车出行解决方案,首创“单车共享”模式。上线一年来,ofo 已成为国内规模最大的共享单车平台,拥有 10 万辆共享单车,提供超过 2000 万次共享单车服务,为 21 座城市 200 多万用户提供便捷的出行服务。2016 年 10 月,ofo 完成 1.3 亿美元 C 轮融资。
张一甲
Xtecher 联合创始人
嘉宾简介:
科技媒体、科技企业服务平台 Xtecher 联合创始人。毕业于北京大学数学科学学院,获经济学双学位。曾获中国数学奥林匹克金牌,入选国家集训队。毕业后先后就职于奥美中国、百度,为奔驰、伊利、奥迪、雀巢、康师傅、361度等国际一流客户提供品牌策划、创意管理和长期服务。Xtecher 成立于 2015 年 4 月,致力于发现最有潜力的早期科技项目,并为它们进行全面的价值加速。
金亦冶
Ping++ 创始人&CEO
嘉宾简介:
连续创业者,斯坦福大学电子工程硕士学位,2015 年入选福布斯中国 30 位 30 岁以下创业者榜单。2014 年创立面向开发者提供移动支付 SDK 服务的公司 --「Ping++」,让「7 行代码接入支付」成为了业内新标准,2015 年 12 月获得宽带资本领投的千万美元 B 轮融资。
大会媒体/合作联系:马锐 18608948398(同微信)、安贤龙 17710330365(同微信)
合作伙伴
主办方:Ping++ 聚合支付系统
联合主办:Xtecher
协办方:什么值得买、分答 & 在行、掌合天下、ofo 共享单车
特别合作:微软加速器、环信、北京天津企业商会、天天投、互动吧
合作伙伴:灵伴科技、纳什空间、鸟哥笔记、SDK.cn
媒体合作:Donews、创业邦、人人都是产品经理
速记支持:有道云笔记
ping++微信公众号,
特别提醒:为保证活动质量,本次大会为收费制,50 元/人。环信作为本次大会的合作伙伴,其用户/粉丝可直接使用 VIP 邀请码进行报名,无需付费。请通过关注 Ping++ 公众号:Pingplusplus,后台回复”环信+公司+职位“领取 VIP 邀请码。
报名方式:扫描以下二维码进入报名页面,
输入邀请码,报名费会自动变为 0.01 元,支付 0.01 元后即可完成报名。 收起阅读 »
iOS 环信昵称、头像、群头像、群昵称处理
废话不多说,直接进入主题。因为这次不涉及sdk内的什么,所以不用管SDK版本。
重中之重:先和你的好基佬,安卓哥们定好走什么流程
环信官方不会跟你存储好友关系什么的,昵称头像什么的就不要想着偷懒了,所以自力更生吧!!
单人昵称 + 头像
方法一:自家服务器建张表,把所有的好友关系存储起来,这也是最好的,能够做到昵称头像实时更新等:
1、后台建表存储好友关系后,我们在每次登陆后,开一个线程把表数据请求下来存起来。方法二:把昵称头像放到消息拓展中。
2、写几个方法,根据环信ID查找表中的昵称和头像。
3、更新昵称和头像,可以像微信一样,点击头像查看好友详情时进行更新;还有自家好友列表应该会给最新的,这个时候同步更新一份。(写方法,进行更新)
easeui中发送方法中把昵称头像传到ext中去
在push到聊天界面时,把昵称头像放到拓展中互传
原谅这是以前的代码,没有做到简化,原理一样,就是在聊天时,把自己的昵称头像和对方的昵称头像放到一个字典里,自己定Key,把它加到消息体中的拓展里面,每次拿到消息时,直接取消息体中的拓展,把相对应的拿出来展示就可以。
两者比较:
前者:最理想的方法之一,就是要多写点代码,建张表和刷选而已,具体缺点,我还没发现重点:后者其实也可以跟新的啦!!!!
后者:简单容易处理,新生版本可以考虑,减少开发时间,但是测试肯定给你找问题,我先聊几句,然后改个昵称和头像,尼玛,改完之前还是老昵称和头像,这是因为这些消息体也是存到本地的,没有给你更新,因为拓展就是为了便于开发者开发各种消息的,所以做不到给你更新。
这只是一个例子,我用来更新我的业务逻辑的
根据环信ID,拿到消息体的拓展,把以前的昵称和头像都更新下就可以啦!
具体的方法可以参考环信官方:http://docs.easemob.com/im/490integrationcases/10nickname
群聊名称 + 头像
方法一:把所有的好友信息包括昵称头像等放到群组的群名称中去。
群名称
拿到群名称后,自己写方法,把里面的的各种数据拿出来
各种方法
群名称的方法
其他的我就不做过多展示,给一个效果图:
群头像的九宫格展示:直接去gitub上面搜索就可以找到,各种各样的,只需把头像传进去,返回一个imageView(大部分是本地图片效果,所以需要自己改成网络的)。方法二:拓展消息
同样可以借鉴单聊中使用到的消息体中的拓展。然后自己写方法把里面的数据拿出来,具体方法我没有操作过,有兴趣的朋友可以尝试下。
有建议和好的想法的小伙伴可以提出来,大家互相讨论下,增长知识。有不懂的可以找我:qq:1804094055
收起阅读 »
iOS 新手集成单聊、群聊、语音和视频通话的简述
(1)集成环信SDK:
pod:pod 'HyphenateFullSDK'
手动:因为我们要使用到语音和视频的功能,所以我们需要导入(环信 iOS HyphenateFullSDK 开发使用(包含实时通话功能))HyphenateFullSDK这个包。手动导入包文件后,我们需要手动加上一些库:
第 1 步:SDK 包含实时语音依赖库有:
CoreMedia.framework
AudioToolbox.framework
AVFoundation.framework
MobileCoreServices.framework
ImageIO.framework
libc++.dylib
libz.dylib
libstdc++.6.0.9.dylib
libsqlite3.dylib
libiconv.dylib
(如果使用的是 xcode7,后缀为 tbd。)
第 2 步:SDK 不支持 bitcode,向 Build Settings → Linking → Enable Bitcode 中设置 NO。
(2)添加EaseUI:
必须和SDK相对应的版本,不然会出现各种报错(方法找不到或者不对)
注意:如果编译报错,1、先检查EaseUI中的第三方是否和本地工程中的重复。 2、在PCH文件中引入头文件时:
#ifdef __OBJC__ #import "easeUI.h" #import "EMSDKFull.h" 等等 #endif
正式开始代码的编写:
初始化SDK:
//AppKey:注册的AppKey,详细见下面注释。//apnsCertName:推送证书名(不需要加后缀),详细见下面注释。
EMOptions*options=[EMOptions optionsWithAppkey:@"douser#istore"]; options.apnsCertName=@"istore_dev"; [[EMClient sharedClient]initializeSDKWithOptions:options];
注册:
EMError*error=[[EMClient sharedClient]registerWithUsername:@"8001"password:@"111111"];if(error==nil){NSLog(@"注册成功");}
登陆:
EMError*error=[[EMClient sharedClient]loginWithUsername:@"8001"password:@"111111"];if(!error){NSLog(@"登录成功");}
注意:具体的自动登录(免登陆)、重连、退出登陆、异地登录等请移驾至环信官方:http://docs.easemob.com/im/300iosclientintegration/30iossdkbasic
聊天会话列表界面:建议自己搭建,便于管理和拓展
1:直接用环信的列表界面:ConversationListController 直接初始化加到自己的tabar上去
2:自己搭建列表界面:
获取与自己相关的所有的会话
cell上的角标、时间、信息等
tabar上的角标
- (void)didReceiveMessages:(NSArray *)aMessages;是刷新该列表的重点(记住注册及代理)。对方发来的消息都会在这个方法中进行刷新列表及跟新角标数等。
注意:其他代码自行到demo中去寻找,环信demo中都有参考;
单聊+群聊:因为自己写的效果远没有环信的好,加上需求不要对聊天界面进行自定义,所以最后我还是直接用的demo中的界面(把demo中的ChatViewController拖到自己工程中,编译,注释掉报错的代码),初始化,push到聊天界面即可:
ChatViewController *chatController = [[ChatViewController alloc] initWithConversationChatter:conversation.conversationId conversationType:conversation.type];
群列表:获取与之相关所有的群
NSArray *groups = [[EMClient sharedClient].groupManager getMyGroupsFromServerWithError:nil];
语音和视频及时通话:因为都是环信写的 所以把有关及时通话的文件拖进来;
ChatDemoHelper CallViewController
1:在pct中加上 #define DEMO_CALL 1
2:全局搜索#if DEMO_CALL == 1 删掉,编译如有报错请仔细看是不是哪句代码重复了或者哪里没有注释完全。
3.ChatDemoHelper.m中 注册代码到——#pragma mark - EMCallManagerDelegate宏中间的代码都可以注释掉
重中之重:在根控制器中一定要把控制器赋给ChatDemoHelper:[ChatDemoHelper shareHelper].mainVC = self;
语音和视频通话必走的代码
如果集成语音和视频过程中有问题的,可以参考官方给出的视频,不过只能借鉴:http://www.imgeek.org/video/24
上面所述就是我使用环信的心得,不是很全面。大神手下留情,新手一枚。后续我会把单人昵称、头像;群组名称、群组头像等等的一些方法写出来,如果发现我所提出的有问题和有好的建议,请直接提出来,也可以一起讨论。qq:1804094055 有问题可以找我,环信讨论群:340452063。
收起阅读 »
呼叫中心还是客户中心?
近年来,呼叫中心常常被称为这个时代的“白领血汗工厂”。作为一名资深的客户服务代表、主管、经理、总监,当我第一次听到这种说法时,被深深地触动了。我熟悉的很多呼叫中心都把办公场所设在比较偏远的地方,在这些地方一般人很难把工作有效地完成做好,但客服工作人员却可以在电话里处理好各种任务。
想一想,传统的呼叫中心是什么样子呢?它们通常是由一些普通格子间组成,几乎没有什么可以发挥创造力的空间。通话时长和通话处理时长都是很重要的指标,这说明每一通电话都是在处理业务而不是单纯地交流互动。另外对于呼叫中心的工作人员来说,即使公司朝着蓬勃的方向发展,客服工作人员的发展空间也是极其有限的。
将呼叫中心转型为客户中心。有人会认为,以这样一种方式来加深企业与客户之间的关系,无异于痴人说梦。但事实真的是这样吗?其实只要做出一些调整,呼叫中心就可以变为客户中心。
第一步也是最简单的一步是将部门名称改为客户中心。如果我们希望员工成为客户关系的建立者,那么我们应该从部门的定位开始。在这个以交易时间、任务量和呼入量来微观管理的时代,我们应该时常这样反问自己:如果我们不以最好的方式来对待我们的员工,又怎能期望他们以最好的方式来对待我们最尊贵的客人?如果做不到最好,起码得一视同仁,只可惜我们连这样也做不到,我们只是一味地强调员工是企业与客户关系的建立者以及公司产品的形象代表,仅此而已。通常情况下,呼叫中心是企业与客户仅有的互动方式。客户愿意花时间打电话给我们,是因为遇到了各种类型的问题,他们需要我们提供帮助。难道我们不想让员工在成为公司政策执行者的同时还是客户问题的解决者吗?这样不仅不会让客户的投诉不断升级,也能更好地帮旅客解决问题。
如何管理比较合适呢?怎样能在让公司在付出最小代价的同时能够给员工最大的权限去帮客户解决问题?这就需要我们花时间培养员工提前预判的能力并在此基础上出色地完成任务,这样也能在机会来临时给客户带去惊喜。这其中的关键是需要准备,我们不能单纯地期望我们的员工认识到这些东西,也不能在一个问题上只告诉他们一次就期待他们能坚持,更不能在没有被加强训练的情况下期待他们保持正确的工作习惯。
解决方案:创建一个世界一流的服务体系。在这样一个体系中,所有员工都能发现并及时指出不足,坚持同样的标准,在把握机会的同时不断变得更好。为了能让员工更好地处理每天发生的不同情况,我们需要花更多的时间在幕后管理他们。这允许我们监督客服代表的活动以确保团队中的每个成员不在微观管理下都能恪尽职守。这让我们的客服代表们不会压力过大、负担过重进而保持员工数量的稳定性,因为我们没有足够的人员来雇佣和培训,这对呼叫中心来说是一大难题。这听起来很棒,但我们如何把它完成好呢?我建议从以下两个步骤开始,但两者都将需要投入一定的时间和人力成本。
第一步是让你的团队一起参与创造你的客户体验周期,这包括与团队一起研究确定客户的接触点。一旦确定了这些接触点,你就可以借此去剖析每一个人,找到可能出错的地方(服务缺陷),接下来就知道每个人和每通电话里需要做什么(操作和体验标准),同时我们能通过哪些方式来取悦客户(利用机会超越机会)。
通过这个项目,你和你的一线团队将会大开眼界,并产生新的使命感。你的团队会重现活力并能很好地完成工作。虽然这是一个很棒的开始,你不能指望这样一个开始在没有加强巩固的基础上就能保持不断发展的势头。接下来我们该做第二步了。
第二步是解决日常会议。在你说“这在这里永远都行不通,因为……”之前(我知道你会这样说,因为我听过所有的借口,而且我自己曾经也这样说过),可以思考下金牌服务的典范:丽思卡尔顿酒店。他们每天都会举行一个他们称之为“站起来”的会议。福来鸡也一样。这些公司已经忽略每个员工不能每天都出席会议的事实,因为他们一天有多种轮班制。他们能做的是利用好平台专注他们的服务价值,讨论并解决问题,庆祝每天成功的案例。
结论:这个过程在成就一个伟大的团建活动的同时也会不断提升团队成员的自主性和增强他们的归属感。创建属于自己客户体验周期,并在日常活动中不断加强,这有助于给团队带去新的使命感,并让员工变成真正的客户关系的建设者。随着日常会议深入,活动并不会因时间推移而逐渐消失,而是会变成一种超越规范并深入人心的文化。
本文原载于《客户世界》2016年11月刊;作者Dave Murray,DiJulius集团高级客户体验顾问;译者皮晶晶,深圳航空营销委电子商务电话营销中心运营人员。 收起阅读 »
终于等到你|“好客之道-客户管理轻学院”领跑互联网轻学时代
老师,我想学习,没有时间怎么办?”2016年11月30日,广州。借举办“2016全媒体客户中心管理论坛”的契机,客户世界机构今天正式宣布推出“好客之道”客户管理轻学院。
“我入行客户中心行业10年了,想分享一些自己的管理经验,没有渠道什么办?”
“现在有好多微课,微信公众平台视频学习,直播学习,不知道如何规划,选择什么渠道学习什么办?”
“这是一个最好的时代,也是一个最坏的时代”。我们对学习的需求一直存在,但面对茫茫书海以及网上众多课程,如何筛选,如何迅速抓住重点,如何快速吸收成了最关键的问题。
“轻学院”以促进客户管理从业人员的岗位培训与职业发展、提升全社会客户管理意识及客户服务水平为宗旨;系统梳理客户中心和电子商务行业的专业知识并深入研讨相关领域的管理热点话题。帮助本领域的从业者大幅削减高昂的培训费用及大量的时间成本,在互联网+的热潮中真正享受低廉和便捷的专业培训,与行业大咖和知名讲师零距离交流,全面接收行业前端资讯,深度探讨客户管理精髓。
客户世界机构从2003年1月开始编辑出版《客户世界》月刊,至今已14年,累计发行超过160期;同时累计组织编撰出版行业图书超过100本,常年为业内超过千家企业提供咨询和培训服务。作为客户中心行业的旗帜媒体和管理智库,在特定领域沉淀了丰富的资源。
客户世界机构同步于2004年创立了国内最大的客户管理人俱乐部“好客会”,以加强行业同仁之间的互动;通过举办年会、行业/主题论坛及读书沙龙、编辑聚餐、心理学及禅修活动、户外健身运动等方式推动会员交流;已举办各类线下会员活动超过两百场,其中包括了中国客户中心行业历史最久、水准最高、规模最大的行业会议——客户世界年度大会,年度行业评选——“金耳唛杯”中国最佳客户中心,好客会读书沙龙,中国客户中心马拉松赛等业界耳熟能详的品牌活动。
近年来,通讯技术和社交媒体的发展促进了交互的便捷、多元和高效;纸媒和咨询等知识积累方式以及会议和培训等知识传播手段亟待突破和创新。消费者连接技术、接触技术和体验技术的不断创新也正深刻改变着以客户中心为代表的客户交互服务领域,大数据、万物互联、认知计算的深入发展大大扩展了本领域的产业边界, 数字化、体验化、共享经济化的时代特征使得整个服务产业的融合发展成为趋势。
基于互动技术的发展以及受众行为偏好的改变,客户世界机构适时推出“好客会” 知识平台及o2o行业社区(www.iCustomer.com.cn)。旨在搭建一个服务业内互助互帮、优质资源整合的平台,让更多从业者健康快速成长、获益、并享受于服务工作之中。“好客会”社区将采用APP、视频直播、微信互动、社区交流等整合式的渠道开展有计划的内容整合传播以及持续的深度互动。透过新渠道的知识平台,传播知识、培养人才、推动行业健康发展。本次推出的“好客之道”客户管理轻学院是“好客会”知识平台的核心内容,将深度梳理客户中心与电子商务行业的资源,采用视频直播、图文直播、内容点播相整合的传播方式,以管理讲堂、主题论坛、访谈对话、特别策划等栏目定期播出的形式与行业受众见面。区隔于传统呼叫中心的封闭式培训,也区别于大型电商服务在平台内部的客服公开课,是针对客户中心和电子商务行业的管理者和一线从业者搭建的与各行业客户管理工作环节相关的深度学习平台,并为客户中心和电子商务从业者提供行业交流社群和活动组织平台。课程的组织将更加社群化和互联网化,以更加轻松的形式呈现。实名制会员将可以通过视频课程、影音课程、笔记分享等较轻的形式,随时随地进行学习和分享。课程内容围绕着帮助管理者明确管理战略、清晰管理战术、完善高效有序地运作团队,以及帮助一线从业者理解工作的意义、提高工作技能、打通职业晋升通道等。
就在“好客会”平台正式上线发布前的一周(11月24日,感恩节),“好客之道”工作室在位于北京朝阳区兴隆公园的“好客咖啡馆”启动了节目录制工作。自2016年12月起,相关内容将陆续每周推出。 收起阅读 »
安卓修改头像样式
集成环信个人感觉还很容易的,当然,坑也很多,环信很多东西都是可以自己定义的,直接进入正题吧,在demo的EaseUi里面utils包下面有个EaseUserUtils类里面有如下代码:
然后只要在setUserAvatar这个方法里面稍作修改
这个GlideCircleTransform类 可以写成内部类,也可在是外部的,建议内部,GlideCircleTransform这种可以自己写,不会的去百度,实在不会的加下面的群,这个方法我把代码给你们贴上:
public static void setUserAvatar(Context context, String username, ImageView imageView){
EaseUser user = getUserInfo(username);
if(user != null && user.getAvatar() != null){
try {
int avatarResId = Integer.parseInt(user.getAvatar()); //Glide.with(context).load(avatarResId).into(imageView); Glide.with(context).load(avatarResId).transform(new GlideCircleTransform(context)).into(imageView);
} catch (Exception e) {
//use default avatar //Glide.with(context).load(user.getAvatar()).diskCacheStrategy(DiskCacheStrategy.ALL).placeholder(R.drawable.ease_default_avatar).into(imageView);
Glide.with(context).load(user.getAvatar()).diskCacheStrategy(DiskCacheStrategy.ALL). placeholder(R.drawable.ease_default_avatar).transform(new GlideCircleTransform(context)).into(imageView);
}
}else{
//Glide.with(context).load(R.drawable.ease_default_avatar).into(imageView); Glide.with(context).load(R.drawable.ease_default_avatar).transform(new GlideCircleTransform(context)).into(imageView);
}
}
自己去根据图片排版去吧,到这里已经完成一半了,前面说了环信的好,该吐槽一下坑了,我改到这里后,只有列表变成想要的样子,会话页面还是不行,后来和帝都的一个妹子交流了下,她给我说要把EaseUi里面关于聊天界面,会话列表,联系人列表,个人资料布局里面的图片资源全部删除就行了,具体几个我忘记了,大概有七个左右,是左右,我忘了,也没几个布局,你们可以一个一个找找,这样就可以修改成自己喜欢的头像样式了
好了,到这里就差不多了,如果实在还是不行,或者是有其他问题的,请加环信互帮互助群 340452063 到群里找我 杭州-andorid-中草 龙虾头像 最后附上二表哥送的四句话
做一番一生引以为豪的事业
找一个一生荣辱与共的妻子
在有生之年报答帮过我的人
并且帮助那些需要帮助的人 收起阅读 »
环信助力爱宠医生为50万宠物主人在线解决疑难杂症
1.遇到的挑战:
爱宠医生技术总监张振亚表示:“由于业务主要为宠物主人的在线问诊平台,对于初创公司来讲,IM这一块由自己来开发不仅时间不允许,技术沉淀也不够,即便开发出来稳定性也很难保证。所以当时在相对于比较成熟的几款IM服务中,通过服务质量,稳定性,开发团队以及和业务需求进行匹配时,最终认为环信最适合我们的业务。”
2.环信解决方案:
因为在业务场景上宠物主人与宠物医生的对话是以问题的形式出现的,解决问题后问题需要关闭。所以单聊的方式不是特别符合爱宠医生的需求,爱宠医生对聊天室与群组进行对比,最后决定使用群组的方式来实现,宠物主人提出问题创建群组将宠物医生加入群组(群组上线2人)进行对话,问题结束后删除群组,抢单模式为将第一位宠物医生移除群组后再有抢单医生抢单成功后在移入群组进行对话。
3.价值体现:
为超过50万的宠物主人在线解决平常遇到的疑难杂症,环信即时通讯云在当中起到了至关重要的管道作用,保证了爱宠医生IM服务7×24的正常稳定运行。
爱宠医生技术总监张振亚表示:整体来讲,对环信的服务很满意。在创业初期就帮助我们解决了技术集成等问题,并且通过不断的版本迭代一直稳定运行到现在。技术支持服务也相对的很及时也很到位,绝大多数的问题可以在第一时间帮助我们解答。版本迭代更新也是很稳定的,也比较开放,可以让我们在使用过程中自定义与业务相关的功能。正是因为环信对于我们业务上的帮助,可以让我们在越来越繁华的宠物行业以及宠物医疗行业占得先机。
关于爱宠医生
宠物生病了怎么办?不用马上去医院,使用爱宠医生APP随时随地向周边的宠物医生和全国知名的宠物专家提问,给宠物问诊治疗,你还可以查到小区附近的宠物医院,查看宠物医院的评论,帮你找到最好、最靠谱的宠物医院和宠物医生。
爱宠医生是上海宠零宠网络科技有限公司旗下互联网宠物医疗平台,公司成立于2015年6月,坐落于上海浦东张江高科技园区,是浦东软件园孵化器孵化企业。公司于2015年和2016年分别获得中金资本和普华资本的两轮融资。公司核心管理团队均为原互联网上市公司核心人员和宠物行业资深人士。 公司旗下产品包括宠物医生免费在线问诊app、宠物医院智能SaaS管理系统以及宠物医院的供应链采销平台。拥有注册宠物主50多万人,业务覆盖北上广等100多个城市,3000多家宠物医院,5000多位宠物医生,已成为当前互联网宠物医疗第一品牌。公司在 北京举办的“2016创新中国春季峰会”,获得优秀企业奖,同时,在2016年香港举办的“亚洲智能手机应用程式大赛”中获得优秀项目奖。 收起阅读 »
【环信3.x Android加表情】加表情三部曲,你值得拥有!!!
首先我实现方式就是仿照官方demo里兔斯基的实现方式,在自带的表情基础上增加一组新表情。所以就很简单了!!!首先就不说如何集成环信demo了,相信有这个需求的人都是已经集成好了的。
- 第一部
首先找到EmojiconExampleGroupData这个类,复制一份照着修改下,我的代码如下:
package com.liancheng.tiantianzhengchong.HuanXin.domain;这里说明下,
import com.hyphenate.easeui.domain.EaseEmojicon;
import com.hyphenate.easeui.domain.EaseEmojicon.Type;
import com.hyphenate.easeui.domain.EaseEmojiconGroupEntity;
import com.liancheng.tiantianzhengchong.R;
import java.util.Arrays;
public class EmojiconSinaGroupData {
private static int[] icons = new int[]{
R.drawable.d_aini,
R.drawable.d_aoteman,
R.drawable.d_baibai,
R.drawable.d_baobao,
R.drawable.d_beishang,
R.drawable.d_bishi,
R.drawable.d_bizui,
R.drawable.d_chanzui,
R.drawable.d_chijing,
R.drawable.d_dahaqi,
R.drawable.d_dalian,
R.drawable.d_ding,
R.drawable.d_doge,
R.drawable.d_erha,
R.drawable.d_feizao,
R.drawable.d_ganmao,
R.drawable.d_guzhang,
R.drawable.d_haha,
R.drawable.d_haixiu,
R.drawable.d_han,
R.drawable.d_hehe,
R.drawable.d_heixian,
R.drawable.d_heng,
R.drawable.d_huaixiao,
R.drawable.d_huaxin,
R.drawable.d_jiyan,
R.drawable.d_keai,
R.drawable.d_kelian,
R.drawable.d_ku,
R.drawable.d_kulou,
R.drawable.d_kun,
R.drawable.d_landelini,
R.drawable.d_lang,
R.drawable.d_lei,
R.drawable.d_miao,
R.drawable.d_nanhaier,
R.drawable.d_nu,
R.drawable.d_numa,
R.drawable.d_nvhaier,
R.drawable.d_qian,
R.drawable.d_qinqin,
R.drawable.d_shayan,
R.drawable.d_shengbing,
R.drawable.d_shenshou,
R.drawable.d_shiwang,
R.drawable.d_shuai,
R.drawable.d_shuijiao,
R.drawable.d_sikao,
R.drawable.d_taikaixin,
R.drawable.d_tanshou,
R.drawable.d_tian,
R.drawable.d_touxiao,
R.drawable.d_tu,
R.drawable.d_tuzi,
R.drawable.d_wabishi,
R.drawable.d_weiqu,
R.drawable.d_wu,
R.drawable.d_xiaoku,
R.drawable.d_xiongmao,
R.drawable.d_xixi,
R.drawable.d_xu,
R.drawable.d_yinxian,
R.drawable.d_yiwen,
R.drawable.d_youhengheng,
R.drawable.d_yun,
R.drawable.d_zhuakuang,
R.drawable.d_zhutou,
R.drawable.d_zuiyou,
R.drawable.d_zuohengheng,
R.drawable.f_geili,
R.drawable.f_hufen,
R.drawable.f_jiong,
R.drawable.f_meng,
R.drawable.f_shenma,
R.drawable.f_v5,
R.drawable.f_xi,
R.drawable.f_zhi,
R.drawable.h_buyao,
R.drawable.h_good,
R.drawable.h_haha,
R.drawable.h_jiayou,
R.drawable.h_lai,
R.drawable.h_ok,
R.drawable.h_quantou,
R.drawable.h_ruo,
R.drawable.h_woshou,
R.drawable.h_ye,
R.drawable.h_zan,
R.drawable.h_zuoyi,
R.drawable.l_shangxin,
R.drawable.l_xin,
R.drawable.lxh_haoaio,
R.drawable.lxh_haoxihuan,
R.drawable.lxh_oye,
R.drawable.lxh_qiuguanzhu,
R.drawable.lxh_toule,
R.drawable.lxh_xiaohaha,
R.drawable.lxh_xiudada,
R.drawable.lxh_zana,
R.drawable.o_dangao,
R.drawable.o_feiji,
R.drawable.o_ganbei,
R.drawable.o_huatong,
R.drawable.o_lazhu,
R.drawable.o_liwu,
R.drawable.o_lvsidai,
R.drawable.o_weibo,
R.drawable.o_weiguan,
R.drawable.o_yinyue,
R.drawable.o_zhaoxiangji,
R.drawable.o_zhong,
R.drawable.w_fuyun,
R.drawable.w_shachenbao,
R.drawable.w_taiyang,
R.drawable.w_weifeng,
R.drawable.w_xianhua,
R.drawable.w_xiayu,
R.drawable.w_yueliang
};
private static String[] icons_name = new String[]{
"[爱你]",
"[奥特曼]",
"[拜拜]",
"[抱抱]",
"[悲伤]",
"[鄙视]",
"[闭嘴]",
"[馋嘴]",
"[吃惊]",
"[打哈气]",
"[打脸]",
"[顶]",
"[doge]",
"[二哈]",
"[肥皂]",
"[感冒]",
"[鼓掌]",
"[哈哈]",
"[害羞]",
"[汗]",
"[呵呵]",
"[黑线]",
"[哼]",
"[坏笑]",
"[花心]",
"[挤眼]",
"[可爱]",
"[可怜]",
"[酷]",
"[骷髅]",
"[困]",
"[懒得理你]",
"[浪]",
"[泪]",
"[喵喵]",
"[男孩儿]",
"[怒]",
"[怒骂]",
"[女孩儿]",
"[钱]",
"[亲亲]",
"[傻眼]",
"[生病]",
"[草泥马]",
"[失望]",
"[衰]",
"[睡觉]",
"[思考]",
"[太开心]",
"[摊手]",
"[舔屏]",
"[偷笑]",
"[吐]",
"[兔子]",
"[挖鼻屎]",
"[委屈]",
"[污]",
"[笑cry]",
"[熊猫]",
"[嘻嘻]",
"[嘘]",
"[阴险]",
"[疑问]",
"[右哼哼]",
"[晕]",
"[抓狂]",
"[猪头]",
"[最右]",
"[左哼哼]",
"[给力]",
"[互粉]",
"[囧]",
"[萌]",
"[神马]",
"[威武]",
"[喜]",
"[织毛线]",
"[NO]",
"[good]",
"[haha]",
"[加油]",
"[来]",
"[ok]",
"[拳头]",
"[弱]",
"[握手]",
"[耶]",
"[赞]",
"[作揖]",
"[伤心]",
"[心]",
"[好爱哦]",
"[好喜欢]",
"[噢耶]",
"[求关注]",
"[偷乐]",
"[笑哈哈]",
"[羞嗒嗒]",
"[赞啊]",
"[蛋糕]",
"[飞机]",
"[干杯]",
"[话筒]",
"[蜡烛]",
"[礼物]",
"[绿丝带]",
"[围脖]",
"[围观]",
"[音乐]",
"[照相机]",
"[钟]",
"[浮云]",
"[沙尘暴]",
"[太阳]",
"[微风]",
"[鲜花]",
"[下雨]",
"[月亮]"
};
private static final EaseEmojiconGroupEntity DATA = createData();
private static EaseEmojiconGroupEntity createData() {
EaseEmojiconGroupEntity emojiconGroupEntity = new EaseEmojiconGroupEntity();
EaseEmojicon[] datas = new EaseEmojicon[icons.length];
for (int i = 0; i < icons.length; i++) {
datas[i] = new EaseEmojicon(icons[i], icons_name[i], Type.BIG_EXPRESSION);
datas[i].setBigIcon(icons[i]);
//you can replace this to any you want
datas[i].setName(icons_name[i]);
datas[i].setIdentityCode("sina" + (1000 + i + 1));
}
emojiconGroupEntity.setEmojiconList(Arrays.asList(datas));
emojiconGroupEntity.setIcon(R.drawable.ee_3);
emojiconGroupEntity.setType(Type.BIG_EXPRESSION);//设置类型,如果是nomal就可以输入输入框
return emojiconGroupEntity;
}
public static EaseEmojiconGroupEntity getData() {
return DATA;
}
}
datas[i] = new EaseEmojicon(icons[i], icons_name[i], Type.BIG_EXPRESSION);
emojiconGroupEntity.setType(Type.BIG_EXPRESSION);
主要是这里要设置下type类型,这里以BIG_EXPRESSION形式,如何设置成nomal的话,发出来的是纯文字的,不能显示表情的,需要用的话,得修改easeui里的东西,不推荐。一般需要加新表情都是已大图形式的,如果需要纯文字,可以加在默认的(第一组)表情里!
2.第二部
找到ChatFragment,找到((EaseEmojiconMenu)inputMenu.getEmojiconMenu()).addEmojiconGroup(EmojiconExampleGroupData.getData());
复制一份,修改成
((EaseEmojiconMenu) inputMenu.getEmojiconMenu()).addEmojiconGroup(EmojiconSinaGroupData.getData());
加在这句后面。
3.第三部
找到DemoHelper,找到easeUI.setEmojiconInfoProvider,写成如下:
//set emoji icon provider最后写完了,希望能帮到和我这样的小白!!!
easeUI.setEmojiconInfoProvider(new EaseEmojiconInfoProvider() {
@Override
public EaseEmojicon getEmojiconInfo(String emojiconIdentityCode) {
//第一种表情
EaseEmojiconGroupEntity data = EmojiconExampleGroupData.getData();
for (EaseEmojicon emojicon : data.getEmojiconList()) {
if (emojicon.getIdentityCode().equals(emojiconIdentityCode)) {
return emojicon;
}
}
//新增的第二种表情
EaseEmojiconGroupEntity data_sina = EmojiconSinaGroupData.getData();
for (EaseEmojicon emojicon : data_sina.getEmojiconList()) {
if (emojicon.getIdentityCode().equals(emojiconIdentityCode)) {
return emojicon;
}
}
return null;
}
@Override
public Map<String, Object> getTextEmojiconMapping() {
return null;
}
});
收起阅读 »
移动APP测试中的最佳做法!
功能测试
每项开发的新功能都需要进行测试。移动app测试中功能测试是一个重要方面,移动测试员应该要进行手动测试和自动化测试。刚开始测试时,测试员必须把移动app当做"黑盒"一样进行手动测试,看看提供的功能是否正确并如设计的一样正常运作。除了经典软件测试,像点击按钮看看会发生什么,测试员还必须执行更多功能的移动设备专门的测试。
如今,现代移动设备都有触摸屏,要求多点触控动作来与它们互动。设备可以是纵向或横向显示屏。它们提供动作,倾斜和螺旋传感器。它们有不同的接口可以连接其他设备或服务,比如GPS,NFC,照相机,LED等等。
移动软件测试员必须确保app的所有特定设备功能在app里都能用。移动设备的种类这么多,测试时要将所有的覆盖是不可能的,所以功能测试时测试员要专注于他们app的关键之处。什么是真的简单有效的呢?设备旋转。我测试工作期间发现有许多bug仅需将设备从纵向旋转为横向再旋转回来就好了。
除了整个手动测试过程,测试自动化对移动app也很重要。每个代码变化或新功能都可能影响现存功能及它们的状态。通常手动回归测试时间不够,所以测试员不得不找一个工具去进行自动化回归测试。现在市面上有很多移动测试自动化工具,根据我的经验,真机测试效果是最好的,我自己常用的TestBird测试工具,用来进行APP的功能测试,当然,根据开发策略和结构,质量保证专家需要找出最适合他们环境的自动化工具。
选择一个工具对测试自动化并不容易,但做决定时有一点要牢记,因为很重要:测试自动化应该使用同样的编程语言作为产品代码。如果测试和产品代码用一样的语言去写,那对测试员和开发员都有好处,因为这就使得他们做配对代码时可以轻松些。测试员可以和开发员在同一水平进行交流,他们可以执行测试和产品代码的代码审查。对于测试自动化,开发员可以用他们习惯的语言编写他们自己的脚本。
总结:
· 把app作为"黑盒"进行测试并试着中断它。
· 打开移动app的每个屏幕并将设备从纵屏变为横屏再变回纵屏。
· 别忘了去测试设备特定的功能,比如传感器和通信接口。
· 为移动app编写测试自动化脚本。
· 选择一个适应公司策略和结构的测试自动化工具。
· 测试和产品代码应该用同一种语言。
非功能测试
移动app测试的另一重要方面是移动app的非功能需求。移动app在推出市场或进行进一步开发前,移动测试员有许多需要测试的问题。
早期开发阶段要进行的第一个测试应该是实用性测试。通常是由alpha用户或同事进行的。走进一家咖啡馆或餐厅,问问里面的人他们的app使用情况。让他们看看现阶段开发的第一个版本并收集反馈,看看用户是否能很好地使用新功能,以便得出第一印象。
检查app的性能。将推出的版本与当前版本做一番比较,看看性能是一样?更好?还是更差?将app安装到旧的设备上,看看该app在旧设备上是否仍能运作,无论硬件设备好或差。最先进的设备也一样要这么做。
测试电话,短信,彩信,微博或其他通知进来时app的反应。使用app时检查一下电量。确保测试过程测试设备是充满电的并每十分钟检查一下电池使用情况,看看该app有没有太耗电。在低电量时把app安装到设备上看看会发生什么。检查app的内存使用情况。如果app在本地文件系统中存储数据,测测不同内存卡的使用情况。想想看本地存储快满时会发生什么呢--app会崩溃或弹出出错提醒框来通知用户吗?
测试app的安装和删除过程。更重要的是,测试从老版本升级为新版本的过程。或许本地数据库已经改变了,这样就会引起一些严重的迁移问题。
App被本地化了吗?测试员需要用不同的语言测试app。记得在不同的网络载体上以不同的网速进行测试。确定该app在GPRS,EDGE,UMTS,LTE和WiFi环境下都能运作。
别忘了检查网络连接不好或完全掉了时app会怎么反应。飞行模式下使用该app看看如果一个请求失败了会发生什么。将测试设备连接到电脑上并检查开发日志文件有没有例外、警告或其他奇怪的异常之处。这些只是移动测试员和开发员开发和测试一个app时应该考虑的非功能需求中的一部分。每方面都检查到位是绝不可能的,因此整体团队应该支持QA成员尽量覆盖更多方面以防用户得到不好的体验。或者使用众测平台,我习惯性的用TestBird ,当然腾讯阿里也有类似的产品。
总结:
· 做实用性测试。
· 比较app已推出版本和新版本的性能。
· 检查电话,短信,彩信或微博或进来时app的反应。
· 检查测试设备的电量。
· 测试app的内存使用情况。
· 安装并删除app。
· 测试从旧版本升级到新版本的过程。
· 检查语言的转换。
· 在不同的载体和网络连接,如GPRS,WiFi,orLTE,环境中使用app。
· 检查日志文件的错误或例外。 收起阅读 »
李理:从Image Caption Generation理解深度学习(part II)
2. 机器学习基本概念和前馈神经网络
2.1 机器学习基本概念
大家可能平时都写过很多程序,写程序和机器学习的思路可能有一些不同。写程序时,我们是“上帝”,我们规定计算机的每一个步骤,第一步做什么第二步做什么,我们称之为算法。我们能够控制所有的情况,如果出了任何问题,肯定都是程序员的责任。而在机器学习的时候,我们只是“老师”。我们告诉学生(计算机)输入是什么,输出是什么,然后期望它能够学到和我们类似的知识。比如我们跟小孩说这是狗,那是猫,我们没有办法像上帝那样拿着“纳米手术刀”去操作人脑神 经元的连接方式。我们只能不断的给小孩“训练数据”,然后期望他能够学会什么是猫,即使我们觉得他“学会”了识别猫,我们也没有办法知道他是“怎么”学会 的,而且同样的训练过程可能换一个人就不好使。
机器学习和人类的学习是类似的——我们也是给它训练数据,然后期望它能学会。我们会给机器建一个模型,从数学的角度来说一个模型就是一个函数,它的输入一般是一个向量【当然可以是二维的矩阵如图片或者三维的张量比如视频】,输出可以是有限的离散的标签如“猫”,“狗”,这类问题我们称之为分类;而如果输出 是连续的值比如用这个模型来预测气温,那么我们就称之为回归。其实人类的很多科学活动和日常生活,都是在“学习”模型和“应用”模型。比如开普勒通过观测 大量天文数据“归纳”出行星的运动规律。从本质上讲,智能就是从“过去”学习,然后根据“现在”来预测可能的将来并根据自己的目标选择有利于自己行为。只不过之前,似乎只有人类能够从数据中“学习”出规律,而人工智能的目标就是让机器也有类似的学习能力。
模型用数学来说就是一个函数,我们人脑的函数由神经元的连接构成,它可能是一个很复杂的函数,我们现在还很难彻底研究清楚。神经网络就是试图通过计算机来 模拟和借鉴人脑这个模型,除了我们这里要讲的神经网络之外,机器学习领域还有各种各样的模型,它们各有特点。但不管形式怎么变化,本质都是一个函数。一个(或者更准确的是一种)模型一般都是一种函数形式,它有一些“参数”可以改变。而学习的过程就是不断调整这些参数,使得输出(尽量)接近“正确”的答案。 但是一般情况下很难所有的数据我们都能预测正确,所以一般我们会定义一个loss function,可以理解为“错误”的程度,错的越“离谱”,loss就越大。而我们的目标就是调整参数使得loss最小。
但是我们是在“训练”数据上调整的参数,那么它能在“测试”数据上也表现的好吗?这个就是模型的“泛化”能力了。就和人在学校学习一样,有的同学做过的一 模一样的题就会,但是考试时稍微改变一下就不会了,这就是“泛化”能力太差,学到的不是最本质的东西。所以平时会定期有一些“模拟考试”,来检验学生是不 是真的学会了,如果考得不好,那就打回去重新训练模型调整参数。这在机器学习里对应的就是validation的阶段。最后到最终的考试了,就是最终检验 的时候了,这个试卷里的题目是不能提前让人看到的,只能拿出来用一次,否则就是作弊了。对应到机器学习里就是test阶段。
当然这里用通俗的话描述了机器学习,主要是有监督的学习。其实机器学习还有无监督的学习和强化学习。前者就是不给答案,只给数据,让人总结规律;而后者会有答案,但是答案不是现在就告诉你。我个人觉得人类社会里更多的是监督学习和强化学习。从人类社会总体来说,强化学习是获取新知识的唯一途径,也就是向自 然学习,我们做了一个决策,其好坏可能要很长一段时间才能显现出来。而学习出来的这些知识通过监督的方式,通过家庭和学校的教育教给下一代。
另外输出除了简单的分为离散和连续,还可以是序列(时序)的,比如自然语言(文本)是一个字符串的序列 ,对于我们的Image Caption Generation就是生成一个单词序列。另外还有更复杂的输出,比如parsing,输出是一棵语法树。
2.2 多层神经网络
前面介绍了机器学习的基本概念,接下来我们就来学习一下神经网络。现在流行的说法“深度学习”,其实大多指的就是“深度神经网络”,那么首先我们先了解一下“浅度神经网络”,也就是传统的神经网络。这里的内容主要来自http://neuralnetworksanddeeplearning.com的前两章。
2.2.1 手写数字识别问题
我们在学习一门新的语言时会写一个hello world程序,而mnist数据的手写数字识别就是一个很好的学习机器学习(包括深度学习)的一个hello world任务。
计算机和人类大脑似乎有很大的不同,很多人类认为复杂的工作计算机可能认为很简单,而人类认为很简单的事情计算机可能非常难处理。比如数字的计算,记忆,人类的准确度和速度都远远不如计算机。但是识别0-9的手写数字,我们觉得很轻而易举的事情,让计算机程序来处理却异常困难。经过数百万年进化的人类视觉系统在我们大脑没有意识到的时候就已经帮我们完成了数字的识别,把那些复杂的视觉处理过程深深的掩藏了起来。但当我们想自己写一个程序来识别数字的时候,这些困难才能体现出来。首先,对于计算机来说,它“看到”的不是数字,甚至不是笔画。它“看到”的只是一个二位的矩阵(数组),每个点都是一个数字。比如下图,我们“看到”的是左边的“猫”,其实计算机“看到”的是右边的像素灰度值。当然我们视觉系统的视网膜看到的也是类似的一些“数值”,只不过我们的视觉系统已经处理了这些信息并且把它识别成了“猫”(甚至和语言还做了映射)。
MNIST数据介绍:MNIST的每个图片经过缩放和居中等预处理之后,大小是28*28,每个点都是0-255的灰度值,下图是一些样例。总共有60,000个训练数据(0-9共10个类别,每个类别6,000个)和10,000个测试数据。一般会拿60000个中的50000个来做训练集,而剩下的10000个用来做验证集(用来选择一些超参数)。
如果我们自己来写一个“算法”识别数字“9”,我们可能会这么定义:9在上面有个圆圈,在这个圆圈的右下部分有一个竖直的笔画。说起来很简单,如果用算法 来实现就很麻烦了:什么是圆圈?每个人画的圆圈都不同,同样竖直的笔画怎么识别,圆圈和竖直笔画连接处怎么寻找,右下是哪?大家如果有兴趣可以尝试一下用 上面的方法,其实最早做数字识别就是这样的思路。
机器学习的思路则不同,它不需要这么细节的“指示”计算机应该怎么做。而是给计算机足够的“训练”样本,让它“看”不同的10个数字,然后让它“学”出 来。前面我们也讲了,现在的机器学习一般是一个参数化的模型。比如最简单的一个线性模型:f(w;x)=w0+ w1*x1+w2*x2。如果我们的输入有两个“特征”x1和x2,那么这个模型有3个参数w0,w1和w2,机器学习的过程就是选择“最优”的参数。对 于上面的mnist数据,输入就是28*28=784维的向量。
如果用“原始”的输入作为“特征”,线性的模型很可能学到一些简单的特征,比如它看到1一般是分布在从上到下居中的一些位置,那么对于这些位置一旦发现有比较大的灰度值,那么就倾向于判断成1。如果一个像素点2也经常出现,但3不出现,那么它就能学到如果这个像素出现,那么这个数字是2和3的可能性就大一些。
但是这样的“特征”可能不是“本质”的,因为我写字的时候笔稍微平移一点,那么你之前“学到”的参数就可能有问题。而更“本质”的特征是什么呢?可能还是像之前我们总结的——9在上面有个圆圈,在这个圆圈的右下部分有一个竖直的笔画。我们把识别一个数字的问题转化成圆圈和竖直笔画的问题。传统的机器学习需要方法来提取“类似”(但不完全是)基本笔画这样的“特征”,这些特征相对于像素的特征会更加“本质”。但是要“提取”这些特征需要很多的“领域”知识,比如图像处理的技术。所以使用传统的机器学习方法来解决问题,我们不但需要很多机器学习的知识,而且也需要很多“领域”的知识,同时拥有这两方面的知识是比较难的。
而“深度学习”最近之所以火热,其中很重要的一个原因就是对于很多问题,我们只需要输入最原始的信号,比如图片的像素值,通过“多层”的网络,让底层的网络学习出“底层”的特征,比如基本的形状,而中间的层学习出抽象一点的特征,比如眼睛鼻子耳朵。而更上的层次识别出这是一个猫还是一个狗。所有这些都是机器学习出来的,所以基本不需要领域的知识。
上面的图就说明了这一点,而且我们发现越是底层的特征就越“通用”,不管是猫鼻子还是狗眼睛,可能用到的都是一些基本的形状,因此我们可以把这些知识(特征)transfer到别的任务,也就是transfer learning,后面我们讲到CNN的时候还会提及。
2.2.2 单个神经元和多层神经网络(MLP)
神经网络从名字来看是和人类的大脑有些关系的,而且即使到现在,很多有用的东西如CNN和Attention,都有很多借鉴神经科学研究人脑的结果的。不过这里我就不介绍这些东西了,有兴趣的读者可以找一些资料来了解。
一个神经元如下图的结构:
它的输入是一个向量,(x1,x2,x3),输出是一个标量,一个实数。z=w0+ w1*x1 + w2*x2 + w3*x3。z是输入的加权累加,权值是w1,w2,w3,w0是bias,输出 output = f(z)。函数f一般叫做激活函数。最早流行的激活函数是Sigmoid函数,当然现在更流行Relu和它的改进版本。Sigmoid函数的公式和图形如下:
当z=0时,sigmoid(z)=0.5 z趋于无穷大时,sigmoid(z)趋近于1,z趋于负无穷,值趋于0。为什么选择这样的激活函数呢?因为是模拟人脑的神经元。人脑的神经元也是把输入的信号做加权累加,然后看累加和是否超过一个“阈值”。如果超过,继续向下一个神经元发送信号,否则就不发送。因此人脑的神经元更像是一个阶跃函数:
最早的感知机(Perception)其实用的就是这个激活函数。但是它有一个缺点就是0之外的所有点的导数都是0,在0点的导数是无穷大,所以很难用梯度的方法优化。而Sigmoid函数是处处可导。下面我手工推导了一下,如果大家不熟悉可以试着推导一下Sigmoid函数的导数,我们后面也会用到。
我们把许多的单个神经元按照层次组织起来就是多层的神经网络。
比如我们的手写数字识别,输入层是784维,就是神经网络的地一层,然后中间有15个hidden(因为我们不知道它的值)神经元,然后输出层是10个神经元。中间隐层的每个神经元的输入都是784个原始像素通过上面的公式加权累加然后用sigmoid激活。而输出层的每一个神经元也是中间15个神经元的累加然后激活。上面的图就是一个3层的神经网络。
输入一个28*28的图像,我们得到一个10维的输出,那么怎么分类呢?最直接的想法就是把认为最大的那个输出,比如输出是(10,11,12,13,14,15,16,17,18,19),那么我们认为输出是9。
当然,更常见的做法是最后一次经过线性累加之后并不用Sigmoid函数激活,而是加一个softmax的函数,让10个输出加起来等于1,这样更像一个 概率。而我们上面的情况,虽然训练数据的输出加起来是1,但是实际给一个其它输入,输出加起来很可能不是1。不过为了与Nielsen的文章一致,我们还 是先用这种方法。
因此,假设我们有了这些参数【总共是784*15 + 15(w0或者叫bias) + 15*10 + 10】,我们很容易通过上面的公式一个一个的计算出10维的输出。然后选择最大的那个作为我们识别的结果。问题的难点就在怎么 选择这么多参数,然后使得我们分类的错误最少。
而我们怎么训练呢?对于一张图片,假设它是数字“1”,那么我们期望它的输出是(0,1,0,0,0,0,0,0,0,0),所以我们可以简单的用最小平方错误作为损失函数。不过你可能会有些疑问,我们关注的指标应该是分类的“正确率”(或者错误率),那么我们为什么不直接把分类的错误率作为损失函数呢?这样神经网络学习出来的参数就是最小化错误率。
主要的原因就是错误率不是参数的连续函数。因为一个训练数据如果分类正确那么就是1,否则就是0,这样就不是一个连续的函数。比如最简单的两类线性分类器,f(x)=w0+w1*x1+w2*x2。如果f(x)>0我们分类成类别1;否则我们分类成类别2。如果当前的w0+w1*x1+w2*x2<0,我们很小的调整w0(或者w1,w2),w0+w1*x1+w2*x2仍然小于0,【事实上对于这个例子,只要是w0变小,他们的累加都是小于0的】所以f(x)的值不会变化,而w0一直增大到使累加和等于0之前都不会变化,只有大于0时突然变成1了,然后一直就是1。因此之前的错误率都是1,然后就突然是0。所以它不是个连续的函数。
因为我们使用的优化算法一般是(随机)梯度下降的算法,在每次迭代的时候都是试图做一个微小的参数调整使得损失变小,但是不连续的函数显然也不可导,也就没法用这个算法来优化参数。
因此我们使用了最小平方误差(MSE)损失函数。
y(x)就是神经网络的输出,可能写成f(x)大家会习惯一点。a是目标的输出,比如当前分类是数字1,那么我们期望的输出就是(0,1,0,0,0,0,0,0,0,0)。
首先这个损失函数是参数w的连续函数,因为y(x)就是神经网络的输出,每个神经元都是它的输入的线性加权累加,然后使用sigmoid激活函数【如果使用最早的阶跃函数就不连续了,所以后来使用了Sigmoid函数】,然后每一层的神经元都是用上一层的神经元通过这样的方式计算的(只不过每个神经元的参数也就是权重是不同的数值而已),所以这些连续函数的复合函数也是连续的。
其次这个损失函数和我们的最终优化目标是“大致”一致的。比如C(w,b)趋于0时,它就要求y(x)趋于a,那么我们的分类也就趋于正确。当然可能存在一种极端的情况,比如有3个训练数据,第一组参数,它分类正确了2个训练数据,但是错的那1个错的很“离谱”,也就是y(x)和a差距极大;而第二组参数,他正确分类了1个训练数据,但是错的那两个都还不算太差。那么这种情况下MSE和正确率并不一致。
2.2.3 随机梯度下降(Stochastic Gradient Descent)和自动求梯度(Automatic Derivatives)
上面说了,我们有了一个参数化的模型,训练的过程就是根据训练数据和loss function,选择“最优”的参数,使得loss“最小”,这从数学上来讲就是一个优化问题。这看起来似乎不是什么值得一提的问题,也许你还记得微积 分里的知识,极值点的各种充分必要条件,比如必要条件是导数是0,然后直接把参数解出来。但在现实生活中的函数远比教科书里学到的复杂,很多模型都无法用 解析的方式求出最优解。所以现实的方法就是求“数值”解,一般最常见的方法就是迭代的方法,根据现在的参数,我们很小幅度的调整参数,使得loss变小一 点点。然后一步一步的最终能够达到一个最优解(一般是局部最优解)。那怎么小幅调整呢?像闷头苍蝇那样随机乱试显然效率极低。因此我们要朝着一个能使函数 值变小的方向前进。而在一个点能使函数值变小的方向有无穷多个,但有一个方向是下降速度最快的,那就是梯度。因此更常见的方法就是在当前点求函数的梯度, 然后朝着梯度的方向下降。朝梯度的方向走多远呢?一般走一个比较小的值是比较安全的,这个值就是“步长”。一般刚开始随机的初始化参数,loss比较大, 所以多走一些也没关系,但是到了后面,就不能走太快,否则很容易错过最优的点。
因为loss是所有训练数据的函数,所以求loss的梯度需要计算所有的训练数据,对于很多task来说,训练数据可能上百万,计算一次代价太大,所以一 般会“随机”的采样少部分数据,比如128个数据,求它的梯度。虽然128个点的梯度和一百万个的是不一样的,但是从概率来讲至少是一致的方向而不会是相 反的方向,所以也能使loss变小。当然这个128是可以调整的,它一般被叫做batch size,最极端的就是batch是1和一百万,那么分别就是online learning和退化到梯度下降。batch size越大,计算一次梯度的时间就越久【当然由于GPU和各种类似SSE的指令,一次计算128个可能并不比计算1个慢多少】,随机梯度和真正梯度一致 的概率就越大,走的方向就更“正确”;batch size越小,计算一次的时间就越短,但可能方向偏离最优的方向就更远,会在不是“冤枉路”。但实际的情况也很难说哪个值是最优的,一般的经验取值都是几 十到一两百的范围,另外因为计算机都是字节对齐,32,64,128这样的值也许能稍微加快矩阵运算的速度。但是实际也很多人选择10,50,100这样 的值。
除了常见的随机梯度下降,还有不少改进的方法,如Momentum,Adagrad等等,有兴趣的可以看看 http://cs231n.github.io/neural-networks-3/#update ,里面还有个动画,比较了不同方法的收敛速度的比较。
通过上面的分析,我们把问题变成了怎么求loss对参数W的梯度。
求梯度有如下4种方法:
1.手工求解析解
比如 f(x)=x^2, df/dx=2*x。然后我们要求f(x)在x=1.5的值,代进去就2*1.5=3
2.数值解
使用极限的定义:
3.机器符号计算
让机器做符号运算,实现1的方法,但是机器如果优化的不好的话可能会有一些不必要的运算。
比如 x^2 + 2*x*y + y^2,直接对x求导数变成了 2*x + 2*y,两次乘法一次加分,但是我们可以合并一下变成2*(x+y),一次乘法一次加分。
4.自动梯度
下面我会在稍微细讲一下,所以这里暂时跳过。
这些方法的优缺点:
- 手工求解“数学”要求高,有可能水平不够求不对,但效率应该是能最优的。
- 没任何函数,甚至没有解析导数的情况下都能使用,缺点是计算量太大,而且只是近似解【因为极限的定义】,在某些特别不“连续”的地方可能误差较大。所以实际使用是很少,只是用它来验证其它方法是否正确。
- 机器符号计算,前面说的,依赖于这个库的好坏。
实际的框架,如TensorFlow就是自动梯度,而Theano就是符号梯度。
2.2.4 编程实战
通过上面的介绍,我们其实就可以实现一个经典的前馈(feed forward)神经网络了,这种网络结构很简单,每一层的输入是前一层的输出。输入层没有输入,它就是原始的信号输入。而且上一层的所有神经元都会连接到下一层的所有神经元,就像我们刚才的例子,输入是784,中间层是15,那么就有785*15个连接【再加上每个中间节点有一个bias】。所以这种网络有时候也加做全连接的网络(full connected),用来和CNN这种不是全连接的网络有所区别,另外就是信号是从前往后传递,没有反馈,所以也叫前溃神经网络,这是为了和RNN这种有反馈的区别。
当然,我们还没有讲怎么计算梯度,也就是损失函数相对于每一个参数的偏导数。在下一部分我们会详细讨论介绍,这里我们先把它当成一个黑盒的函数就好了。
1.代码
我们这里学习一下Nielsen提供的代码。代码非常简洁,只有不到100行代码。
https://github.com/mnielsen/neural-networks-and-deep-learning
git clone https://github.com/mnielsen/neural-networks-and-deep-learning.git
2.运行
创建一个 test_network1.py,输入如下代码:
import mnist_loader保存后直接运行 Python test_network1.py。这里我们让他进行了30次迭代,最终在测试数据上的准确率大概在95%左右(当然因为随机初始化参数不同,最终的结果可能有所不同)
import network
training_data, validation_data, test_data = mnist_loader.load_data_wrapper()
net = network.Network([784, 30, 10])
net.SGD(training_data, 30, 10, 3.0, test_data=test_data)
Epoch 0: 8250 / 100003. 代码阅读
Epoch 1: 8371 / 10000
Epoch 2: 9300 / 10000
......
Epoch 28: 9552 / 10000
Epoch 29: 9555 / 10000
Python代码很容易阅读,即使之前没有用过,稍微学习两天也就可以上手,而且大部分机器学习相关的代码不会用到太复杂的语言特性,基本就是一些数学的线性代数的运算。而Python的numpy这个库是用的最多的,后面阅读代码的时候我会把用到的函数做一些介绍,继续下面的阅读之前建议花十分钟阅读一下 http://cs231n.github.io/python-numpy-tutorial/。
3.1 mnist_loader.load_data_wrapper函数
这个函数用来读取mnist数据,数据是放在data/mnist.pkl.gz。首先这是个gzip的压缩文件,是Pickle工具序列化到磁盘的格式。不熟悉也没有关系,反正我们知道这个函数的返回值就行了。
这个函数返回三个对象,分别代表training_data,validation_data和test_data。
training_data是一个50,000的list,然后其中的每一个元素是一个tuple。tuple的第一个元素是一个784维的numpy一维数组。第二个元素是10维的数组,也就是one-hot的表示方法——如果正确的答案是数字0,那么这个10维数组就是(1, 0, 0, …)。
而validation_data是一个10,000的list,每个元素也是一个tuple。tuple的第一个元素也是784维的numpy一维数组。第二个元素是一个0-9的数字,代表正确答案是那个数字。
test_data的格式和validation_data一样。
为什么training_data要是这样的格式呢?因为这样的格式计算loss更方便一些。
3.2 Network类的构造函数
我们在调用net = network.Network([784, 30, 10])时就到了init函数。为了减少篇幅,代码里的注释我都去掉了,重要的地方我会根据自己的理解说明,但是有空还是值得阅读代码里的注释。
class Network(object):比如上面的参数,我们保存下来的self.num_layers=3,也就是3层的网络。每一层的神经元的个数保存到self.sizes里。接下来就是构造biases数组并随机初始化。因为输入层是没有参数的,所以是for y in sizes[1:],我们使用了numpy的random.randn生成正态分布的随机数用来作为参数的初始值。注意这里生成了2维的随机变量。回忆一下,如果我们有30个hidden unit,那么bias的个数也是30,那就生成一个30维的1维数组就行了,为什么要是30*1的二维数组呢?其实用1维也可以,不过为了和weights一致,后面代码方便,就用二维数组了。另外weights也是一样的初始化方法,不过注意randn(y,x)而不是randn(x,y)。比如对于我们输入的[784,30,10],weights分别是30*784和10*30的。当然其实weights矩阵转置一下也可以,就是计算矩阵乘法的时候也需要有一个转置。不同的文献可能有不同的记法,但是我们在实现代码的时候只需要随时注意矩阵的大小,检查矩阵乘法满足乘法的约束就行了,矩阵AB能相乘,必须满足的条件是B的列数等于A的函数就行。
def __init__(self, sizes):self.num_layers = len(sizes)
self.sizes = sizes
self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
self.weights = [np.random.randn(y, x)
for x, y in zip(sizes[:-1], sizes[1:])]
对于Nielsen的记法,矩阵的每一行就是一个神经元的784个参数,那么weights(30*784) * input(784*1)就得到30个hidden unit的加权累加。
3.3 feedforward函数
给点输入a(784维),计算最终神经网络的输出(10维)。
def feedforward(self, a):代码非常简单,这里用到了np.dot,也就是矩阵向量的乘法,此外这里有一个Sigmoid函数,这个函数的输入是numpy的ndarray,输出也是同样大小的数组,不过对于每个元素都进行了sigmoid的计算。用numpy的术语就是universal function,很多文献里一般都叫elementwise的function。我觉得后面这个名字更直接。
"""Return the output of the network if ``a`` is input."""for b, w in zip(self.biases, self.weights):
a = sigmoid(np.dot(w, a)+b)
return a
#### Miscellaneous functionsdef sigmoid(z):上面就是Sigmoid函数,另外也把sigmoid_prime,也就是Sigmoid的导数放在了一起【不记得的话看前面Sigmoid的导数的推导】。
"""The sigmoid function."""return 1.0/(1.0+np.exp(-z))
def sigmoid_prime(z):
"""Derivative of the sigmoid function."""return sigmoid(z)*(1-sigmoid(z))
3.4 SGD函数
这个函数是训练的入口,比如我们之前的训练代码:
net.SGD(training_data, 30, 10, 3.0, test_data=test_data)第一个参数就是training_data。
def SGD(self, training_data, epochs, mini_batch_size, eta,
test_data=None):
if test_data: n_test = len(test_data)
n = len(training_data)
for j in xrange(epochs):
random.shuffle(training_data)
mini_batches = [
training_data[k:k+mini_batch_size]
for k in xrange(0, n, mini_batch_size)]
for mini_batch in mini_batches:
self.update_mini_batch(mini_batch, eta)
if test_data:
print "Epoch {0}: {1} / {2}".format(
j, self.evaluate(test_data), n_test)
else:
print "Epoch {0} complete".format(j)
第二个参数就是epochs,也就是总共对训练数据迭代多少次,我们这里是30次迭代。
第三个参数是batch大小,我们这里是10,最后一个参数是eta,也就是步长,这里是3.0。除了网络结构(比如总共多少个hidden layer,每个hidder layer多少个hidden unit),另外一个非常重要的参数就是步长。前面我们也讨论过了,步长太小,收敛速度过慢,步长太大,可能不收敛。实际的情况是没有一个万能的准则,更多的是根据数据,不停的尝试合适的步长。如果发现收敛太慢,就适当调大,反之则调小。所以要训练好一个神经网络,还是有很多tricky的技巧,包括参数怎么初始化,激活函数怎么选择,比SGD更好的优化算法等等。
第四个参数test_data是可选的,如果有(我们的例子是穿了进来的),则每次epoch之后都测试一下。
代码的大致解释我用注释的形式嵌在代码里了:
for j in xrange(epochs): ## 一共进行 epochs=30 轮迭代下面是evaluate函数:
random.shuffle(training_data) ## 训练数据随机打散
mini_batches = [
training_data[k:k+mini_batch_size]
for k in xrange(0, n, mini_batch_size)] ## 把50,000个训练数据分成5,000个batch,每个batch包含10个训练数据。
for mini_batch in mini_batches: ## 对于每个batch
self.update_mini_batch(mini_batch, eta) ## 使用梯度下降更新参数
if test_data: ## 如果提供了测试数据
print "Epoch {0}: {1} / {2}".format(
j, self.evaluate(test_data), n_test) ## 评价在测试数据上的准确率
else:
print "Epoch {0} complete".format(j)
def evaluate(self, test_data):对于test_data里的每一组(x,y),y是0-9之间的正确答案。而self.feedforward(x)返回的是10维的数组,我们选择得分最高的那个值作为模型的预测结果np.argmax就是返回最大值的下标。比如x=[0.3, 0.6, 0.1, 0, ….],那么argmax(x) = 1。
test_results = [(np.argmax(self.feedforward(x)), y)
for (x, y) in test_data]
return sum(int(x == y) for (x, y) in test_results)
因此test_results这个列表的每一个元素是一个tuple,tuple的第一个是模型预测的数字,而第二个是正确答案。
所以最后一行返回的是模型预测正确的个数。
3.5 update_mini_batch函数
def update_mini_batch(self, mini_batch, eta):它的输入参数是mini_batch【size=10的tuple(x,y)】和eta【3.0】。
nabla_b = [np.zeros(b.shape) for b in self.biases]
nabla_w = [np.zeros(w.shape) for w in self.weights]
for x, y in mini_batch:
delta_nabla_b, delta_nabla_w = self.backprop(x, y)
nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
self.weights = [w-(eta/len(mini_batch))*nw
for w, nw in zip(self.weights, nabla_w)]
self.biases = [b-(eta/len(mini_batch))*nb
for b, nb in zip(self.biases, nabla_b)]
def update_mini_batch(self, mini_batch, eta):3.6 backprop函数
nabla_b = [np.zeros(b.shape) for b in self.biases]
## 回忆一下__init__,biases是一个列表,包含两个矩阵,分别是30*1和10*1
## 我们先构造一个和self.biases一样大小的列表,用来存放累加的梯度(偏导数)
nabla_w = [np.zeros(w.shape) for w in self.weights]
## 同上, weights包含两个矩阵,大小分别是30*784和10*30
for x, y in mini_batch:
delta_nabla_b, delta_nabla_w = self.backprop(x, y)
## 对于一个训练数据(x,y)计算loss相对于所有参数的偏导数
## 因此delta_nabla_b和self.biases, nabla_b是一样大小(shape)
## 同样delta_nabla_w和self.weights,nabla_w一样大小
nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
## 把bias的梯度累加到nabla_b里
nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
## 把weight的梯度累加到nable_w里
self.weights = [w-(eta/len(mini_batch))*nw
for w, nw in zip(self.weights, nabla_w)]
## 使用这个batch的梯度和eta(步长)更新参数weights
self.biases = [b-(eta/len(mini_batch))*nb
for b, nb in zip(self.biases, nabla_b)]
## 更新biases
## 这里更新参数是除了batch的大小(10),有的人实现时不除,其实没有什么区别,因为超参数eta会有所不同,如果不除,那么eta相当于是0.3(在eta那里就除了batch的大小了)。
这个函数就是求loss相对于所有参数的偏导数,这里先不仔细讲解,等下次我们学习梯度的求解方法我们再回来讨论,这里可以先了解一下这个函数的输入和输出,把它当成一个黑盒就行,其实它的代码也很少,但是如果不知道梯度的公式,也很难明白。
def backprop(self, x, y):它的输入就是一个训练样本(x,y)分别是784*1和10*1。输出就是和self.biases,self.weights一样大小的列表,然后列表中的每一个数组的大小也是一样。具体到上面的例子,输出nabla_b包含两个矩阵,大小分别是30*1和10*1;nabla_w也包含两个矩阵,大小分别是30*784和10*30。
nabla_b = [np.zeros(b.shape) for b in self.biases]
nabla_w = [np.zeros(w.shape) for w in self.weights]
# feedforwardactivation = x
activations = [x] # list to store all the activations, layer by layerzs = [] # list to store all the z vectors, layer by layerfor b, w in zip(self.biases, self.weights):
z = np.dot(w, activation)+b
zs.append(z)
activation = sigmoid(z)
activations.append(activation)
# backward passdelta = self.cost_derivative(activations[-1], y) * \
sigmoid_prime(zs[-1])
nabla_b[-1] = delta
nabla_w[-1] = np.dot(delta, activations[-2].transpose())
for l in xrange(2, self.num_layers):
z = zs[-l]
sp = sigmoid_prime(z)
delta = np.dot(self.weights[-l+1].transpose(), delta) * sp
nabla_b[-l] = delta
nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())
return (nabla_b, nabla_w)
未完待续
收起阅读 »
作者简介:李理,目前就职于环信,即时通讯云平台和全媒体智能客服平台,在环信从事智能客服和智能机器人相关工作,致力于用深度学习来提高智能机器人的性能。
责编:周建丁(zhoujd@csdn.net)
花式营销渐远,懂用户的服务才有未来
花式杂耍将被新消费技术背书的服务不断打脸
今天,服务在很多人眼里,还停留在售后层面;即使是被移动互联网潮水不断 “打脸”,虽然BAT在不断强调这是一个被服务所承载的用户体验时代,但传统行业及很多企业依然将服务定义为售后,似乎成了墨守成规,而且很多企业把服务中心看成为成本中心,谈起对企业的贡献就要划清界限。
在这些企业眼里,大部分商品交易是一锤子买卖,售前你是上帝,售后你是魔鬼。过度追求利益和强调回报率,导致出现“有钱就服务,没钱就示忙”的“坏圈”,即使宣称有售后,其实是售了就没有以后。
前段时间微博流传一个案例,和我们平时拨打银行的客服一样,某低额储户致电某大银行客服,打几分钟了还提示繁 忙,最后进入语音留言;但这个用户很聪明,在留言中表示自己要咨询存款理财的事情,银行的客服电话马上就回拨过来了,接着这个用户对客服痛斥一番,银行服务人员最后表示了道歉。这些年,许多涉足金融业的互联网公司用哪怕是一点传统银行不肯让惠于用户的小甜头服务,就已让传统银行处于“落花流水春去也”之态势;如果它们还固守“‘有钱’就给服务,‘没钱’无限等待”的思维,在未来金融业全面开放后的竞争中一定会被完全颠覆。
就算是重营销,但很多大企业的营销模式依然是老套路。笔者最近接到不少楼盘、理财类销售电话,外呼似乎依然是这些企业的主要营销手段,而笔者所在的通信运营商,主动的营销手段也以短信通知及外呼营销为主,而显然短信通知已渐渐成为用户遗忘的糟粕,外呼营销虽然给用户带来骚扰感,但当前依然用,只是利用规模效应来拉量。两者由于无法在用户最合适的时间进行营销买卖,所以容易被用户所排斥,不懂用户的营销就是骚扰,相关整治已经上升到了国家层面。
在前沿技术上的革新上,担任“万众创新”主力部队的国内民营企业,更多的是在营销模式上机关算尽,从饥饿营销到病毒传播,玩得不亦乐乎;而在产品创新及黑科技深度上,永远都是走着模仿的套路,走出去就吃专利官司,唯有在国内躺着享受新营销模式的红利,于是有了某宝的“店大欺客”,“屌丝米”舶来乔布斯营销模式成就400亿估值,但无法持续满足用户对产品服务体验的追求,便真验证了成也萧何败也萧何,目前估值下降到40亿。
服务,是一种脚踏实地的营销模式,而且是一种基于用户需求和互动的长营销。大多数服务隐藏着高价值营销需求,特别是在泛金融、电商、通信等行业。以通信运营商为例,终端、手机套餐或宽带产品被用户购买后,意味着销售工作才只是开始而已,不应该只关注最开始的卖出环节,客服中心是服务营销的主体机构,不应该被简单看成成本中心。市场营销部门知道哪款产品卖得好,但不一定知道为何卖得好、用户最喜欢的部分是什么,不能第一时间获取用户群的声音。服务是产品设计、优化产品和迭代的重要“情报站”。未来,重营销藐服务者,必定会被市场抛弃。
下面笔者分享一下最近发生的两个案例:
万达老王驳斥营销的规划,卖完不管后边是不懂商业规律。
前不久网上发布了一段王健林日常工作的视频,王健林对汇报的下属说“不能看营销人修改的东西,他们是卖完不管后边,着重的是后边接手的人员,没有全局(观),是很要命的”。
同样,下属汇报合肥项目商业地产开发项目说考虑到将来做餐饮、冷饮,在走廊里面设计一些休息室,还摆一些小座椅什么的。王驳斥:不能开玩笑,这么一弄彻底死了,送菜送汤把走廊全部弄得脏兮兮的。
另外有一个项目,主管的设计方名称叫做:黄金屋项目,王训斥:黄金屋多么的土啊,太蠢了,完全土豪。像叫红灯笼、金编钟这样体验中国文化的名称不是挺好的吗?
懂得用户,是懂得商业规律的一种体现。做营销的不会管客户后续反应如何,只管卖出去,是否退货,客户是否抱怨,口碑是否差,不管了。
笔者并不是否定营销,我们应该反过来看,做市场营销都是为了服务做支撑的,而不是服务为市场开拓者擦屁股。服务,不管是售后还是售前。营销主要是撮合交易,但用户使用后的感知是基于对服务的体验,“做实”服务、懂用户,才是真懂商业规律。
360老周当客服,重视用户声音的产品经理才是好BOSS。
10月初,360的老周在微薄公开说要当客服了,其实一直以来,老周在微博、微信上与用户互动得很好,经常见到其亲自上阵解决问题。
360官方微信号文章中描述:要解决这个问题,就要把“用户至上,体验为王”真正贯彻为360团队的文化,这也是互联网思维最基本的点。客服作为一线的、最直接和客户接触的群体,他们有很直观和很深刻理解。所以做好客服,接收到来自各方的反馈,公司才能不断完善产品,让产品更接近用户的需求点。
很多产品经理说,我的产品很好啊,为何用户不买账。因为产品经理只看到产品的亮点,而用户可能被亮点吸引,然而很多产品所谓的亮点都不够说服用户来体验,或许会因为冲动消费了一把,但没有服务的闭环来支撑体验感知,没有形成粘性和口碑,品牌得不到持续的发展。今天,连互联网的大佬们都要亲自上门做服务,正如老周所说: “自己的狗粮自己都不吃怎么行”。
服务是用户声音通道,不重视用户的声音,用户会买账吗?会被持续忽悠?
很多市场营销者,对服务嗤之以鼻,认为自己在前线开拓“江山”,是利润中心;但是客户靠什么来维系呢?市场开拓者说,用钱砸用户关系就行了,但是钱能一直烧下去吗?美团、大众点评烧得不少吧,滴滴、Uber烧得不少吧。诚然,市场营销团队是战场上的主力;但服务团队不仅承担了粮草物资筹备运输,还有用户的情报收集角色。
未来经营用户的服务凸显,运营产品思维的营销渐消
而随着“智能+”时代的到来,基于用户消费需求的数据对比中心逐渐取代营销将成为趋势,这个信用中心将所有商品及服务从质量、口碑等维度进行对比,并指导用户进行理性选择,当然非理性选择依然存在,但无论花式营销多么成功都无法掩盖产品或者服务本身的问题。
今天,花式营销可以把石头包装成为钻石,未来石头就是石头,花式营销将无法在智能技术及信用数据面前遁形;而服务将从懂用户中凸显其价值,成为企业长青的最好背书!
本文原载于《客户世界》2016年11月刊;作者曾岳衡,广东移动(江门)客服中心。 收起阅读 »
iOS客户端集成环信3.0详解
集成的SDK版本 V3.2.1
版本时间2016-11-12
集成时间2016-11-21
前提:
观看视频,视频地址如下:
环信SDK集成:http://www.imgeek.org/video/40
环信EaseUI集成:http://www.imgeek.org/video/39
具体集成过程:
一: 添加依赖库
1. CoreMedia.framework
2. AudioToolbox.framework
3. AVFoundation.framework
4. 4.MobileCoreServices.framework
5. ImageIO.framework
6. libc++.tbd
7. libz,tbd
8. libsqlite3.tbd
9. libstdc++.6.0.9.tbd
10. Foundation.framework
11. libiconv.tbd (Xcode7以上)
最终效果如图:
二:一些设置
1.修改info.plist文件,适配iOS9以上系统,在info.plist中添加
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
2.修改info.plist文件,适配iOS10.0,在info.plist中添加
为了调用相册,地理位置,话筒,照相机,通讯录
<key>NSPhotoLibraryUsageDescription</key>
<string>中华人需要使用相册服务获取照片</string>
<key>NSCameraUsageDescription</key>
<string>中华人需要使用照相机服务进行拍照获取照片</string>
<key>NSContactsUsageDescription</key>
<string>中华人需要使用通讯录服务进行好友邀请</string>
<key>NSMicrophoneUsageDescription</key>
<string>中华人需要使用话筒进行吐槽反馈信息</string>
<key>NSLocationUsageDescription</key>
<string>中华人需要使用定位服务来发送位置信息</string>
3.Bulid Setting 设置bitcode 为NO,如图:
4.新建pch文件,如图:
进行设置,如图:
三:Appdelegate
#import "AppDelegate.h"四:添加键盘表情(说明)
#import "ChatViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// SDK的初始化
/**
* EMOptions类是SDK的配置信息
* 可以加入推送证书的名称
*/
EMOptions *options = [EMOptions optionsWithAppkey:@"luoxiaoyong#mingxin"];
options.apnsCertName = @"Push_dev";
// 初始化SDK
EMError *error = [[EMClient sharedClient] initializeSDKWithOptions:options];
if (!error) {
NSLog(@"初始化成功");
}
// 登录
error = [[EMClient sharedClient] loginWithUsername:@"xrdaly001" password:@"123456"];
if (!error) {
NSLog(@"登录成功");
}
else {
NSLog(@"登录失败");
}
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
ChatViewController *vc = [[ChatViewController alloc] initWithConversationChatter:@"xrdaly002" conversationType:EMConversationTypeChat];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
self.window.rootViewController = nav;
[self.window makeKeyAndVisible];
return YES;
}
在EaseMessageViewController.m的viewDidLoad方法结尾处加上
EaseEmotionManager * manager = [[EaseEmotionManager alloc] initWithType:EMEmotionDefault emotionRow:3 emotionCol:7 emotions:[EaseEmoji allEmoji]];
[self.faceView setEmotionManagers:@[manager]];
五:国际化文件乱码问题
下载demo,直接把demo中的国际化文件拷贝到现在项目中,ok
以上就是实现环信单聊的全部过程,,如有任何疑问欢迎加Q:714700382,我们共同讨论,共同进步 收起阅读 »
后移动互联网时代App创新的挑战 【北京站】
本次活动APICloud联合图普和智齿跟大家聊聊,后互联网时代,App如何创新?
13:30-14:00 签到
14:00-15:00 后移动互联网时代App创新的挑战
微信小程序的推出是否会改变现有的移动格局?
后移动互联网时代的App应如何创新?
15:00-15:40 如何利用人工智能使你App差异化
15:40-16:20 后移动互联网时代的客户服务变革与创新
16:20-16:25 抽奖
16:25 活动结束&自由交流
APICloud创始人兼CEO 刘鑫
刘鑫,APICloud移动应用云服务创始人兼CEO,见证了中国移动互联网从SP梦网到智能机时代的全过程。专注于国内外移动应用开发平台领域的研究,系统的阐述过Web App的挑战与Hybrid App的发展。并且凭借APICloud.com移动应用云服务成功拿到北极光领投的A轮融资。
图普科技市场负责人 李麟
曾在新浪,电信负责市场及战略合作,经历过两次创业,在产品,运营,市场等方面有丰富的实战经验。
智齿科技产品总监 杨兴成
智齿科技产品总监,曾任凤凰网产品经理,负责凤凰新闻媒体开放平台、凤凰网APP;智齿客服,移动时代的智能客服,专注为企业提供人工智能服务。
活动时间:2016年11月26日(周六)13:30-16:30
活动地点:义创空间—(北京)小样青年社区(北京市海淀区中关村创业大街甲一号鼎好大厦A座扶梯口上2楼)
报名链接:http://www.huodongxing.com/event/5361525571400
收起阅读 »
Erlang之父Joe Armstrong今日到访环信,激情讲述如何构建一个永不停机的系统
据环信社报道:今日,61岁的Erlang之父Joe Armstrong不远万里来到中国,与环信程序猿一行举行了亲切的会谈。Joe分享了对如何学习编程,如何成为大牛等一系列热门问题提出了自己的看法。
大神Joe激情讲述如何用Erlang特性来构建一个永远不停机的系统。Joe表示:“一个永不停机的系统需要能够在多种失败的情况下依然能够保持正常运行。特别在系统维护和升级方面,Erlang独有的热代码替换有着天然的优势。”
环信首席架构师&即时通讯云产品线负责人Eric向Joe介绍了Erlang在环信的部署情况:“Erlang在环信已经部署上千台机器,一个典型集群会使用高达3176核8068G内存,用来支持包括移动端、Web端、Windows和Linux等多个平台的千万级长连服务。”
双方在友好、建设性的气氛中深入探讨就共同关心的重大问题深入交换意见,达成重要共识。
Eric向大神Joe赠送环信纪念品
环信首席颜值担当Eric首先欢迎Joe Armstrong访问环信。他说,这是Erlang之父近2年来的首次访问环信,也是中国和瑞典程序猿交流中的一件大事。环信高度重视Joe的访问,相信此访必将对中瑞计算机语言长远发展产生新的推动。(新闻联播口音)
环信小粉丝获得大神Joe亲笔签名赠书
为了帮助大家学习Erlang语言,大神Joe推荐给开发者的教材
Erlang特性:
- 并发性 - Erlang支持超大量级的并发进程,并且不需要操作系统具有并发机制。
- 分布式 - 一个分布式Erlang系统是多个Erlang节点组成的网络(通常每个处理器被作为一个节点)
- 健壮性 - Erlang具有多种基本的错误检测能力,它们能够用于构建容错系统。
- 软实时性- Erlang支持可编程的“软”实时系统,使用了递增式垃圾收集技术。
- 热代码升级-Erlang允许程序代码在运行系统中被修改。旧代码能被逐步淘汰而后被新代码替换。在此过渡期间,新 旧代码是共存的。
- 递增式代码装载-用户能够控制代码如何被装载的细节。
- 外部接口-Erlang进程与外部世界之间的通讯使用和在Erlang进程之间相同的消息传送机制。
- Fail-fast(中文译为速错),即尽可能快的暴露程序中的错误。
- 面向并发的编程(COP concurrency-oriented programming)
- 函数式编程
- 动态类型
- 及早求值或严格求值
- 脚本语言
关于Erlang和Joe Armstrong
Erlang得名于丹麦数学家及统计学家Agner Krarup Erlang,同时Erlang还可以表示Ericsson Language。环信Erlang工程师招聘
Erlang并非一门新语言,它出现于1987年,只是当时对并发、分布式需求还没有今天这么普遍,当时可谓英雄无用武之地。Erlang语言创始人Joe Armstrong当年在爱立信做电话网络方面的开发,他使用Smalltalk,可惜那个时候Smalltalk太慢,不能满足电话网络的高性能要求。但Joe实在喜欢Smalltalk,于是定购了一台Tektronix Smalltalk机器。但机器要两个月时间才到,Joe在等待中百无聊赖,就开始使用Prolog,结果等Tektronix到来的时候,他已经对Prolog更感兴趣,Joe当然不满足于精通Prolog,经过一段时间的试验,Joe给Prolog加上了并发处理和错误恢复,于是Erlang就诞生了。这也是为什么Erlang的语法和Prolog有不少相似之处,比如它们的List表达都是[Head | Tail]。
1987年Erlang测试版推出,并在用户实际应用中不断完善,于1991年向用户推出第一个版本,带有了编译器和图形接口等更多功能。1992年,Erlang迎来更多用户,如RACE项目等。同期Erlang被移植到VxWorks、PC和 Macintosh等多种平台,两个使用Erlang的产品项目也开始启动。1993爱立信公司内部独立的组织开始维护和支持Erlang实现和Erlang工具。
职位:通讯研发工程师(Erlang/Golang) 薪资范围: 25000以上收起阅读 »
工作职责:
1. 负责开发和维护即时通讯系统,优化提高后端服务的承载能力;
2. 或负责优化、改进和实现IM协议,为移动互联网以及物联网用户提供可靠实时的即时通讯服务;
任职要求:
1. 熟悉Erlang、Golang或C/C++开发,有Unix/Linux平台相关经验者优先;
2. 熟悉网络通信机制及常用数据传输协议;
3. 熟悉常用数据库,如MySQL、Redis系统,有HBase或其他NoSQL相关使用经验者优先;
4. 有较强的解决问题能力,能够承受压力情况下完成解决问题;
5. 能够与团队成员紧密合作,共同攻克技术难题;
6. 掌握多种语言者优先,Go、Python或其他语言均可;
7. 需要有开放共享的心态,接受开源思想,有Github创建、维护或参与经验更好;
简历请发送至"talent@easemob.com"
环信移动客服v5.5.1更新:新增多机器人功能,完美适应不同场景
管理员模式
智能机器人界面优化
优化机器人设置页面,将欢迎语等设置合并至“自动回复”页签,将知识库合并至机器人设置。优化后,机器人相关的设置更集中,更方便使用。
欢迎语等合并至自动回复页签
机器人的欢迎语、默认回复、重复回复、超时回复、转人工设置合并至“自动回复”页签。
知识库合并至机器人设置
原来知识库页面的“知识规则”和“菜单素材库”页签合并至“机器人设置”页面,分别对应“知识规则”和“自定义菜单”。
[机器人知识规则]
多机器人功能(增值服务)
新增多机器人功能,支持创建机器人,并且为每个机器人单独设置基础信息、自动回复、知识规则、自定义菜单、场景智能应答。您还可以为新增的机器人绑定不同的关联,回答来自不同关联的用户的提问。
多机器人功能为增值服务,如需开通,请联系环信商务经理。
环信移动客服更新日志http://docs.easemob.com/cs/releasenote/5.5.1
环信移动客服登陆地址http://kefu.easemob.com/ 收起阅读 »
客服如何变为盈利中心?环信要把精准营销融入云客服
环信起家于IM(即时通讯云),2014年6月产品上线,随着业务逐渐完善,公司在IM产品线基础上增加了更加垂直的云客服产品,在2014年10月全力押注云客服。为了巩固优势,又增加人工智能业务,即客服机器人。
经过一系列战略调整,环信的业务线包括即时通讯云、云客服和客服机器人三大块。
如何将这三者结合起来?
环信的做法很直接,首先在手机上提供APP内置客服,这既符合客户服务移动化的时代大趋势,也是基于环信的看家本领-IM;其次将APP内置客服、微信客服、网页在线客服,电话呼叫中心客服等集成到统一的客服平台,提供全渠道客服;第三,加入机器人客服,节省人力,提高效率;第四,通过大数据和人工智能完善客户画像,帮助企业精准营销。
通过这套业务逻辑,环信将打通客服与精准营销,让客服成为一个节约成本、创造利润的部门。
经过市场洗牌,IM业务站稳脚跟
虽然IM是个老业务,在1998年就已经面世,但是直到微信的出现才被推到了顶峰,引发了市场对社交的追捧。许多互联网企业纷纷在产品中嵌入IM功能,发掘产品的社交属性。这也导致了移动IM云厂商应运而生。
环信就是其中之一,IM是环信最早的产品,通过将IM能力打包成云服务和SDK,接入到客户的APP,使之拥有微信、陌陌这类社交软件的IM功能,为客户的APP添加社交属性。
首先是2014年移动IM云市场出现,到2015年,最多时有14家IM服务厂商在争夺市场,其中包括阿里的阿里悟空、阿里百川和腾讯云通讯IM等,市场竞争激烈。但是随着洗牌和市场格局基本确定,大部分厂商都已离场,只剩下几家公司留存,环信成为其中主要的参与者,无论是在IM深耕还是向其他领域延伸,环信都有很大空间。
在业务模式上,环信的IM分公有云和私有云二块业务。公有云主要面向互联网企业,采用按日活方式收费。IM私有云业务主要面向中大型私企,国企,政府,受监管的行业如银行证券等。经过阿里钉钉和企业微信的教育,国内企业都IM是移动办公系统的核心基础。但钉钉和企业微信目前只被中小企业接受,大型企业普遍倾向于IM私有云方案。目前环信的即时通讯云一共聚集了8万APP,未来仍将是重点发展的方向,是公司的现金牛和并未其他业务导流。
由IM切入客服,帮助客户实现精准营销
云客服是IM应用场景的延伸。IM天生就有2种场景。一种是即时通讯云实现的连接人与人的社交功能,一种是云客服实现的人和商家之间沟通,实质上是连接人与商业。不管是淘宝旺旺,还是微信公共账号,本质都是用IM的方式让人(消费者)和商家更好的沟通和服务。
具体来看,环信的云客服分为六个部分。
全媒体接入,通过APP端的IM、网页在线聊天、微信、微博、邮件、工单、电话呼叫中心,七种形态接入统一的客服系统;
客服平台,作为工具性平台提供基础客服功能;
客户旅程透析,分析跨媒体跨渠道客服接入环境下的客户旅程及客户体验;
用户忠诚度运营,提供360度客户画像;
客服机器人,降低人力成本;
精准营销,根据在客户旅程透析、用户忠诚运营360度画像和客服机器人积累起来的数据,为商家提供精准营销。
这六部分综合起来覆盖企业的服务到营销的完整闭环,是环信云客服竞争力所在。
目前在云客服这块已经积累2.9万用户(包括最早免费用户)。其中教育、电商和金融是占比最大的行业,国美在线、楚楚街、泰康在线、新东方、中信证券等都是环信的客户。
对标Zendesk,不仅是Zendesk
与市值超过22亿美元的云客服上市公司Zendesk对比,环信的业务线更长。除了IM、客服平台、客户行为分析、客服机器人这类相互重合的业务,环信还从客服延伸到营销销售。不像Zendesk仅作为客服工具,环信在提供客服工具之外更是帮助客户销售产品。
Zendesk目前付费客户达到81,000,客单价较低,约3,000美元左右,由于大部分客户是中小客户,客服需求少,付费也就少,自然拉低了客单价。而环信这边的两种收费标准:
1500元/坐席/年、4800元/坐席/年,与Zendesk收费标准相似,但是主要面向中大型企业客户,目前环信平均客单价在5万左右,部分大客户客单价超过50万元。
参考2015年Zendesk约2.08亿美元营收,以及50%以上增速,中国云客服市场仍然广阔。对于环信来讲,业务定位并不止于客服。
布局未来,重点投入人工智能
在云客服产品推出之后,环信成立客服机器人业务线。
随着人力成本的提高,客服将不再是一个依赖人力的行业,以人工智能为基础的客服机器人将逐渐成为客服的重要部分,不仅如此,在应对日常的客服之外,客服机器人还能分析客户画像,进行精准营销,是客服行业未来的趋势所在。
从目前行业现状来看,云客服厂商在人工智能领域的表现都差强人意,有些仍旧是基于搜索的方式做客服机器人,结果表现为用户体验差,维护困难。
针对人工智能,环信投入20多人的团队开发基于深度学习的人工智能机器人服务,并已推出了环信机器人、环信客户声音和环信机器人智能质检等产品功能。在人工智能的探索上走在前列。
近期,爱分析对环信创始人刘俊彦进行访谈,现将部分内容分享如下。
Q:IM、云客服和客服机器人三块业务占比?
A:收入上来讲,IM与云客服一半一半,客服机器人这边有20多人的团队在做,暂时没有收入。
Q:环信在客服机器人的进展?
A:人工智能的产品建设需要很多时间,所以持续在进行,已经陆续推出几个产品,包括环信智能客服机器人、环信客户声音和环信机器人智能质检。
环信智能客服机器人为客户提供机器人客服,客户声音基于全渠道客服产生的大量非结构化数据做客户旅程的透析,环信机器人智能质检会应用在一些特殊行业比如保险、金融等监管要求比较高的行业,做全员智能质检,现在基本能检出80%的内容,很大程度上代替人工质检。
Q:做好客服机器人的关键在于?
A:我把机器人在客服行业的落地分为几个层面。第一个层面是单轮会话的能力,这一项所有做客服机器人的公司都能做,但有部分公司需要人工对问答库做手动的维护和标注。这是当前很多企业实施客服机器人失败的主要原因,客服机器人系统买的起,但长期维护成本太高,用不起。第二个层面是多轮会话的能力,可能有50%的公司做不了多轮会话。第三个层面是人机协作,在一些以销售为导向的售前场景,服务的目的是为了转化和成单。销售是一门艺术,当前的人工智能技术,还达不到代替一个topsale的阶段。这种情况下,机器人退居二线,但可以根据消费者和真人客服的对话过程向客服推荐会话,不仅能提高客服的工作效率,好的会话推荐模型还可以把行业最佳实践应用到每个普通客服的身上。
做好机器人客服,不仅要有牛逼的人工智能团队,更要有海量的数据。泰康在线,新东方都是环信机器人的客户。
Q:人工智能在客服领域的应用前景?
A:创业公司涉足人工智能一定要找到最垂直的行业,深挖下去,否则无法与Google、百度等巨头竞争。
我看到创业公司有机会的人工智能领域包括,无人驾驶、医疗、金融和客服这四个行业。人工智能之所以在客户领域落地会产生巨大价值是因为:1.客服行业是个传统的劳动密集型行业,有通过新技术来大幅度优化人力成本的强烈需求。2.客服行业天然存在海量的数据,如以语音,文字为主要形式的客服沟通记录。3.客服沟通记录中沉淀了大量的行业知识体系,比如新东方的客服如何帮助消费者推荐一个英语课程。通过机器人系统不断对特定领域的知识图谱进行抽取和积累,是阻止后来者包括巨头公司进入的主要门槛。在客服领域,金融理财、教育、电商对AI的需求非常大。
Q:环信在2014年以IM起家,当时市场的竞争情况?
A:环信是第一家正式发布即时通讯云的公司。
在2014年随着IM产品的成功,很快有几家创业公司进入,到2015年市场进入混战的格局,最多的时候有14家公司,其中包括阿里的2个产品,腾讯的1个产品,但是到2016年就变了,市场只有前三名有份额,环信排第一。
ToD市场遵循28原则,市场第一拿8,第二拿2,第三不入流,其他的公司拿不到份额就撤了。
Q:BAT在IM领域内部创业为什么失利?
A:哪怕是BAT在to B领域创业,也不一定能成功。
首先是技术门槛,虽然阿里和腾讯的微信、QQ和钉钉很强,但是内部创业的团队并一定是核心团队,相比创业公司并不一定有优势;
第二是资金门槛,BAT内部创业拿的钱也有限,可能拿个500万开始创业,但是比较环信拿了几个亿融资,并不具备优势,如果短时间内做不到行业第一,BAT也不会继续为他们输血;
第三是流量门槛。企业级服务与to C不一样,BAT在to C端的流量优势并不能为to B的业务直接导流;比如环信就从来不做电梯广告,因为那个没用。to B的用户流量是要一个一个生磕出来的,在这点上创业公司没有劣势。
第四是产品门槛。像snapchat这样的to c产品,大家都一看就懂,BAT可以用2周抄出产品,然后利用资金和流量优势快速放大。但toB行业完全不一样。一个200人的呼叫中心到底怎么管理的,现场大屏幕监控怎么做,排班怎么排,KPI怎么考核,这个没有多年垂直行业经验连产品原型都做不出来。BAT不如这个专注于垂直领域的创业公司有经验。
Q:环信客服业务面向中大型客户,IM面向的客群是?
A:IM的客群包括大客户和小客户,因为交付更简单,大型客户小型客户都能满足,只不过大的客户客单价高,小的客户是长尾数量大。
Q:云客服业务包括售前和售后?
A:环信早期偏重做售前,因为像教育、金融、电商这些付费能力强的行业最重要需求在售前,初期的大客户也集中在售前环节。而且基于环信IM的客服形式,主要强项也是实时沟通,适合要求响应速度快,客单价高的售前环节。
售后部分主要是邮件、工单这类服务,现在做好售前的基础上也开始做售后服务。
Q:环信很少对外披露自己的数据?
A:环信不是不做公关,而是针对性的做公关,因为我们的客户集中在比较传统的中大型企业,所以对外宣传的目标都是这些企业,在他们能看到的地方比如说行业媒体和会议上投放的比较多。
客户看到环信的介绍后,再了解环信,都愿意使用环信的产品,所以环信的百度指数是最高的。
Q:用户数量?
A:环信IM用户8万家,客服用户2.9万家。其中有许多是之前的免费用户,但是现在环信的策略是不再开放免费版,每一个新客户都收费。
环信客服用户增长很快,互联网属性很强,但是现在其他行业属性也很强,比如教育、金融、电商这些偏传统行业,客户客单价大几万。
Q:大客户客单价在什么水平?
A:年费50万以上属于大客户。
Q:为什么说国内这波企业级服务投资热潮是在押注中国出现千亿市值的to B公司?
A:中国一定会出现自己的Oracle和Salesforce。Oracle市值1600亿美金,Salesforce500多亿美金。
一是中国企业在软件上的消费能力正在打开,去IOE后大型企业不买IBM、Oracle、EMC,开始选用国内的产品,而中小企业也开始注重效率,愿意为软件服务付费。二是国外企业因为ICP牌照进不来中国,给了国内企业成长的机会,简单的例子就是百度能成长起来是因为Google被赶出去了。
Q:成为千亿市值的企业级服务公司的路径是什么?
A:首先要占据核心赛道。只有在核心赛道上,才能保证足够的纵深和各路竞争对手厮杀迂回,才能有足够的市场支撑足够大的销售收入并放大估值想象空间。现在我看到的核心赛道大概有五条:协同办公(但是已经被BAT占据);销售自动化(销售易,纷享销客、红圈营销。都过c轮了或者新三板挂牌了,市场格局已定,新公司难有机会);客服跑道(现在虽然环信比较领先,但也还有不少公司竞争,类似1年前的销售自动化赛道。预计1年后市场会逐渐整合,剩下三四家左右);HR跑道;财务软件跑道(被用友、金蝶占据,创业公司机会小)。
第二在核心赛道上成为小巨头;预计会享有几十亿到百亿的市值。
第三通过自身横向扩张或者并购进入其他核心赛道,成为大巨头,综合性软件公司。Oracle和Salesforce都是综合性软件公司。zendesk只做客服软件,所以现在zendesk市值只有20多亿美金。
Q:云客服竞争中脱颖而出的关键?
A:关键在服务好大客户,大客户会有大量的定制开发和个性化需求。要做到这一点就需要建设好底层的PaaS平台,环信不敢说已经做好了PaaS,但基本完成了2/3。未来80%的通用需求环信来解决,剩下20%的个性化需求企业通过PaaS平台来实现。
80%是核心,20%可以外包出去,由生态圈伙伴和集成商来做。
当然还有人工智能。人工智能决定了一年后,你只是一家工具软件公司,还是一家可以输出服务,行业知识图谱,以及行业最佳实践的公司。
收起阅读 »
见云沙龙:互联网出海生存之道
你,是否开始向往国外广阔市场的美好前景?
你,是否需要了解如何跨过走向海外的暗礁?
越来越多的企业希望跨出国门,探索海外蓝海市场。但国内企业出海仍然面临技术、文化、商业环境等诸多挑战。为此,见云社区、迅达云SpeedyCloud、IBM联合发起了“见云沙龙”第3期——“互联网出海生存之道”主题沙龙,将邀请百度、大观资本、Mobvista、迅达云、IBM、白鲸社区等嘉宾参与,旨在分享企业出海的经验,避免掉进同一个坑。
11月26日,周六,北京、中关村、3W咖啡,
经验丰富的老司机们,讲讲如何驾驭出海的几座大山,技术、文化、环境、资本......来这里,和榜样们面对面,成为下一个榜样!
活动议程
13:00~13:55 签到
13:55~14:00 开场介绍
14:00~14:30
《海外互联网产品的技术经验》
刘占亮 互联网国际化专家
在海外市场,你可能遇到技术、文化、语言等各种问题,本次分享将从以下几点介绍在海外市场运营的经验:
1、工具型产品 vs. 内容型产品
2、语言文化差异与用户需求把握
3、数据驱动 vs. 产品驱动
4、产品技术挑战
14:30~15:00
《IBM SoftLayer 公有云 -省心易用, 全球同服》
蒋旭春 IBM云计算技术经理
IBM SoftLayer公有云如何帮助企业出海,跨境运维,全球同服,独特的竞争优势。
15:00~15:30
《引领非洲互联网春天的混合网络媒体平台》
庞一 四达时代集团研究院常务副院长
在泛非地区(撒哈拉沙漠以南),在不同层面(骨干网、接入网、终端等),将广播电视网与互联网整合,提供更高效低成本的端到端视频直播、点播媒体传输运营平台。利用互联网技术升级付费广播电视业务的支撑能力。在泛非地区,缺少有线网络,缺少宽带网络,缺少计算机终端,只有近些年发展的移动互联网网络及增长快速的智能移动终端,本演讲会介绍针对泛非独特的互联网基础设施的环境,如何与广播电视网络结合,提供更优质的媒体服务平台,进而支持更丰富的互动增值业务。
15:30~16:00
《全球云计算资源一体化整合实战》
陈震 迅达云SpeedyCloud运维总监
在全球化的今天,尽管大型云服务公司覆盖了大部分地区,但仍然不能保证100%覆盖。因此,将不同的云服务平台无缝的整合在一起就显得十分必要了。本次分享将介绍迅达云如何在全球整合云计算资源,并为用户提供一体化的服务的实践经验。
16:00~16:30
《猎豹出海故事》
范路 大观资本创始合伙人
猎豹移动于2010年10月由金山安全和可牛影像合并而成,专注在海外移动市场。本次分享将介绍猎豹移动出海的历程,以及选择出海的原因和背景。在出海之后,遇到的各种问题以及解决的方法。
16:30~17:00
《海外产品推广&变现》
王平 Mobvista CTO
2014年猎豹在美上市,将中国移动出海推到了崭新的里程碑高度,吹响了大航海时代高速发展的号角,至2016年,中国移动产品在海外已经百花齐放。出海已成热点,而出海初期如何迅速获取海外用户,当用户规模起来后又如何解决变现,始终是开发者关心的问题。
17:00~17:30 圆桌讨论《互联网出海生存之道》
17:30 结束
讲师介绍
刘占亮 互联网国际化专家
刘占亮,天津大学计算机硕士。毕业后先后供职于微软亚洲研究院、腾讯、搜狗和百度,历任研究软件工程师、研究员、资深研发工程师/高级技术经理。目前在百度国际化事业部负责内容型产品线的算法和架构团队。2006-2010曾作为产品技术负责人参与创办Hitchsters.com。同时他与学术界也有密切的联系,他是中国人民大学大数据分析与智能实验室的兼职架构师。他有着广泛的研究兴趣,包括信息检索、互联网搜索、数据挖掘、自然语言处理和人工智能等。
蒋旭春 IBM云计算技术经理
蒋旭春,IBM云计算技术经理,10+跨国运营商CP/SP/PaaS平台开发设计经验。
庞一 四达时代集团研究院常务副院长
庞一女士现任四达时代集团研究院常务副院长(主持工作),分别于2005年和2010年获得清华大学计算机系工学学士学位和博士学位(优秀),西贝尔学者(Siebel Scholar)。博士期间从事视频图像高性能处理等课题研究,作为第一作者获得视频领域优秀国际期刊IEEE Trans. CSVT最佳论文奖,这是大陆高校首次独立获得该奖项。2012年加入四达时代,2013年负责筹建四达时代研究院,设计构建四达下一代多业务平台,利用互联网技术提升广播电视媒体传播平台支撑能力,构建泛非首个媒体云平台、大数据平台和在线支付平台,拓展互联网媒体娱乐业务。
陈震 迅达云SpeedyCloud运维总监
陈震,2011年开始从事公有云服务运维工作。2011年至2013年在蓝汛就职高级运维工程师,曾维护过BTV、小米等客户。2013年中旬入职迅达云成,任职运维经理,后升为运维总监。
范路 大观资本创始合伙人
范路,大观资本创始合伙人,是一位技术型的投资人,结合了10年的码农经验,和20年互联网和移动互联网经验,行业内真正熟悉出海运营的技术专家。
王平 Mobvista CTO
王平就职于Mobvista,担任CTO,负责公司整体商业变现技术体系的构建和管理。Mobvista,是亚洲最大的移动广告平台,Mobvista是亚洲最大的移动广告平台,凭借着自身覆盖全球240多个国家、每天超过100亿展示量的移动流量体系,专注于海外高质用户获取与流量变现。在加盟Mobvista之前,先后在百度、高德就职。在百度,作为凤巢核心成员,负责凤巢流量变现商业产品的技术管理,主要聚焦在广告存储、变现算法和架构、百度商业知心等方向,承担百度凤巢提升10%~14%的收入业绩。随后加入高德担任商业变现总监,负责产品和技术管理。9年多的职业生涯,一直活跃于互联网商业变现领域的风口,对行业技术体系构建有深刻的理解。
现场福利
报名链接:http://www.huodongxing.com/event/6359813352600 收起阅读 »
有关头像处理的问题
第一个就是缓存本地,在我们刚进入程序的时候,我们把获取所有的好友信息,把她们的信息获取到,这时候我们要知道,在我们用
self.messageArray = [NSMutableArray
arrayWithArray:[[EMClient sharedClient].chatManager getAllConversations]];
这个方法获取的是所有的好友的ID ,在我们查询数据库的时候根据这个ID 进行查询就可以获取这个用户的你所要的信息,头像,昵称,等等,在这个方法中需要注意的时候,当被人添加你为好友的时候,或者你删除被人为好友的时候,需要更新你的数据库,
第二个就很简单了,消息扩展
NSDictionary *dic = [[NSDictionary alloc]initWithObjectsAndKeys:@"rand",@"money_type_special",self.userID,@"userID",self.position,@"positionStr",self.nameCatergoryStr,@"name",self.gooAtStr,@"gooAtStr",self.imagUrl,@"imagUrl", nil];
EMMessage *message = [EaseSDKHelper sendTextMessage:@"向您分享一张名片! " to:model.userid.stringValue messageType:EMChatTypeChat messageExt:dic];
[[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:^(EMMessage *aMessage, EMError *aError) {
if (!aError) {
[MBProgressHUD showSuccess:@"发送成功" toView:self.view];
self.tableView.userInteractionEnabled = YES;
}else{
[MBProgressHUD showError:@"发送失败" toView:self.view];
}
把头像和昵称做成字典dic 在接受消息的时候,按照消息扩展 NSDictionary *ext = messageModel.message.ext; 进行相应字段解析就OK了
希望对你有帮助 收起阅读 »
你看过最漂亮的开源IM Demo UI
项目开源地址:https://github.com/gyjzh/LLWeChat
github上有项目的详细描述,这里就仅仅发一部分,下面上效果图。
一、输入框动态调整高度
二、文本全屏浏览
三、发送照片
四、发送视频
五、地图
六、录音时长
这个项目的顺利开发离不开环信的支持,在此祝愿环信越来越好。 收起阅读 »
解读Gartner 2017年十大技术趋势
Gartner将战略科技发展趋势定义为具有颠覆性潜力、脱离初级阶段且影响范围和用途不断扩大的战略科技发展趋势,这些趋势在未来五年内迅速增长、高度波动、预计达到临界点。
“2017年十大战略科技发展趋势为Gartner智能数字网(Intelligent Dgital Mesh)提供了舞台。”Gartner副总裁兼研究员David Cearley说,“这十大趋势中,前三个趋势体现了‘智能无处不在’,数据科学技术和方法如何演化,向先进的机器学习和人工智能发展,以将智能物理和基于软件的系统应用于机器学习和自适应。接下来的三个趋势聚焦数字世界,物理和数字世界日益纠缠。而最后四个趋势则着眼于智能数字网络所需的平台和服务网络。”
让我们逐一看看Gartner预测的十大技术趋势并进行分别简单地分析。
人工智能和高级机器学习
人工智能(AI)和高级机器学习(ML)由许多科技和技术(例如,深度学习、神经网络、自然语言处理(NLP))组成。 更先进的技术超越了传统的基于规则的算法,以创建理解、学习、预测、适应和潜在地自主操作的系统。 这就是智能机器出现“智能化”的原因。
“应用人工智能和高级机器学习带来了一系列智能实现,包括物理设备(机器人,自动车辆,消费电子)以及应用和服务(虚拟个人助理(VPA),智能顾问)”。Cearley说,“这些实现将表现为新一类的智能应用和物件,以及为广泛的网格设备和现有的软件和服务解决方案提供嵌入式智能。”
这个问题的关键在于如何产生嵌入式的AI技术,能够支持业务流程、模型,以及从一开始就被定义为企业中“智能”模块的应用。另外,资金也是个大问题。
智能App
诸如VPA的智能App执行人工助手的一些功能,使日常任务更加容易(例如,优先考虑电子邮件)及其用户效率的提高(突出最重要的内容和交互)。其他智能App(如虚拟客户助理(VCA))更加专注销售和客户服务等领域的任务。因此,这些智能App有可能改变工作的性质和工作场所的结构。
“在未来10年,几乎每个应用程序和服务都将包含一定水平的人工智能。”Cearley说,“这将成为长期趋势,不断发展和扩大人工智能和机器学习应用和服务。”
这对一些企业而言是一个巨大的机遇,目前在应用、基础设施和设备上的智能分量越来越重。运用智能应用的形式是通过新的智能特性嵌入到某一行业的现有应用程序中。麦当劳生产汉堡包运用了智能App,对汉堡包面包生产的监控由人工专为自动化,能够提高并保证质量。智能应用还拥有数据和分析的优势,如,每分钟通过照片分析超过1000个面包来检查颜色、形态和芝麻分布,并根据分析结果不断自动调整烤箱和流程,以保证生产最好的汉堡包面包。其带来的结果显而易见:避免了浪费,每年节省数千万元;加速生产并节约能源;减少人工成本。
智能应用对其他行业也有显著的价值,比如医学顾问。凯特琳癌病中心肿瘤学顾问,应用智能App可带来高价值的用户,并能解决复杂的问题,整理杂乱、非结构性和重复内容,并带给用户高影响力的结果。
智能事物
智能事物指的是超越刚性编程模型的物理实体,利用人工智能和机器学习来实现高级行为,与周围环境和人们交互更加自然。作为智能事务,如无人机,自动车辆和智能家电的不断普及,Gartner预计单独的智能物件将演变为协作的智能物件模型。
智能事物的预测,就是认为在可以预期的未来,任何事物都可以智能化,比如消费者产品、医疗产品、嵌入式产品等等。但这个预测已经滞后了,现在已经有这方面的产品,甚至都具备了可用性。比如Google、Uber研发的应用在通用道路的自动车辆;运用在特定环境的自动驾驶汽车:如无人收割机等;以及各种各样的机器人,比如零售机器人、迎宾机器人等等。
除了上述智能事物的形式外,还有协同智能。
虚拟和增强现实
沉浸式技术,如虚拟现实(VR)和增强现实(AR),改变了人与人和人与软件系统交互的方式。
Cearley说:“到2021年,沉浸式消费、商业内容和应用程序的格局将发生巨变。VR和AR功能将与数字网络合并,形成一个更加无缝的设备系统,能够协调来自用户的信息流作为超个性化的相关应用和服务。融合多个移动、可穿戴设备、物联网和大量传感器的环境将拓展沉浸式应,超越孤立的单人体验。客房和空间将与物体互动,它们通过网络的连接,并与沉浸式虚拟世界一起工作。”
时下,正是VR、AR兴起的时代。有各种各样的产品已经出现并投入使用,比如可以应用于模拟体验;对于科学研究来说,可以用于分子建模;医生也可以用于远程虚拟诊断并开出医疗处方,等等。孩子还可以应用这种技术,进行探索动物园等未知世界。这个趋势的预测已经滞后了,严格讲,不算趋势预测而是实实在在来临了。
数字化双生
数字化双生(Digital Twin)是事物或系统的多元软件模型,它依赖于传感器数据来理解其处境,响应变化,改进操作和增加价值。数字化双生包含元数据(例如,分类、组成和结构),处境或状态(例如,位置和温度),事件数据(例如,时间序列)和分析方法(例如,算法和规则) 。
在三到五年内,数以亿计的物件将由数字化双生的形式呈现。组织将使用数字化双生主动修复和规划设备服务、规划制造流程、操作工厂、预测设备故障或提高运营效率,以及执行增强的产品开发。因此,数字化双生最终将成为技术人员和传统监测设备和控制(例如,压力计,压力阀)的组合的代理。
这个预测没有什么新意。显然,物联网的发展显示了数字化双生的潜力。数字化双生可以理解为不断发展和扩张的数字化宇宙,这需要从智能生态系统的内容、广度和控制将继续从不同维度上扩展。
区块链和已分配分类帐
区块链(Blockchain)是一种已分配分类账(Distributed Ledgers),其价值交换交易(以比特币或其他代币计)按顺序分组成块。每个块链接到前一个块,使用加密的信任和保证机制,跨对等网络进行记录。区块链和分布式分类账概念日益广受关注,因为它们有望改变行业运营模式。虽然当前炒作是围绕金融服务行业,但是应用前景广泛,包括:音乐分发,身份验证,所有权登记和供应链。
Cearley说:“已分配分类帐有可能引起一场变革,但大多计划仍处于早期的Alpha或Beta测试阶段。”
该趋势预测的要点就是在不可信环境中增加信任的机制,对于重要数据和事件不可更改的记录,例如货币交易、财产登记或其他有价资产,不仅是被动式数据记录,同时能够有选择性的为事件增加动态预置行为。这个技术在供应链中蕴含着万亿美元的机遇。但是人们并不十分了解区块链技术,最大的挑战就是如何能广泛使用区块链。区块链的实施需要各方进行深入合作,区块链行业将如何发展,现在还无法预测是各方割据还是一家独大的局面。
会话系统
会话界面的当前焦点集中在聊天机器人(chatbots)和支持麦克风的设备(例如,扬声器、智能手机、平板电脑,个人电脑和汽车)。然而,数字网格有一系列不断扩展的端点,人们可通过这些端点访问应用程序和信息,或与他人。社交群体、政府和组织互动。随着设备网格的演变,连接模型将会扩展,设备之间出现更大的协作交互,为连续和环境数字新体验奠定基础。
现在已经有了成熟的方案,比如苹果的Siri,微软的Cortana、京东的小i,这类应用的共同特征是通过智能云服务,聊天机器人和个人助理成为对话媒介。甚至进入了婴幼儿产品市场,如腾讯的早教故事机米小兔,就是通过智能云服务来达到人工智能对话的。语音对系统界面很重要,越来越智能、越来越交互的语音接口,将是人机交互的首选方式。未来的交互方式是一种主动性对话,将进一步增强语音交互。主动式语音协助由用户位置等数据进行支持,将会在没有人机交互的情况下,也能够提供指导和管理。随着语义分析的加重,会话语音的价值会增加。语音分析能够理解用户服务记录和社交媒体的各类数据并进行推理。
网格应用和服务架构
在网格应用程序和服务架构(MASA)中,移动应用程序、网络应用程序、桌面应用程序和物联网应用程序链接到广泛的后端服务网络,创建被用户视为“应用程序”的内容。该架构封装服务,并在多级别和跨组织边界公开了API,从而平衡了服务的灵活性和可伸缩性的需求与服务的组合和重用。
网格使用户能够具有针对数字网格(例如,桌面、智能手机、汽车)中的目标端点的优化解决方案以及当他们在这些不同信道上切换时的连续体验。
这只是基于理想状态的市场竞争中设想的。现实是,在非理想的市场竞争中,专有基础架构数量并不占优,要实现所有的软硬件基础架构无缝集成并协同,难于上青天。
数字技术平台
数字技术平台为数字业务提供基本的构建模块,是数字业务的关键推动者。Gartner已经确定实现数字业务新功能和商业模式的五个要点:信息系统、客户体验、分析和智能、物联网和业务生态系统。 每个组织都将有这五个数字技术平台组合的平台。
可以理解为对话式AI驱动平台。
比如亚马逊的amazon echo+wink。物联网平台是解决方案成功的必要因素,现在微软Azure、ORACLE、Google、SAP等IT巨头都有涉足。惠顾上世纪60年代,是主机系统,到70年代就是微型计算机,80年代是PC和文件共享LAN,90年代是服务器和图形界面,1998~2007年是因特网和网络应用,2007~2016年是移动和云,未来,将是对话式AI和物联网。所有这些并非割裂,而是互相交织。未来会有越来越多的基础架构和应用程序融合,组织需要了解这种融合,对他们的竞争力、应变能力带来什么样的影响。
自适应安全架构
智能数字网格和相关的数字技术平台和应用程序架构创建了一个日益复杂的安全世界。 Cearley表示:“规定的安全技术应作为确保物联网平台的基准。监控用户和实体行为是物联网中特别必要的一个重要补充,然而,物联网边缘是许多IT安全专业人员产生薄弱领域的新前沿,因此经常需要新的补救工具和流程,建立物联网平台必须考虑这些因素。”
自适应安全架构能够实现持续分析用户和实体行为,如外部身份和威胁智能,包含审查、规则/评分;持续画像;持续分析和验证。但是通常业务端会滞后于技术端,而技术端又滞后于设备和应用端,还要对安全行业有一个正确的认识——本质就是响应机构,是以解决问题为目的,而不管这个问题出现有多久。 收起阅读 »
千人盛会——2016永洪科技用户大会
一、大会背景
大数据经济时代,数据分析支持企业决策,数据分析产品层出不穷,数据分析技术与行业应用渐成各行业追逐热点。在IT产业前沿北京,金融、制造、交通、能源、医疗、政企、越来越多的企业开始在大数据领域创造企业价值的创新与发展。
11月26日,永洪科技齐聚“政企学协资社用”生态七方,携一站式大数据分析平台产品及行业经典应用方案,力邀1000名各行大数据行业专家与来宾,共同探讨大数据的生态应用,一场史无前例的大数据峰会等待着您的莅临!
二、大会概况
峰会主题:“智慧运营 数造未来“——永洪科技•2016用户大会
峰会时间:2016年11月26日 9:00—18:00(周六)
峰会地点:北京千禧大酒店(北京市朝阳区东三环中路7号院5)
峰会规模:1000+人
峰会人群:
* CEO、CIO、 CMO、 BI、数据分析、数据挖掘、大数据平台等领域开发人员、技术经理和总监、数据分析爱好者等;
*制造、电商、零售、金融、互联网、电信、能源、交通、医疗、政企、渠道等各行业业务部门信息化负责人;
*IT服务商、渠道商、系统集成商、代理商等;
三、会议议程
四、会议亮点
趋势解读:大数据成为国家战略的今天,数据已然成为企业的无形资产,如何构建企业自己的一站式大数据平台,顶级行业专家将为您解读其中的奥秘。
新品发布:“从v1.0到v7.0,永洪科技的大数据分析平台到底实现了哪些创新和突破?“——十年磨一剑,永洪科技如何自主创新实现蜕变,且听创始人Henry娓娓道来。
尖峰对话:“这么多数据,我该如何挖掘其中的价值?数据化运营如何开始、如何构建体系架构... ...”灯不拨不亮,理不说不明,行业精英共同探讨如何实现数据驱动智慧企业。
同行取经:制造、金融、能源、交通、互联网、电商、政府、医疗等行业用户携现身说法,讲解自身痛点、解决方案及数据分析的应用价值,让你少走弯路少进坑。
五、报名方式
抢票链接:http://www.bagevent.com/event/267090
六、合作单位
主办:永洪科技•永洪数据科学研究院
协办:环信、中关村大数据产业联盟、首席数据官联盟、崔牛会、天善智能、CDA数据分析师、msup、爱数据网、数据分析网、数据猿、China Hadoop Summit、Bi168大数据社区、大数据人、segmentfault、ThoughtWorks、数董会、经管之家、PPV课;
媒体:IT168、CSDN、中国软件网、中国计算机报、SP计算机产品与流通、商业伙伴、计世传媒; 收起阅读 »
第四届互联网运营大会 - 数据驱动产品运营和社会化运营
大会时间:2016年11月27日 9:00 ~ 2016年11月27日 17:00
会议地点:上海浦东新区博云路2号浦软大厦
大会规模:600人
报名链接:http://www.huodongxing.com/event/9359909288600
数据驱动产品运营和社会化运营
8位重磅嘉宾分享互联网运营经验和方法!
由中国最大的产品经理社群PMCamp和汇智Tek联合主办的第四届中国互联网运营大会((IOCon2016)将于2016年11月25日-27日在上海浦软大厦举行。
本届大会主题为: “数据驱动产品运营和社会化运营”。大会将邀请来自互联网、传统行业、服务业、新型创新企业的CEO、COO/产品副总裁/产品总监/产品经理、运营副总裁/运营总监/运营经理,创业者等,围绕大变革时代的各种机会和问题,探讨产品商业模式、产品运营、数据分析、社交媒体运营、社会化运营、游戏化设计和运营,提供产品运营的道、术、器等内容分享,为一切关注产品创新、产品运营、互联网创业者搭建一个学习交流、思想碰撞的干货分享平台。
自2010年起,PMCamp已经举办过六届产品经理大会,三届互联网运营大会、两届数字营销大会、五届人本设计大会,以及近百场的产品经理工作坊、设计工作坊、产品经理沙龙等线下聚会活动。正在筹办互联网产品增长大会。5年来,已经有超过10万人关注PMCamp,1万多人参加过PMCamp的活动,600家企业代表参加过PMCamp组织的活动
演讲嘉宾
子墨
前阿里巴巴运营专家,
Convertlab 联合创始人,多准数据CIO
子墨,前阿里巴巴运营专家,新零售人社群创始人,独立传统行业转型互联网实战顾问,浙江大学、上海交大、淘宝大学授课嘉宾; Convertlab 联合创始人;多准数据CIO;新零售人社群创始人;老阿里茶馆/漫私塾咖啡创始人;
曾在微软金融事业部从事IT服务顾问、在阿里巴巴五年,是淘宝礼物创始人,阿里旺旺卖家版.运营专家。曾作为 SAP、有赞、商伴等软件公司资深业务顾问,以及TCL、安奈儿、平安集团、等企业互联网业务顾问。
演讲主题:新零售之全渠道用户运营解析
主题简介;传统行业如何玩转线上?电商行业如何拥抱线下?线上线下的融合不只是是1+1,而是在底层“数据”结合的基础上围绕“消费者价值”做改造,表现出来就是全渠道用户运营。
路盛华
沪江高级运营总监
前盛大创新院多产品运营负责人
路盛华,沪江高级运营总监,对商业市场有浓厚兴趣,熟悉IT和互联网领域,擅长市场运营及营销管理。
曾就职于韩寒投资的去动网络科技有限公司,担任「去动」&「Fit」APP 的市场运营总负责人。曾在盛大创新院担任Bambook电子书合作推广部门负责人,负责Bambook的市场合作、渠道拓展、媒体公关、销售、运营等工作。后期在麦库记事担任产品运营负责人。
曾供职于CBSi中国(哥伦比亚广播公司)传媒集团,担任业务群组总监。期间策划主持过大型互动活动和产业发展高峰论坛。
演讲主题:运赢 :透析数据做最有效的产品运营
主题简介:数据是产品运营工作的基础,也是产品运营的目的。如何透彻的设计和分析数据,是决定成败的关键因素。
杨文雅(特工先生)
淘宝大学明星讲师,天猫国际专家顾问
杨文雅(特工先生),淘宝大学明星讲师,天猫国际专家顾问。上海飞域网络科技有限公司/上海天媒实业有限公司 总经理。电商行业实操八年以上经验,知名电商讲师,培训授课超过10万人次。擅长无线端运营、互动营销、移动电商操盘。2015年度淘宝大学最高奖项春蚕丝语奖(全国仅10人)、鲁班奖(全国仅2人)获得者。受邀给美国梅西百货、日本富士拍立得、苏泊尔、春水堂、361度等几十个大型企业、几千名各地政府领导讲课。
他也是天猫黄金台诊断高级专家,阿里数据学院认证讲师,阿里巴巴商学院出版《电商运营》书籍作者,编写组组长,百年天猫2015年双11千里马导师。
演讲主题:《电商运营新思维》
主题介绍:1.无线端趋势 2.消费结构升级带来的电商机会 3.场景化营销 4.以未来为因的运营思维
曾艳琦
洋码头高级运营总监
前腾讯QQ市场总监
曾艳琦,洋码头高级运营总监。前腾讯手机QQ市场总监,前盛大创新院研究员,曾在11年试水移动互联网社交创业,和团队一起做了国内最早的私密社交app–“时光流”。十年互联网经验,09年进入移动互联网,尤其擅长社交类移动互联网产品。
主要工作经历:
腾讯—QQ:负责手机QQ、QQ开放平台项目QQ互联、QQ商业化项目腾讯课堂、兴趣部落、QQ群
创业-时光流:中国的私密社交应用,主打照片分享,11年-12年在中国照片类应用中市场占有率排第五;
盛大:盛大网盘everbox和中国最早的LBS社交产品盛大切客客户端;
洪弘 (花名红利)
挖财理财运营总监
洪弘 ,挖财理财运营总监,花名红利。主要负责挖财理财的用户运营、数据运营、品牌运营、内容运营、活动运营、金融产品运营等多个团队。在用户精准营销、用户教育、转化率运营、创新产品孵化、金融产品营销等方面有丰富的经验。
黄捷
携程国际业务事业单位运营经理
黄捷,携程国际业务事业单位运营经理,负责产品供应产品转化用户运营数据分析工作。
演讲主题:漏斗图的两个实际工作案例
主题简介:数据运营最常用的漏斗图,基础虽然简单,应用方式很多样。介绍两个中阶的应用案例,一是时序图辅助横截面漏斗图,适用于跟踪事件节假日发布活动的影响,寻找改进机会和评估改版效果,二是客户群分漏斗图,国际化网站可以通过不同地域语种划分方式,漏斗图对比找特征和流失点,这种模式也可以扩展到更多用户属性的ab测试,普适性很强。
王小毅
浙大管理学院市场营销学系副主任、副教授、博士生导师
浙大管理学院市场营销学系副主任、副教授、博士生导师,中国管理科学与工程学会副秘书长,国际知名的脑神经营销专家,研究领域为互联网商业模式,移动和在线消费心理。
培训课程:“新媒体运营和内容运营”
培训简介:
- 微信公众号运营方法论和技巧
- 新媒体运营
- 平台内容运营策略
- 内容运营方法论。
陈世欣
昭合投资合伙人
前美国Movoto中国总经理
陈世欣,昭合投资合伙人,InnoSpace特聘创业导师,前美国Movoto.com中国总经理,互联网社群专家,具有10多年的增长黑客经验,3年以上用游戏化思维运营社群和组织大会经验,曾经为4家互联网企业实现高速增长。他从1999起参与多家互联网创业公司,历任任安家网副总经理、movoto.com中国公司总经理、和家网CTO、2Style4You公司CTO、永泰红磡养老产业集团战略研究总监、创猿投资董事合伙人等;
曾作为平安大学、苏宁大学、中国移动、中国银联、中国电信、复旦大学MBA教研组、众戴金融等机构内训讲师。
培训课程:“如何炼成增长黑客,如何获取用户、促活和转化价值”
培训简介:介绍增长黑客的基础和体系,系统化提出做增长的100个方法和案例,引导分组练习获取用户、促活和转化价值。
刘振华
原笔记侠运营总监,新周刊特约编辑,单篇百万+作者
刘振华,原笔记侠运营总监,新周刊特约编辑,写作过单篇100W+阅读量原创文章。对知识类内容付费有深入研究。个人微信公众号有一定业界影响力。
培训课程:“社群运营和价值变现”
培训简介:
如何运营好社区和价值变现
如何策划和引爆一场活动
培训课程
11月25日-26日:“硅谷堂”首席运营官训练营三期
地址:上海静安区南京西路1376号上海商场曼彻斯特大学中国中心
11月25日:
09:00 ~ 12:00 《如何炼成增长黑客》,《如何获取用户、促活和转化价值》陈世欣 昭合投资合伙人,前美国Movoto中国总经理
13:30 ~ 17:00 《微信公众号运营方法论和技巧》,《新媒体运营》王小毅 浙大管理学院市场营销学系副主任、副教授、博士生导师
11月26日:
09:00 ~ 12:00 《平台内容运营策略》,《内容运营方法论》王小毅 浙大管理学院市场营销学系副主任、副教授、博士生导师
13:30 ~ 17:00 《如何运营好社区和价值变现》,《如何策划和引爆一场活动》刘振华 原笔记侠运营总监,新周刊特约编辑,单篇百万+作者
12月10日 ~ 11日: " 互联网人的数据运营实践培训课"
地点:全季酒店新天地店
12月10日:
09:00 ~ 12:00 《数据驱动渠道优化》 安琦,携程无线营销产品负责人
13:30 ~ 17:00《数据驱动设计优化》 陈抒,上汽车享网UED总监
12月11日:
09:00 ~ 12:00 《互联网数据分析师的成长之路》纪杨,Teambition数据分析负责人
13:30 ~ 17:00 《产品运营的数据事件分析实务》黄捷,携程国际多语言网站及APP运营负责人
大会议程
全天共有8个演讲,1个互动论坛,1次午餐,2次茶歇
上午日程
08:20 - 09:00 签到
09:00 - 09:20 开场演讲和日程介绍 大会主持人
09:20 - 10:05 演讲1 《新零售之全渠道用户运营解析》前阿里巴巴运营专家,Convertlab 联合创始人,多准数据CIO 子墨
10:05 - 10:50 演讲2 洋码头 高级运营总监 曾艳琦
10:50 - 11:00 茶歇
11:00 - 11:50 演讲3 《电商运营新思维》杨文雅(特工先生),淘宝大学明星讲师,天猫国际专家顾问
11:50 - 12:00 演讲4 《漏斗图的两个实际工作案例 》黄捷,携程国际多语言网站及APP运营负责人
12:00 - 13:00 午餐
下午日程
13:00 - 13:45 演讲5 《数据化运营与用户生命周期管理》洪弘 (花名红利),挖财理财运营总监
13:45 - 14:30 演讲6 《运赢:透析数据做最有效的产品运营》路盛华,沪江高级运营总监,前盛大创新院多产品运营负责人
14:30 - 14:45 茶歇
14:45 - 15:30 演讲7 《游戏化产品设计和运营》,陈世欣 昭合投资合伙人,前美国Movoto中国总经理
15:30 - 16:15 演讲8 确认中
16:15 - 16:55 全场嘉宾 Q&A 互动环节
16:55 - 17:00 合影、抽奖
注意:大会议程将根据当天实际情况进行轻微调整,最终解释权归主办方所有。
购票政策
折扣票购买方式、范围、期限
1. 购买“互联网运营大会”参会票
在11月01日-11月11日期间 以199元购早鸟票
在11月11日-11月20日期间 以299元购特惠票
在11月21日-11月27日期间 以399元购普通票
2. 购买“硅谷堂首席运营官训练营”培训票
全价票:2299元/人
早鸟价:早起的鸟儿有虫吃,立刻报名享受早鸟价1999元
(仅限30席,截止日期:11月11日)
三人团购价:三人行5097(1699×3)一起学起
(费用包含课程资料费、场地费用、结业证书以及两餐午餐、课间茶歇)
注:本培训由“硅谷堂”组织,PMCamp协办。
收起阅读 »
盘点10款逆天级效率工具,能帮创业公司节省50%时间成本
在当今移动互联网创业环境里,好的创业项目在半年至一年时间里应该可以拿到A轮了。既然你是一个创业公司,要么快速“干”起来,要么赶紧去“死”,半死不活的运行着浪费公司所有人的时间,毕竟时间是创业最大的敌人。
越来越多的公司和个人也开始愈加注重效率的提升。工欲善其事,必先利其器。现在就结合互联网创业公司的实际工作场景和需求,给大家分享一些能大大提高工作效率的工具神器,这些工具能从梳理工作思路、团队协作、产品原型图设计、数据统计分析、销售与客服等各方面提高创业公司的工作效率,降低运营成本。
一、梳理工作思路,思维导图工具助你一臂之力
在日常工作中,我们经常需要梳理和展示自己的工作思路和规划,或是向领导汇报,或是向同事展示,亦或是仅供自己查看。借助思维导图工具不仅可以更高效地进行梳理,同时还能将自己的思路规划更清晰美观地展示出来。平时用得比较多且感觉不错的的思维导图工具主要有两款,MindManager和XMind。百度脑图也曾用过,但最终因为产品体验问题而不得不忍心放弃。
先介绍下MindManager。不管是梳理运营策略、做项目管理还是开展头脑风暴,都可以在MindManager上高效完成。在MindManager上,你可以在单一视图里将想法和灵感以清晰的思维导图形式记录并展示出来。它的时间轴布局功能可帮你清楚展示产品路线图、项目里程碑或是营销发布计划。此外,你还可以利用它提供的图像库在导图里添加丰富的视觉效果。
MindManager产品官网:http://www.mindmanager.cc/
再分享一下XMind这款产品。XMind产品外观整体比较清新简洁,对其他格式兼容性较好,提供甘特图、矩阵图等多种结构。XMind以画布概念管理,方便思维导图的层次化。XMind可以导入MindManager、FreeMind数据里面的文件,也可以将文件导出为Word、PPT、PDF、图片和TXT等格式的文件,以便将用XMind绘制的图与他人轻松共享。
XMind产品官网:http://www.xmindchina.net/
上面两款思维导图工具都非常不错,如果你需要一款思维导图工具来协助自己工作的话,不妨直接在上面两款工具中选择一款。
二、团队高效协作是降低时间成本的有力保证
创业公司员工规模相对较少,理论上应该比较容易沟通和协作。有需要沟通协作或是需要什么东西,直接当面沟通或是在面积不大的办公室大喊一声就能搞定。然而,如果在创业公司工作一段时间,你便会发现,创业公司内部要想实现真正的高效协作其实并非易事。
大公司协作有大公司协作的繁琐,创业团队协作有创业团队协作的痛点。下面就结合创业公司的三种不同协作需求推荐三款不同类型的协作工具。
团队文档协作工具:WPS云文档
文案校稿时,经常需要为往返发送稿件和上传下载而苦恼;企业资料混乱存于各处,需要时找不到;办公资料全在公司电脑里,无法随时随地办公。如果你也在为这些问题苦恼,说明你还没有找到合适的工具。
WPS云文档是一个企业文档存储、共享与协作平台,支持多人同时编辑一个文档、文档内评论和历史还原等众多便捷功能。不管你在任何时间、任何地点、使用任何设备,只要打开云文档就能处理工作文件。不管是产品研发、市场运营和人力行政人员,都可以在WPS云文档上便捷地进行文档的协作、存储与共享。WPS云文档有企业级管理后台,可管控所有企业成员和文档的权限。此外,WPS云文档还提供WPS Office全套办公组件,大家在一个平台上就能搞定所有工作。
WPS云文档产品官网:https://drive.wps.cn/
想用一个工具就解决工作中的所有沟通问题,试试零信
工作中用的软件太多太乱,通知信息到处都是。这时你可能也会希望有一款一站式的企业内部沟通平台。如果你有这个需求,零信或许是一个不错的选择。
零信的是一款便于整合信息的企业IM产品。你在零信这一个平台上就能处理基本所有工作信息,让大家更专注地工作,目前支持群聊、私聊、应用接入、文件管理、视频会议等。它还支持企业自定义开发,一行代码就能搞定。零信已整合邮件、任务管理、文件管理、客服支持、代码开发等60多种应用。
零信产品官网:https://pubu.im/
三、改善客服、优化销售管理流程,这两款工具值得一试
无论哪一家创业公司,产品做出来之后,不管是做客服还是做销售,都需要和客户打交道。这样才能更好地了解用户的需求,并从用户那里获得收入以求生存。为更高效地为客户提供客服服务,同时优化销售管理流程,这当然离不开专业的销售和客服类工具的支持。
销售易CRM
销售易CRM是销售管理类工具中非常不错的一款,它以销售管理为核心,基于销售管理全流程,结合合作伙伴管理、市场与客户服务管理,可以为客户提供灵活的配置机制,帮助企业数字化销售管理,提升团队业绩和效率。销售易CRM,已实现SaaS和PaaS的无缝整合,可快速响应客户个性化、定制化的业务诉求,支持不同规模企业的销售流程。
销售易CRM产品官网:http://www.xiaoshouyi.com/
环信移动客服
传统的客服工具已经无法满足移动互联网时代的需求了。这是个移动的时代,客户无处不在,客服工作极大的需要移动化和全平台化的支持。2016年双11天猫突破1111亿,其中移动端占比高达82.04%,这也是为什么在这里推荐环信移动客服的原因所在。环信移动客服支持全媒体接入,包括网页端、社交媒体客服(微博、微信)、APP内置客服和呼叫中心等多种渠道接入。全媒体客服已是大势所趋,全媒体客服核心在于移动端接入,而移动端正是环信的核心技术优势所在。
环信国内首创基于人工智能和大数据挖掘的客户行为透析产品"客户声音"可以通过自然语言解析,主题聚类,情感度分析等技术手段挖掘和分析热点话题,发现畅销或问题商品,同时分析发现服务运营中存在的问题,企业就此可以优化运营,利用大数据洞察力来发现销售机会,改善产品质量。
基于自然语言处理和机器学习技术的环信智能客服机器人,能够辅助或代替人工客服精准回答常见或高频问题,能解答80%常见问题,极大降低企业客服人力成本。目前,环信在客服领域已经服务了三万多家标杆客户,积累了人工智能在客户服务行业落地的大量最佳实践。典型用户包括国美在线、58到家、楚楚街、海尔、神州专车、新东方、链家自如客、泰康在线等众多标杆企业。
环信移动客服产品官网:http://www.easemob.com
四、做产品原型设计,这些工具肯定能满足你的需求
互联网创业公司基本都会用到产品原型设计工具。大家其实对原型有着不一样的需求,有些公司注重产品的原型版本管理,有些注重原型的交互和PRD需求文档,所以下面分享三款各具特色的产品原型设计工具,墨刀、Axure RP和Balsamiq Mockups,能够很大程度上让迭代速度上一个门槛。
首先介绍下MockingBot墨刀
凭借“十分钟设计一个 App”的易用性,墨刀已经成为产品经理界非常流行的一款原型协作工具,受到知乎和爱范儿的强烈推荐。
你一定有着这样头疼的场景,导出原型后要么需要详细的文档,要么就需要非常多的沟通,和其他同事共同制作时更是频繁返工。而墨刀恰巧可以解决从原型制作-交互动效-团队协同作业-实时分析查看效果-跟踪团队及用户反馈整个产品开发流程中大部分让你挠墙的问题。
使用墨刀完成设计后,可以直接对功能进行备注及说明,简单有效。把同事拉进你的项目,就可以看到协同者的操作进程和改动细节,更好的协作和分享信息。实时的扫一扫查看,不光可以检查制作效果,更可以把原型的交互效果发送给团队和用户内测征集意见。用户可以用打点评论的方式告诉制作者他的真实感受。大大降低了产品的开发试错成本。
墨刀是一个国内的团队开发制作的产品,因此比较符合国内互联网公司的使用习惯。
墨刀产品官网:https://modao.cc/
再说说Axure RP
如果产品经理对产品原型、交互演示、原型细节设计等的需求比较强烈,Axure RP是非常不错的选择。Axure RP 能让产品经理快速创建应用软件和基于Web的的线框图、流程图、原型页面、交互页面和规格说明文档。Axure RP应该是目前产品经理群体中用得最广泛的一款原型设计工具。
五、要做到数据驱动,离不开数据分析产品的支持
对于互联网创业公司来说,因为人力和资源都非常有限,无法承受起将时间和资源浪费在没有成效的工作上,因此理想的方式是所有工作都能做到数据驱动,让数据决定该将时间精力用在什么地方。目前市面上有很多现成的数据分析产品,但并非有了数据分析产品就一定能做到数据驱动决策,如果没有更好的数据分析方法论的指导,即使有产品也未必能真正实现增长。
相较于市面上其它数据分析产品,GrowingIO背后有强大的数据分析团队,能为客户提供数据驱动增长方面的理论支持。GrowingIO是一款拥有谷歌基因的数据分析产品,因为公司创始团队基本都是来自硅谷的数据分析大牛。这款数据分析产品的最大亮点在于不需要开发人员埋点,就可以采集全量、实时的用户行为数据,不管是对管理者、产品经理、市场运营、数据分析师还是增长黑客,GrowingIO都能帮助他们实现更精细化地数据分析,从而优化产品、提升转化率,实现用户的快速增长和变现。
GrowingIO产品官网:https://www.growingio.com/
六、无处不在的表单设计和数据收集需求,用金数据就够了
创业公司无论是做用户与市场调研、收集意见反馈、在线投票,还是做活动报名和在线预约等,这都需要用到表单设计和数据收集工具。金数据是一款非常适合中小创业公司使用的表单设计与数据收集工具。金数据的操作非常简单,功能比较齐全,你只需通过像搭积木般的简单拖拽即可创建出好看实用的表单,高效完成数据收集工作。凡是需要表单设计和数据收集的场景,都可以借助金数据快速完成。
金数据产品官网:https://jinshuju.net/
其实能提高创业公司工作效率的工具还有很多,我在本文中只推荐了一些自己及身边同事用过且感觉不错的工具。最后还是文章开头时那句话:要么快速“干”起来,要么赶紧去死。巧用效率工具可以帮助创业公司最大限度节约时间成本,提高创业成功的概率。希望大家在工作中都能选对工具,在节省时间成本的同时,早日拿到A轮、B轮或C轮融资,甚至上市。
收起阅读 »
从APP内直跳另一APP内容页┃Deep Linking技术探究沙龙┃11月19日(周六) 中关村方正国际大厦6楼北大孵化器
现在Deep Linking技术将改变这一现状,实现从APP内直接跳转到另一APP的指定内容页;
这周六,我们准备了一场技术沙龙,为你解答有关Deep Linking技术的方方面面:从Deep Linking的历史,Deep Linking 的具体形态;到Deep Linking实现原理及技术体系立体解析等等。
现邀请渴望打破app孤岛的你,一起来探究!
基本信息:
LinkedME技术沙龙第一期:Deep Linking技术探究
11月19日 中关村方正国际大厦6楼北大孵化器
13:30~14:00签到
14:00~17:00分享
分享嘉宾:
齐 坡|LinkedMECEO,清华信息技术研究院硕士,曾于新浪微博任算法工程师 擅长大数据架构,网络安全;
王仁阳|系统架构师,北京邮电大学硕士,前新浪微博Feed项目的核心开发者,具有丰富的大型互联网项目的架构经验。
徐 斌|移动研发工程师,前腾信创ios工程师和Android工程师,5年移动端研发经验,熟练掌握Android及iOS研发
郭亚伦|她理财移动开发经理,前任职搜狐新闻客户端
活动日程:
13:30
签到
14:00~14:40
打通移动互联世界——Deep Linking技术的前世今生
齐坡
14:40~15:20
Deep Linking实现原理及技术体系立体解析
王仁阳
15:20~16:00
Deep Linking在移动应用开发中的实践
郭亚伦
16:00~16:40 场景和Deep Linking应用新玩法 徐斌
16:40~17:00 Q&A+抽奖
参与沙龙,并将获得:Deep Linking技术白皮书
我要报名:http://www.huodongxing.com/event/1358649997400 收起阅读 »
Android ios V3.2.1 SDK 已发布,发起电话支持自定义内容
Android V3.2.1 2016-11-12
新功能/优化:
- 聊天室列表支持分页获取
- 发起电话的接口增加ext参数,方便用户自定义内容
- EMOption中增加setUseHttps()的接口
- 优化会话加载的速度
- 修复使用视音频后可能导致手机外放没有声音的bug
- 修复发送消息后马上删除附件可能导致手机crash的bug
- 修复音视频呼叫在某些魅蓝手机上会卡死的bug
- 修复demo中呼叫时没有铃声的bug
- 修复了视频通话时使用后置摄像头时图像显示不正确的bug
- 聊天室列表支持分页获取
- 发起电话的接口增加ext参数,方便用户自定义内容
- EMOption中usingHttps默认为YES
- 修复Lite版本SDK编译warning的问题
版本历史:Android SDK更新日志 ios SDK更新日志
下载地址:SDK下载 收起阅读 »
环信CEO刘俊彦:SaaS领域一定能诞生千亿市值的科技巨头
提到客服这个词,人们第一印象可能是雪白衬衣、黑亮西服,甜美声线,端庄大方的业务员耐心接听电话的情景。没错,这是典型的人工客服场景,但随着信息技术不断发展,客服内涵更加丰富,文字、语音、视频以及人工智能开始结合,客服已经成为一项重要的企业服务内容,催生出新的产业市场。
环信就是客服产业中的一份子,从2013年成立到去年拿到1250万美元融资,随着市场潜力不断被释放,环信业绩也大幅增长,根据易观智库的数据显示去年环信已占据国内SaaS移动端客服市场77.4%的份额,在市场竞争中取得了不俗表现,但在新技术不断转化落地,竞争日益激烈的大环境下,如何让企业跑得更快,怎样更好地理解市场,行业天花板在哪里,作为客服领域参与者和受益者,环信CEO刘俊彦给出了他的理解。
亿欧:企业级服务赛道很多,为什么选择客服这个领域呢?
刘俊彦:企业服务可以分为5个核心赛道, 协同办公、CRM、客服、人力资源和财务 ,选择从客服切入首先是因为我们对这个行业了解,有过多年相关产品的开发经验,其次从市场角度来看,无论是北美市场还是目前的国内市场,客服的市场规模最大,仅国内在线服务和电话服务两个细分市场就已达到300亿元规模,像京东、阿里、苹果都在客服项目投入了巨大资源,从人员培训到系统的购买等,所以这是一项成本中心,是企业与客户沟通的第一窗口。
从其他赛道来看,协同办公是基础性战略服务,是腾讯、阿里这样巨头的必争领域,这个领域竞争很激烈;客服是CRM中占比最大的服务内容,综合性CRM企业有纷享销客、销售易和红圈营销等;人力资源领域有北森,也是一块大市场;财务方向主要是传统IT企业例如金蝶、用友等公司。环信选择在客服深耕是从主观和客观两个维度来判断,我看好这个赛道。
亿欧:很多客服公司都希望做中国的Zendesk,而您希望企业能有更大格局,能成为salesforce、微软和甲骨文这一类综合性公司,关于行业天花板您怎么看?
刘俊彦:与美国相比,中国企业面临着难得机遇,眼光应该看得更远,只要把握机会,成为一家百亿美元市值的综合性软件巨头是很有希望的。
中美两国市场环境是不同的,Zendesk在美国还不是最大客服企业,占据第一阶梯的仍然是巨头,去年salesforce的客服云收入大概是19.6亿美元,而Zendesk是2亿美元左右,双方差距近10倍,所以巨头在各个行业保持强势地位,让新型企业难以立足。其他巨头例如微软、甲骨文也有自己的客服云系统,主要服务面向客单价在几十万到几百万的大型企业,所以整体来看美国客服市场是巨头的竞技场,小型服务商机会渺茫。
而在国内由于云服务落地受到限制,国外巨头不得不和中国企业合作共建数据中心,造成了市场空白,这给本土企业 休养生息并不断发展壮大自己赢得了时间。另一方面国内中小型企业发展迅速,付费意识和能力逐渐增强,进一步扩大了市场空间,延长了赛道深度。更重要的因素是国内在各个赛道都没有形成像美国一样强大的巨无霸企业,竞争状态相对平行,群雄逐鹿的程中,第一阶梯的企业都有机会成为巨头。
亿欧:您说过环信有两场仗要打,一是客服赛道另一个是综合性软件,您认为打赢这两场仗的核心是什么,环信所处的阶段又是怎样的呢?
刘俊彦:因为有大机遇所以有更强的愿景,站在行业发展方向来看,企业成长路径从确定方向再到逐步成长为该领域的小巨头,最后跨赛道边界,跻身综合性企业行列,这个过程就是环信将要面对的,目前我们处在第二阶段,这也是时间上最漫长,洗牌压力最大的阶段,走好就能化蛹成蝶,走不好就只能被淘汰。
如果想在局部赛道和整个航道上打胜仗, 最关键就是产品和销售。
销售要做好服务,让客户实现价值;产品是核心竞争力,是服务基础,在两者之上是资金投入,在资本推动下能实现快速成长,以往的软件公司靠自我造血进行研发,但在SaaS领域初期投入非常巨大,资金不足、产品化速度太慢,很难把握市场机遇,所以做好产品和销售再加上资本催化,SaaS企业就能突破局部赛道藩篱实现大航道方向地起飞。
亿欧:环信在产品体系上有什么亮点吗?
刘俊彦: 第一个亮点是客服移动化。 移动互联网时代,单靠PC端并不能满足客户需求,客户更多会从手机端访问页面,这是共性趋势,但环信更强调移动端客户体验,保证产品舒适性。
第二个亮点是全媒体客服。社交渠道多元化和应用软件功能的丰富让全媒体客服成为客户新需求,微信公众号、微博、网页、电话等渠道的用户访问都能提供客服支持,同时数据可以统一记录并管理,以便更好服务用户。
第三个亮点是客服智能化。对于企业来讲客服既是成本中心也是获客窗口,如何压缩成本,扩大获客能力,是人工智能的重要应用方向。一般客服场景中很多对话具有重复性、结构化特点,通过人工智能方式能够代替前端基础信息的交互,能节省大量人力成本,同时赋能客服人员以更大专业性,进而提升服务水平。对于有多轮会话需求的企业,我们也会提供定制化服务,以满足不同层次业务需求,但目前多轮会话受会话场景影响,比如噪音问题等,在技术上还有待突破。
第四个亮点是客服营销化。通过客服这个窗口进行用户画像的描绘、有针对性采取互动营销手段,构筑完整闭环,打通服务链条,多维度布局产品,提供“从进到出”的全周期服务体验。
亿欧:续约率是SaaS企业的盈利命门,环信在这方面有什么措施?
刘俊彦:续约率高低体现了销售服务的好坏,我们在售出一套产品后并不是甩手不管而是有专业团队来帮助客户用好产品,根据反馈和意见来提升客户手中的产品价值。为了帮助客户在实践中提升产品使用效能,环信成立了客户成功与交付部,将服务从交付延伸到下次续约,实现全周期跟踪服务,从而保证续约率。 收起阅读 »
先定一个小目标,比如写一个QQ
本项目是即时通讯的示例项目,使用了MVP模式,集成了环信SDK和Bmob后端云,展示了即时通讯基本功能的实现,包括注册登录,退出登录,联系人列表,添加好友,删除好友,收发消息,消息提醒等功能。
使用的开源项目
学习目标
- 环信SDK的集成与使用
- MVP模式的运用
- ORM数据库的集成与使用
- 模块化思想的运用
允许两人或多人使用网络即时的传递文字讯息、档案、语音与视频交流。相关产品
- 鼻祖 ICQ
- 国内主流 QQ 微信 陌陌 YY等
- 国外主流 Facebook Messenger WhatsApp Skype Instagram Line
环信集成[list=1]
android { sourceSets { main { jniLibs.srcDirs = ['libs'] } } }
注意事项运行出错:Didn't find class "com.hyphenate.chat.adapter.EMACallSession",原因是hyphenatechat_3.2.0.jar包内没有该类。解决办法:导入Demo源码中EaseUI库里面的hyphenatechat_3.2.0.jar替换。软件架构MVCMVC应用于Ruby on Rails, Spring Framework, iOS开发和 ASP.NET等。- Model: 获取数据的业务逻辑,网络操作,数据库操作
- View: UI
- Controller: 操作Model层获取数据传递给UI
服务器端的MVC
Android中MVCAndroid中并没有清晰的MVC框架,如果把Activity当做Controller,根据我们实际开发经验,里面会有大量的UI操作,所以V和C就傻傻分不清了。
- Model:Java Bean, NetworkManager, DataBaseHelper
- View: xml res
- Controller: Activity Fragment
- ArrayList-ListView-Adapter(MVC)
- Model: 获取数据的业务逻辑,网络操作,数据库操作
- View: UI
- Presenter: 操作Model层获取数据传递给UI
MVVMMVVM主要应用于WPF, Silverlight, Caliburn, nRoute等。[list=1]
Android中MVVM 软件架构的核心思想
分层分模块
参考
- MVC,MVP和MVVM模式如何选择
- 教你认清MVC,MVP和MVVM
- android architectureUnderstanding MVC, MVP and MVVM Design Patterns
- Android Data Binding
- Clean Architecture
- adapter 存放适配器
- app 存放常量类,Application类以及一些app层级的全局类
- database 数据库相关类
- event EventBus使用的事件类
- factory 工厂类
- model 数据模型
- presenter MVP模型中的Presenter类
- ui 存放activity和fragment
- utils 工具类
- view MVP模型中的View类
- widget 自定义控件
- BaseActivity
- BaseFragment
- SplashView
- SplashPresenter
@Overridepublic void checkLoginStatus() { if (EMClient.getInstance().isLoggedInBefore() && EMClient.getInstance().isConnected()) { mSplashView.onLoggedIn(); } else { mSplashView.onNotLogin(); }}登录界面功能需求[list=1]
- LoginView
- LoginPresenter
android:imeOptions="actionNext"//下一个android:imeOptions="actionGo"//启动android:imeOptions="actionDone"//完成android:imeOptions="actionPrevious"//上一个android:imeOptions="actionSearch"//搜索android:imeOptions="actionSend"//发送监听软键盘Action事件,发起登录
private TextView.OnEditorActionListener mOnEditorActionListener = new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_GO) { startLogin(); return true; } return false; }};EMCallBack的适配器 EMCallBack是环信的一个请求回调接口,包括请求成功的回调onSuccess,请求失败的回调onError和请求进度回调onProgress,但在实际使用过程中,通常只使用到请求成功和失败的回调,请求进度回调通常留在那里成了一个空方法,对于一个有代码洁癖的搬砖师来说,这是很难受的。所以我们可以创建一个适配器类实现这个接口,使用时用适配器类来替换EMCallBack接口,这样只需要覆写我们想覆写的方法就可以了。
//EMCallBack接口的适配器public class EMCallBackAdapter implements EMCallBack{ @Override public void onSuccess() { } @Override public void onError(int i, String s) { } @Override public void onProgress(int i, String s) { }}//EMCallBack适配器的使用private EMCallBackAdapter mEMCallBack = new EMCallBackAdapter() { @Override public void onSuccess() { ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mLoginView.onLoginSuccess(); } }); } @Override public void onError(int i, String s) { ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mLoginView.onLoginFailed(); } }); }};Android6.0动态权限管理
Andrioid6.0对权限进行了分组,涉及到用户敏感信息的权限只能动态的去获取。当应用的targetSdkVersion小于23时,会默认采用以前的权限管理机制,当targetSdkVersion大于等于23时并且运行在Andorid6.0系统上,它才会采用这套新的权限管理机制。参考 动态获取写磁盘权限环信SDK内部维护了一个数据库来存储聊天记录等数据,需要读写磁盘的权限,所以我们在用户登录之前要申请该权限。类似的,很多同学在集成百度地图或者高德地图时常常不能正常定位,往往是忽略了在Android6.0上需要获取位置的权限。
/** * 是否有写磁盘权限 */private boolean hasWriteExternalStoragePermission() { int result = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE); return result == PermissionChecker.PERMISSION_GRANTED;}/** * 申请权限 */private void applyPermission() { String permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE}; ActivityCompat.requestPermissions(this, permissions, REQUEST_WRITE_EXTERNAL_STORAGE);}/** * 申请权限回调 */@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) { switch (requestCode) { case REQUEST_WRITE_EXTERNAL_STORAGE: if (grantResults[0] == PermissionChecker.PERMISSION_GRANTED) { login(); } else { toast(getString(R.string.not_get_permission)); } break; }}
注册界面功能需求[list=1]
- RegisterView
- RegisterPresenter
private static final String USER_NAME_REGEX = "^[a-zA-Z]\\w{2,19}$";//用户名的正则表达式private static final String PASSWORD_REGEX = "^[0-9]{3,20}$";//密码的正则表达式
- ^ 匹配输入字符串的开始位置
- [a-zA-Z] 字符范围。匹配指定范围内的任意字符。
- \w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
- $ 匹配输入字符串的结束位置
云数据库 Bmob集成Bmob开发文档
- 注册创建应用
- 下载SDK
- 导入SDK
- 初始化SDk
protected void hideSoftKeyboard() { if (mInputMethodManager == null) { mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); } mInputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);}注册用户到BmobBmob用户管理
private void registerBmob(final String userName, final String pwd) { User user = new User(userName, pwd); user.signUp(new SaveListener注册到环信() { @Override public void done(User user, BmobException e) { if (e == null) { registerEaseMob(userName, pwd); } else { notifyRegisterFailed(e); } } });}
private void registerEaseMob(final String userName, final String pwd) { ThreadUtils.runOnBackgroundThread(new Runnable() { @Override public void run() { try { EMClient.getInstance().createAccount(userName, pwd); ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mRegisterView.onRegisterSuccess(); } }); } catch (HyphenateException e) { e.printStackTrace(); ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mRegisterView.onRegisterError(); } }); } } });}用户名已注册的处理当我们注册一个用户名到Bmob云数据库后,使用相同的用户名再次注册,Bmob会返回错误码202,信息为username '%s' already taken。所以我们应该处理该错误,通知用户换一个用户名注册。Bmob错误码
private void notifyRegisterFailed(BmobException e) { if (e.getErrorCode() == Constant.ErrorCode.USER_ALREADY_EXIST) { mRegisterView.onResisterUserExist(); } else { mRegisterView.onRegisterError(); }}主界面
底部导航条 主界面底部是一个Tab导航条,实现的方法可以有很多种,我们可以使用RadioGroup或者FragmentTabHost, 或者我们可以自定义一个控件,为了不重复造轮子,本Demo使用了第三方导航条BottomBar。BottomBar的使用请参考其Github地址。第三方导航条Fragment的切换
private OnTabSelectListener mOnTabSelectListener = new OnTabSelectListener() { @Override public void onTabSelected(@IdRes int tabId) { FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction(); fragmentTransaction.replace(R.id.fragment_container, FragmentFactory.getInstance().getFragment(tabId)).commit(); }};动态界面
MVP实现
- DynamicView
- DynamicPresenter
@Overridepublic void logout() { mDynamicView.onStartLogout(); EMClient.getInstance().logout(true, mEMCallBackAdapter);}联系人界面
MVP实现
- ContactView
- ContactPresenter
- LinearLayoutManager 线性布局管理器 (类似ListView效果)
- GridLayoutManager 网格布局管理器 (类似GridView效果)
- StaggeredGridLayoutManager 分散网格布局管理器(瀑布流效果)
private void initRecyclerView() { mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));//设置布局管理器 mRecyclerView.setHasFixedSize(true);//设置true如果列表内容不会影响RecyclerView的大小 mContactListAdapter = new ContactListAdapter(getContext(), mContactPresenter.getContactList()); mContactListAdapter.setOnItemClickListener(mOnItemClickListener); mRecyclerView.setAdapter(mContactListAdapter);}ContactListAdapter的实现 ContactListItemView
运用模块化的思想,将联系人的列表项抽取成一个独立的自定义组合式控件ContactListItemView。ContactListItemView只需传入一个与之对应的数据模型ContactListItem即可完成渲染。联系人是否在同一个组
当多个联系人的首字符相同时,只有第一个ContactListItemView显示首字符,后续首字符相同的ContactListItemView均不显示首字符。在ContactListItem中声明一个布尔型变量showFirstLetter来标记是否显示首字符。该变量在创建ContactListItem时赋值。
/** * 获取联系人列表数据 * @throws HyphenateException */private void startGetContactList() throws HyphenateException { ListCardView的使用contacts = EMClient.getInstance().contactManager().getAllContactsFromServer(); DatabaseManager.getInstance().deleteAllContacts(); if (!contacts.isEmpty()) { for (int i = 0; i < contacts.size(); i++) { ContactListItem item = new ContactListItem(); item.userName = contacts.get(i); if (itemInSameGroup(i, item)) { item.showFirstLetter = false; } mContactListItems.add(item); saveContactToDatabase(item.userName); } }}/** * 当前联系人跟上个联系人比较,如果首字符相同则返回true * @param i 当前联系人下标 * @param item 当前联系人数据模型 * @return true 表示当前联系人和上一联系人在同一组 */private boolean itemInSameGroup(int i, ContactListItem item) { return i > 0 && (item.getFirstLetter() == mContactListItems.get(i - 1).getFirstLetter());}
CardView继承自FrameLayout, 是Material Design里面的卡片设计,带有圆角和阴影效果。CardView效果非常好看,但也不能滥用,比如:
更多的使用规范,请参考Material Design的设计规范Material Design Cards。这里我们给ContactListItemView的布局里面包了一层CardView,实际上是不可取的做法,这里只是为了展示CardView的使用姿势,实际项目中请大家遵循Material Design的设计规范。参考SwipeRefreshLayout的使用
//设置SwipeRefreshLayout的颜色mSwipeRefreshLayout.setColorSchemeResources(R.color.qq_blue, R.color.qq_red);//设置SwipeRefreshLayout的监听器mSwipeRefreshLayout.setOnRefreshListener(mOnRefreshListener);自定义控件SlideBar分类字符数组
rivate static final String SECTIONS = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L" , "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};绘制居中文本FontMetrics
@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) { mTextSize = h * 1.0f / SECTIONS.length;//计算分配给字符的高度 Paint.FontMetrics fontMetrics = mPaint.getFontMetrics(); float mTextHeight = fontMetrics.descent - fontMetrics.ascent;//获取绘制字符的实际高度 mTextBaseline = mTextSize / 2 + mTextHeight/2 - fontMetrics.descent;//计算字符居中时的baseline}@Overrideprotected void onDraw(Canvas canvas) { float x = getWidth() * 1.0f / 2; float baseline = mTextBaseline; for(int i = 0; i < SECTIONS.length; i++) { canvas.drawText(SECTIONS[i], x, baseline, mPaint); baseline += mTextSize; }}[/i]在ContactFragment里面监听SlideBar的事件 当用户在SlideBar上ACTION_DOWN和ACTION_MOVE时,如果用户触摸到的首字符发生变化,则会回调监听器onSectionChange,当ACTION_UP时回调onSlidingFinish()。
private SlideBar.OnSlideBarChangeListener mOnSlideBarChangeListener = new SlideBar.OnSlideBarChangeListener() { @Override public void onSectionChange(int index, String section) { mSection.setVisibility(View.VISIBLE);//显示中间绿色背景的首字符 mSection.setText(section); scrollToSection(section);//滚动RecyclerView到用户滑到的首字符 } @Override public void onSlidingFinish() { mSection.setVisibility(View.GONE);//隐藏中间绿色背景的首字符 }};联系人点击事件当单击联系人时跳转到聊天界面,当长按联系人时弹出Dialog询问用户是否删除好友。
private ContactListAdapter.OnItemClickListener mOnItemClickListener = new ContactListAdapter.OnItemClickListener() { /** * 单击跳转到聊天界面 * @param name 点击item的联系人名字 */ @Override public void onItemClick(String name) { startActivity(ChatActivity.class, Constant.Extra.USER_NAME, name); } /** * 长按删除好友 * @param name 点击item的联系人名字 */ @Override public void onItemLongClick(final String name) { showDeleteFriendDialog(name); }};添加好友界面
MVP实现
- AddFriendView
- AddFriendPresenter
@Overridepublic void searchFriend(final String keyword) { mAddFriendView.onStartSearch(); //注:模糊查询只对付费用户开放,付费后可直接使用。 BmobQuerygreenDAOgreenDAO是Android SQLite数据库ORM框架的一种。ORM即对象关系映射, object/relational mapping, 将Java对象映射成数据库的表。我们需要存储联系人数据到数据库,在添加好友界面,需要判断搜索出来的用户是否已经是联系人,如果已经是好友,则应显示“已添加”。其他ORM框架 参考 创建实体类query = new BmobQuery (); query.addWhereContains("username", keyword).addWhereNotEqualTo("username", EMClient.getInstance().getCurrentUser()); query.findObjects(new FindListener () { @Override public void done(List list, BmobException e) { processResult(list, e); } });}
@Entitypublic class Contact { @Id public Long id; public String userName;}初始化
public void init(Context context) { DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(context, Constant.Database.DATABASE_NAME, null); SQLiteDatabase writableDatabase = devOpenHelper.getWritableDatabase(); DaoMaster daoMaster = new DaoMaster(writableDatabase); mDaoSession = daoMaster.newSession();}保存联系人
public void saveContact(String userName) { Contact contact = new Contact(); contact.setUsername(userName); mDaoSession.getContactDao().save(contact);}查询联系人
public List删除所有联系人queryAllContacts() { List list = mDaoSession.getContactDao().queryBuilder().list(); ArrayList contacts = new ArrayList (); for (int i = 0; i < list.size(); i++) { String contact = list.get(i).getUsername(); contacts.add(contact); } return contacts;}
public void deleteAllContacts() { ContactDao contactDao = mDaoSession.getContactDao(); contactDao.deleteAll();}发送好友请求 AddFriendItemView里面处理添加好友的点击事件
@OnClick(R.id.add)public void onClick() { String friendName = mUserName.getText().toString().trim(); String addFriendReason = getContext().getString(R.string.add_friend_reason); AddFriendEvent event = new AddFriendEvent(friendName, addFriendReason);//通过EventBus发布添加好友事件 EventBus.getDefault().post(event);}AddFriendPresenterImpl实现发送好友请求
@Subscribe(threadMode = ThreadMode.BACKGROUND)public void addFriend(AddFriendEvent event) { try { EMClient.getInstance().contactManager().addContact(event.getFriendName(), event.getReason()); ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mAddFriendView.onAddFriendSuccess(); } }); } catch (HyphenateException e) { e.printStackTrace(); ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mAddFriendView.onAddFriendFailed(); } }); }在联系人列表中监听联系人变化当新增好友或者被好友删除时刷新联系人列表。
private EMContactListenerAdapter mEMContactListener = new EMContactListenerAdapter() { @Override public void onContactAdded(String s) { mContactPresenter.refreshContactList(); } @Override public void onContactDeleted(String s) { mContactPresenter.refreshContactList(); }};聊天界面
MVP实现
- ChatView
- ChatPresenter
mEdit.addTextChangedListener(mTextWatcher);private TextWatcherAdapter mTextWatcher = new TextWatcherAdapter() { @Override public void afterTextChanged(Editable s) { mSend.setEnabled(s.length() != 0); }};动画文件
- anim文件夹:存放补间动画
- animator文件夹:存放属性动画
- drawable文件夹:存放帧动画
- animator文件夹:存放属性动画
9文件制作官方说明
发送一条消息 返回消息的类型 根据是发送的消息还是接受的消息,来创建不同的item。
@Overridepublic int getItemViewType(int position) { EMMessage message = mMessages.get(position); return message.direct() == EMMessage.Direct.SEND ? ITEM_TYPE_SEND_MESSAGE : ITEM_TYPE_RECEIVE_MESSAGE;}是否显示时间戳的判断
/** * 如果两个消息之间的时间太近,就不显示时间戳 */private boolean shouldShowTimeStamp(int position) { long currentItemTimestamp = mMessages.get(position).getMsgTime(); long preItemTimestamp = mMessages.get(position - 1).getMsgTime(); boolean closeEnough = DateUtils.isCloseEnough(currentItemTimestamp, preItemTimestamp); return !closeEnough;}更新消息的状态处理三种消息状态,正在发送中INPROGRESS,发送成功SUCCESS,发送失败FAIL。
private void updateSendingStatus(EMMessage emMessage) { switch (emMessage.status()) { case INPROGRESS: mSendMessageProgress.setVisibility(VISIBLE); mSendMessageProgress.setImageResource(R.drawable.send_message_progress); AnimationDrawable drawable = (AnimationDrawable) mSendMessageProgress.getDrawable(); drawable.start(); break; case SUCCESS: mSendMessageProgress.setVisibility(GONE); break; case FAIL: mSendMessageProgress.setImageResource(R.mipmap.msg_error); break; }}接收一条消息 监听消息的接收,当收到一条消息后,通知MessageListAdapter进行刷新,并且滚动RecyclerView到底部。
private EMMessageListenerAdapter mEMMessageListener = new EMMessageListenerAdapter() { @Override public void onMessageReceived(final List初始化聊天记录list) { ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { final EMMessage emMessage = list.get(0); mChatPresenter.makeMessageRead(mUserName); mMessageListAdapter.addNewMessage(emMessage); smoothScrollToBottom(); } }); }};
@Overridepublic void loadMessages(final String userName) { ThreadUtils.runOnBackgroundThread(new Runnable() { @Override public void run() { EMConversation conversation = EMClient.getInstance().chatManager().getConversation(userName); if (conversation != null) { //获取此会话的所有消息 List加载更多聊天记录messages = conversation.getAllMessages(); mEMMessageList.addAll(messages); //指定会话消息未读数清零 conversation.markAllMessagesAsRead(); } ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mChatView.onMessagesLoaded(); } }); } });}
@Overridepublic void loadMoreMessages(final String userName) { if (hasMoreData) { ThreadUtils.runOnBackgroundThread(new Runnable() { @Override public void run() { EMConversation conversation = EMClient.getInstance().chatManager().getConversation(userName); EMMessage firstMessage = mEMMessageList.get(0); //SDK初始化加载的聊天记录为20条,到顶时需要去DB里获取更多 //获取startMsgId之前的pagesize条消息,此方法获取的messages SDK会自动存入到此会话中,APP中无需再次把获取到的messages添加到会话中 final List会话界面messages = conversation.loadMoreMsgFromDB(firstMessage.getMsgId(), DEFAULT_PAGE_SIZE); hasMoreData = (messages.size() == DEFAULT_PAGE_SIZE); mEMMessageList.addAll(0, messages); ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mChatView.onMoreMessagesLoaded(messages.size()); } }); } }); } else { mChatView.onNoMoreData(); }}
MVP实现
- ConversationView
- ConversationPresenter
加载所有会话
@Override
public void loadAllConversations() {
ThreadUtils.runOnBackgroundThread(new Runnable() {
@Override
public void run() {
Mapconversations = EMClient.getInstance().chatManager().getAllConversations();
mEMConversations.addAll(conversations.values());
//根据最后一条消息的时间进行排序
Collections.sort(mEMConversations, new Comparator() {
@Override
public int compare(EMConversation o1, EMConversation o2) {
return (int) (o2.getLastMessage().getMsgTime() - o1.getLastMessage().getMsgTime());
}
});
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
mConversationView.onAllConversationsLoaded();
}
});
}
});
}
未读消息计数更新
环信官方文档
会话列表中未读消息的更新
private EMMessageListenerAdapter mEMMessageListenerAdapter = new EMMessageListenerAdapter() {
@Override
public void onMessageReceived(Listlist) {
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
toast(getString(R.string.receive_new_message));
//当收到一个新消息时,重新加载会话列表。
mConversationPresenter.loadAllConversations();
}
});
}
};
BottomBar badge的更新
private EMMessageListenerAdapter mEMMessageListenerAdapter = new EMMessageListenerAdapter() {
//该回调在子线程中调用
@Override
public void onMessageReceived(Listlist) {
updateUnreadCount();
}
};
private void updateUnreadCount() {
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
BottomBarTab bottomBar = mBottomBar.getTabWithId(R.id.conversations);
int count = EMClient.getInstance().chatManager().getUnreadMsgsCount();
bottomBar.setBadgeCount(count);
}
});
}
标记消息已读
加载聊天数据时标记已读
//指定会话消息未读数清零
conversation.markAllMessagesAsRead();
在聊天界面收到新消息时将消息标记已读
private EMMessageListenerAdapter mEMMessageListener = new EMMessageListenerAdapter() {聊天界面返回时更新未读badge
@Override
public void onMessageReceived(final Listlist) {
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
final EMMessage emMessage = list.get(0);
if (emMessage.getUserName().equals(mUserName)) {
//标记消息已读
mChatPresenter.makeMessageRead(mUserName);
mMessageListAdapter.addNewMessage(emMessage);
smoothScrollToBottom();
}
}
});
}
};
@Override
protected void onResume() {
super.onResume();
updateUnreadCount();
}
消息通知
通知
判断app是否在前台
public boolean isForeground() {
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
ListrunningAppProcesses = am.getRunningAppProcesses();
if (runningAppProcesses == null) {
return false;
}
for (ActivityManager.RunningAppProcessInfo info :runningAppProcesses) {
if (info.processName.equals(getPackageName()) && info.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
return true;
}
}
return false;
}
如果app在后台则弹出Notification
private void showNotification(EMMessage emMessage) {声音
String contentText = "";
if (emMessage.getBody() instanceof EMTextMessageBody) {
contentText = ((EMTextMessageBody) emMessage.getBody()).getMessage();
}
Intent chat = new Intent(this, ChatActivity.class);
chat.putExtra(Constant.Extra.USER_NAME, emMessage.getUserName());
PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, chat, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new Notification.Builder(this)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.avatar1))
.setSmallIcon(R.mipmap.ic_contact_selected_2)
.setContentTitle(getString(R.string.receive_new_message))
.setContentText(contentText)
.setPriority(Notification.PRIORITY_MAX)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build();
notificationManager.notify(1, notification);
}
初始化SoundPool
private void initSoundPool() {
mSoundPool = new SoundPool(2, AudioManager.STREAM_MUSIC, 0);
mDuanSound = mSoundPool.load(this, R.raw.duan, 1);
mYuluSound = mSoundPool.load(this, R.raw.yulu, 1);
}
播放音效
private EMMessageListenerAdapter mEMMessageListenerAdapter = new EMMessageListenerAdapter() {多设备登录
@Override
public void onMessageReceived(Listlist) {
if (isForeground()) {
mSoundPool.play(mDuanSound, 1, 1, 0, 0, 1);
} else {
mSoundPool.play(mYuluSound, 1, 1, 0, 0, 1);
showNotification(list.get(0));
}
}
};
环信官方文档
private EMConnectionListener mEMConnectionListener = new EMConnectionListener() {
@Override
public void onConnected() {
}
@Override
public void onDisconnected(int i) {
if (i == EMError.USER_LOGIN_ANOTHER_DEVICE) {
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
startActivity(LoginActivity.class);
toast(getString(R.string.user_login_another_device));
}
});
}
}
};
github地址:https://github.com/uncleleonfan/QQDemo 收起阅读 »
直聘学院| 独角兽产品养成记【深度对话摩拜单车/喜马拉雅FM等产品总监】
产品工作如何让你们的市场、运营、技术同事为你欢呼尖叫?
怎么样的产品策略能不靠投资后来居上逆袭行业排名第一?
2016年11月20日
让那些独角兽产品的创造者们和我们一起聊聊:
独角兽产品养成记!
活动嘉宾介绍:
活动流程
13:30-14:00丨现场签到 & 交流
14:00-15:00丨摩拜单车Stella主题分享《线上线下结合的产品实践》
15:00-16:00丨涂图石强主题分享《如何用产品思维驱动业务实践》
16:00-17:00丨Neta干田主题分享《运营背后的坑是这么填的》
17:00 —— 丨全场合影
关于直聘学院
对话产品总监是BOSS直聘 「 直聘学院 」 旗下系列活动之一。联合明星公司&合作伙伴共同发起,为互联网领域的产品经理从业者举办的专场沙龙,旨在通过纯业内的干货分享,推动互联网行业从业者职业路上进步。
特别鸣谢
抢票链接:http://gz.huodongxing.com/event/5358825198900
收起阅读 »
减少APK的大小,Android官方这样说
减小APK的大小。到处搜索一下各路大神的方法。还是觉得无论从原理上还是具体做法上都是官方的比较全面。所以就翻译了一下,分享出来。主要是用Google Translate,然后自己稍微按照中文逻辑修了一下。如有不妥的地方,请多提意见。(PS:另外还碰到了传奇的65535方法数这个大坑,后面再写这个。文中有些超链接可能需要梯子)
Android官网链接:Reduce APK Size
用户经常会避免下载看起来过大的应用程序,特别是在新兴市场,设备连接到常见的2G和3G网络或者使用按字节付费的网络。本文介绍如何减少应用程序的APK大小,让更多使用者下载你的应用程序。
一、了解APK结构
在讨论如何缩小应用程序的大小之前,先了解应用程序APK的结构,是有帮助的。APK文件包含ZIP文件,其中包含构成应用程序的所有文件。这些文件包括Java类文件,资源文件和已编译资源的文件。
APK包含以下目录:
- META-INF/:包含CERT.SF和CERT.RSA签名文件,以及MANIFEST.MF清单文件。
- assets/:包含应用程序的资源,应用程序可以使用AssetManager对象检索该资源。
- res/: 包含未编译到resources.arsc中的资源。
- lib/:包含特定处理器的软件层的编译代码。此目录包含每个平台类型的子目录,如armeabi,armeabi-v7a,arm64-v8a,x86,x86_64和mips。
- resources.arsc:包含已编译的资源。此文件包含来自res / values /文件夹的所有配置的XML内容。包装工具提取此XML内容,将其编译为二进制形式,并归档内容。此内容包括语言字符串和样式,以及未直接包含在resources.arsc文件中的内容路径,例如布局文件和图像。
- classes.dex:包含以Dalvik / ART虚拟机理解的DEX文件格式而编译的类。
- AndroidManifest.xml:包含核心Android清单文件。此文件列出应用程序的名称,版本,访问权限和引用的库文件。该文件使用Android的二进制XML格式。
res/layout/preferences.xml: Warning: The resource R.layout.preferences appears to be unused [UnusedResources]
注意:lint工具不扫描assets/文件夹,它是通过反射来发现引用的资源或已链接到你的应用程序的库文件。此外,它不会删除资源;它只会提醒你们他们的存在。 你添加到代码的库可能包含未使用的资源。如果在应用程序的build.gradle文件中启用shrinkResources,Gradle可以自动删除资源。android { // Other settings buildTypes { release { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }}要使用shrinkResources,必须启用代码缩减。在构建过程中,首先要用ProGuard删除未使用的代码,但留下未使用的资源。然后Gradle删除未使用的资源。有关ProGuard和Android Studio帮助你减少APK大小的其他方法的详细信息,请参阅Shrink Your Code and Resources。在Android Gradle Plugin 0.7及更高版本中,你可以声明你的应用程序支持的配置。 Gradle使用resConfig 、resConfigs flavor和defaultConfig选项并将此信息传递给构建系统。然后,构建系统会阻止来自其他不受支持的配置的资源出现在APK中,从而减少APK的大小。有关此功能的详细信息,请参阅 Remove unused alternative resources最小化库中的资源使用开发Android应用程序时,通常使用外部库来提高应用程序的可用性和多功能性。例如,你可以引用Android Support Library 以改善旧设备上的用户体验,或者你可以使用 Google Play Services 检索应用内文字的自动翻译。如果库是为服务器或桌面设计的,它可能包括你的应用程序不需要的许多对象和方法。要仅包含应用程序需要的库的部分,你可以编辑库的文件(如果许可证允许你修改库)。你也可以使用其他适合移动设备的库给你的应用添加特定功能。
注意: ProGuard可以清理引用库导入的一些不必要的代码,但它不能删除库的大型内部依赖项 。仅支持特定密度Android支持非常大的设备集,包括各种屏幕密度。在Android 4.4(API级别19)及更高版本中,框架支持各种密度: ldpi,mdpi,tvdpi,hdpi,xhdpi,xxhdpi和xxxhdpi。虽然Android支持所有这些密度,但你不需要细化资源到适合每个密度。如果你知道只有一小部分用户使用具有特定密度的设备,请考虑是否需要将这些密度捆绑到应用中。如果你不包括特定屏幕密度的资源,Android会自动缩放最初为其他屏幕密度设计的现有资源。如果你的应用只需要缩放的图片,你可以通过在drawable-nodpi /中使用图片的单个变体来节省更多空间。我们建议每个应用程序至少包含一个xxhdpi图片版本。有关屏幕密度的详细信息,请参阅 Screen Sizes and Densities。减少动画帧逐帧动画会大幅增加APK的大小。图1显示了在目录中分成多个PNG文件的逐帧动画的示例。每个图像是动画中的一帧。对于添加到动画中的每个帧,都需要增加APK中存储的图片数量。在图1中,图像在应用程序中以30 FPS动画。如果图像仅以15FPS动画化,则动画将仅需要所需帧的数目的一半。
使用Drawable对象一些图像不需要静态图像资源; framework可以在运行时动态地绘制图像。 Drawable(XML中的<shape>)可能会占用你APK中的少量空间。此外,XML Drawable对象还能产生符合Material Design准则的单色图像。重用资源你可以为图像的变体使用单一的资源,例如同一图像的有色,阴影或旋转版本。但是,我们建议你重复使用相同的资源集,在运行时根据需要进行自定义。Android提供了几个实用程序来更改资产的颜色,使用Android 5.0(API级别21)或更高版本上的android:tint和tintMode属性。对于较低版本的平台,请使用 ColorFilter类。你还可以省略只是等效于另一个资源的资源。以下代码段提供了一个例子,通过简单地将原始图像旋转180度,将“展开”箭头转换为“折叠”箭头图标:
<?xml version="1.0" encoding="utf-8"?><rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_arrow_expand" android:fromDegrees="180" android:pivotX="50%" android:pivotY="50%" android:toDegrees="180" />从代码中呈现你还可以通过程序性渲染图片来减少APK大小。这个过程也释放了空间,因为你不再在APK中存储图像文件。压缩PNG文件aapt工具可以在构建过程期间优化放置在res / drawable /中的图像资源,以及无损压缩。例如, aapt工具可以将不需要多于256种颜色的真彩色PNG转换为带有调色板的8位PNG。这样做会产生质量相同但占用内存较小的映像。请记住,aapt有以下限制:
- aapt工具不会压缩资源/文件夹中包含的PNG文件
- 图像文件需要使用256个或更少的颜色的aapt工具来优化它们。
- aapt工具可能会使已压缩的PNG文件膨胀。为了防止这种情况,你可以在Gradle中使用cruncherEnabled标志为PNG文件禁用此过程:
aaptOptions { cruncherEnabled = false}压缩PNG和JPEG文件你可以使用像 pngcrush,pngquant,或 zopflipng等工具来减少PNG文件大小,而不会丢失图像质量。所有这些工具都可以减少PNG文件大小,同时保持图像质量。pngcrush工具特别有效:此工具在PNG过滤器和zlib(Deflate)参数上迭代,使用过滤器和参数的每个组合来压缩图像。然后选择产生最小压缩输出的配置。对于JPEG文件,你可以使用 packJPG 等工具将JPEG文件压缩为更紧凑的形式。使用WebP文件格式除了使用PNG或JPEG文件,你还可以为你的图像使用WebP 文件格式。 WebP格式提供有损压缩(如JPEG)和透明度(如PNG),还可以提供比JPEG或PNG更好的压缩效果。但是,使用WebP文件格式有一些显着的缺点。 首先,在低于Android 3.2(API级别13)的平台的版本中不支持WebP。 第二,系统解码WebP比PNG文件需要更长的时间。
注意:只有当所包含的图标使用PNG格式时,Google Play才接受APK。如果你打算通过Google Play发布应用,则无法对应用图标使用其他文件格式(如JPEG或WebP)。使用矢量图形你可以使用矢量图形创建独立于分辨率的图标和其他可伸缩图片。 使用这些图形可以大大减少APK的大小。 矢量图形在Android中表示为 VectorDrawable对象。 使用 VectorDrawable对象,100字节的文件可以生成屏幕大小的清晰图像。 然而,系统渲染每个 VectorDrawable对象需要大量的时间,较大的图像需要更长的时间才能出现在屏幕上。 因此,只有在显示小图像时才考虑使用这些矢量图形。有关使用 VectorDrawable更多信息,请参阅 Working with Drawables。三、减少原生和Java代码有几种方法可以用来减少应用程序中Java和原生代码库的大小。删除不必要的生成的代码确保了解自动生成的任何代码的足迹。例如,许多协议缓冲工具生成过多的方法和类,可以使应用程序的大小增加一倍或三倍。删除枚举单个枚举可以使应用程序的classes.dex文件添加大约1.0到1.4 KB的大小。 这些添加可以快速积累为复杂的系统或共享库。 如果可能,请考虑使用@IntDef注释和 ProGuard 来除去枚举并将它们转换为整数。 此类型转换保留枚举的所有类型的安全性好处。减少本地二进制文件的大小如果你的应用使用原生代码和Android NDK,你还可以通过优化代码来减小应用的大小。两个有用的技术是删除调试符号和提取原生库。
- 删除调试符号
- 避免提取原生库
将.so文件存储在APK中未压缩的文件,并在应用清单的<application> 元素中将android:extractNativeLibs标记设置为false。 这将防止 PackageManager在安装过程中将.so文件从APK复制到文件系统,并且将具有使你的应用程序的delta更新更小的额外好处。
四、维护多个精益版APK
你的APK可以包含用户下载但从不使用的内容,例如区域或语言信息。 要为用户创建最低限度的下载,你可以将应用细分为多个APK,并根据屏幕尺寸或GPU纹理支持等因素进行区分。
当用户下载你的应用时,其设备会根据设备的功能和设置接收正确的APK。这样,设备不会接收设备没有的功能的资源。例如,如果用户具有hdpi设备,则他们可能不需要你为具有更高密度显示的设备添加的xxxhdpi资源。
更多信息,请参阅 Configure APK Splits 和 Maintaining Multiple APKs。
本文作者:Android 工程师Kevin_Han 收起阅读 »
2016程序员技术交流年会
即将于2016年12月10日在北京东城区百富怡大酒店举办
大会介绍
大会坚持公益性质且技术干货为主,与数百位最具影响力的行业领袖和技术领军人物共同学习、了解最新互联网技术趋势,分享和讨论互联网最新研究成果和前沿技术,探讨互联网技术如何定义未来,致力于以多种形式灵活整合、分享软件和互联网技术最新动态,评估最新行业趋势;为技术研发人员开拓思路,找寻有效的研究方向。
届时将会有知名媒体到现场报道,国内著名门户网站、社交网站、O2O、移动互联网等各个领域产品和设计专家参与,无论您处于互联网行业的哪个领域,2016程序员技术交流年会将成为引领互联网技术的风向标,汇聚领域的顶尖专家,打造一场技术领域极具价值的技术盛会。
大会亮点
跨行业,跨技术领域,跨国度,年度盛会
与真正的程序员开发贡献者和参与者,直接互动
大数据,云计算,操作系统,全球领先的AI,VR技术,精彩纷呈
我们是谁
浪曦网是由中国支持软件程序员的企业、社区以及个人所组织的一个开发者联盟企业,一直以来致力于在中国软件开发推广,推动中国软件社区成为全球软件和硬件的积极贡献者。并携手国内社区,高校,企业,政府,共创健康可持续发展的生态体系。
我们打算办一个怎样的大会
通过这次大会,我们希望能够实现:
软件开发行业、企业的高手齐聚一堂、激荡火花
跨行业、跨技术领域、跨国度的年度盛会
与真正的软件开发贡献者、参与者,直接互动
最终达成我们“天下程序员是一家、浪曦携手迸火花”的理想!
会议形式
为了实现上述目标,我们策划了丰富的会议形式:
主题演讲:浪曦大牛为您带来精彩的软件开发模式相关的深度内容
高峰对话:行业领军人物,共同探讨程序员未来的发展
分论坛:包括操作系统、云计算、大数据、前沿技术、等诸多领域,精彩纷呈,一定会有你感兴趣的话题。
圆桌高峰会:邀请企业、社区、协会及专家代表,畅谈分享企业软件开发治理的心得,流程,实践与各种酸甜苦辣。
浪曦之夜:欢聚一堂、敞开心扉、畅所欲言的社区见面会。(仅限受邀嘉宾,讲师,赞助伙伴,及大会工作人员,恕不对外开放)
创新互动
和一般的大会不一样,我们知道草根程序员社区听众,期盼听到纯干货,更希望与讲师能有更多互动,因此我们安排了:讲师打赏(提供讲师更高的动力分享干货) 、现场在线抽奖
大会规模
500人,大部分来自浪曦网达到一定层次的高级会员
大会主办方
大会合作方
合作媒体
嘉宾名单
胡辛征 中国电子工业出版社社长
吴召学 滴滴运营总监CTO
黄维维 云和恩墨运营总监
郑文平 世界瑜伽大会组委会副主席
罗 皆 大数据实战项目专家
方 沛 阿里巴巴前端总指挥
更多嘉宾名单介绍,请关注浪曦官网 www.langsin.com
参加对象
企业创始人、CEO,合伙人、董事长、CTO 、VP 、总工程师 、总经理、总架构师 ,高级架构师 、资深架构师、高级经理、技术主管、技术负责人、高级工程师 、资深工程师、开发开程师 、运维工程师、研究员等 软件行业新上岗一线技术工程师、拟提拔一线经理、二线经理、项目经理。
注册费
赞助企业与浪曦网高级会员免注册费及餐费(如您是浪曦会员填表时请附上您的浪曦网会员用户名)
无赞助企业与非会员注册费:1000元/人,含餐。
从五千元到二十万元不等的多种赞助推广方案。
我要报名:http://www.bagevent.com/event/264024
大会招商部
联系人:刘先生
手机:18210801352
Q Q:1598234192
邮箱:lhs_852@163.com 收起阅读 »
从中国女排里约夺冠看企业培训管理
中国人对于排球运动的热情始于20世纪80年代,中国女排曾获得过“五连冠”的辉煌,郎平的“铁榔头”称号在当时成为了中国女排的代名词。当时的中国刚刚开始改革开放,中国女排在1981年的世界杯中战胜日本队为中国人创造了一个英雄形象。
在本届里约奥运会的女排赛场上,中国女排一路披荆斩棘,先是以2胜3负的小组成绩进入八强,然后接着在1/4决赛中力压上届卫冕冠军东道主巴西队,接着在半决赛中击败了小组赛中曾获胜的荷兰队,最后在决赛中以3:1战胜了塞尔维亚夺得了冠军!有人说中国女排这次在里约奥运会是爆发了“洪荒之力”,让中国在12年之后重返世界女排巅峰的地位,让我们再次领略了什么叫“女排精神”,让中国人重振民族自豪感!那么,中国女排的里约夺冠对于我们的企业培训管理工作,又有什么启发呢?
NO.1 一支队伍
随着2004年奥运会“黄金一代”的逐渐淡出,郎平教练在采访中是这样说的:“虽然今年最主要任务是奥运会,但是训练不能只考虑奥运会,还要考虑明年、后年,不能说完成奥运会的比赛任务,下个奥运周期的事儿就不管了。国家队人才的培养需要长期的规划,有新人我们是一定要培养的。”在郎平执教时代,一个又一个新人被挖掘出来,国家队不但实现了技术的上年年进步,球员也呈现越来越年轻化的趋势。郎平在执教上,擅长整合管理。利用有限的资源,将本土化与国际化相结合,打造一支高效的、年轻化的复合型团队。复合型团队,即由主教练、助理教练、陪打教练、医生、康复师、体能师、营养师、科研、信息研究、数据统计等专业人才组成。
培训是企业培养人才的重要手段。企业的每个发展阶段都有企业最需要的人才和相应的岗位,企业只有通过持续不断地培训,员工的工作技能和个人综合素质才会得到显著提升,为企业高速发展做出他们应有的贡献。对于企业管理者来说,员工培养是一个长期的、持续的过程。不管是发掘潜力股还是发现培养新人对于打造优秀企业团队都是同等重要的。
强化自主培训功能,加强对员工特别是一线员工的教育和培训,除了聘请外部师资和教育资源,企业内部的重要手段就是发展一支自己的企业内训师队伍。企业内训师队伍建设,需从企业、行业、专业三方面进行考虑。
(1)“企业人”。要求候选对象在本企业工作有一定时间,一般大概在2年以上,这样才能保证他们对企业足够了解,保证其能够准确传递企业文化和业务知识。当候选对象对企业充满感情,才能在内训活动中充满激情,为公司人才培养事业尽自己全力去发光发热。
(2)“行业人”。要求候选对象具备深厚理论基础或者专业的技术水平。他们既可以是管理人才,也可以是业务骨干。由于他们受到广大员工的普遍认可,避免了员工对内训师可能会产生的抵触情绪。候选对象对企业有深入了解,能够给企业留下宝贵的知识积累和经验,可以通过培训让更多的人学习到知识,从而提高企业员工的整体素质。
(3)“专业人”。作为一名内训师,其核心职能就是通过培训活动的开展传达知识、培养人才,这要求内训师候选对象需要具备一定的岗位专业能力,同时要具备强烈的个人动机、一定的文化程度、潜在的培训师特质、主动的服务意识等。
NO.2 一个体系
自从郎平接队之后,构建了“大国家队”的概念。“大国家队”理念,顾名思义就是增加国家队球员人数,集训的国家队大名单扩大到30多人,每次参加国家队集训的也有20至30多人,老中青结合,每个位置保持三到四个人在竞争。
这一小小管理范围的转变,改善的不仅仅是运动成绩,更是充满希望的年轻一代。郎平的大国家队理念目的是广纳贤才,为国家队建立各个梯度的预备人才。这种不拘一格发现人才、使用人才的训练管理理念及人才培养体系,对于企业管理者来说也有一定的启示意义。
在人力资源管理工作中,持续不断地培训不仅让员工得到了个人知识和能力的提高,同时也使员工会发自内心的感激企业促使自我成长,提供自我价值实现的机会。我们不妨搭建一个“2+2”的人才培养体系为企业人才发展铺路。
1、两项制度
建立企业自身的培训体系首先需要明确企业内部的内训师管理、培训项目管理的制度。
(1)内训师管理制度:
从培训的实用性、适应性、持续性和经济性方面考虑,发展内部培训将逐渐成为企业未来培训的主流。完善内训师管理制度,首先从日常管理工作出发。根据内训师级别、授课满意度、授课时长、培训人数等方面,周期性进行星级考核评定。其次,给予一定的物质激励,同时将非货币激励如内训师等级纳入员工职位晋升考评与年度绩效考评,作为主管、经理选拔重要参考因素等,促使并保持内训师在企业中的活跃性,形成完整的内训师闭环管理。
(2)培训项目管理制度:
培训是企业知识传播、积累、创新的重要途径。从企业日常生产运营角度出发,规范培训项目生成的实施流程,实现“常态性”、“临时性”培训项目的分类管理,打通培训项目生成渠道,形成“需求”与“供给”的“市场”机制,提高内部培训质量水平。下面以内部常态化的课程开发培训项目管理为例,介绍一下培训项目管理在实践中的具体操作(图1:课程开发及评估流程项目):
2、两种模式
(1)新员工培养模式:
从企业需求出发,针对新入职员工开展入职培训,通过结业考试、导师制、定期沟通会等一系列基础工作,将企业文化和理念、岗位职责与意识渗透到员工日常工作中。同时也可适当融入一些性格测试等心理学方面的管理方法,如Tree-House-Person房树人测验、FPA性格色彩测试等。
(2)转岗人员培养模式:
在企业内部因市场转型、结构调整、岗位变化等外在原因,时常会有人员转岗、重新学习技能的情况,为了规范转岗人员培养流程,使转岗人员快速融入企业内部新的工作团队、适应企业文化、行为规范、岗位技能与知识对其的要求,帮助转岗人员短时间成长为公司所需要的优秀人才,促进员工与组织共同发展。可结合岗位胜任力模型开展转岗人员培养,进行学习清单制培养,分线条、分技能的清单学习,最后再进行评估与验收。
NO.3 一套方法
说起“女排精神”,郎平说过“单靠精神不能赢球!对于中国女排来说,夺冠的主要还是靠战术、队员素质和临场指挥,建立规范的、科学的培训制度!”在采访中郎平还说,“平时训练不好我们都要加班。这不是讲点故事和心灵鸡汤就够了,技术上我们也做了很多计划,就是要突破自己!”有人说“三从一大”的训练模式是中国女排夺得世界冠军的法宝,“三从一大”就是指训练过程中从难、从严、从实战出发,坚持大运动量训练。
道理相同,没有专业的企业培训方法,就没有高素质的员工队伍。每个行业都有结合自身实际情况的科学培训训练方法。下面,我们分三个步骤来演示一下如何训练和提升客服代表的沟通能力:
第一步:沟通训练情景化
客服人员在为客户服务的过程中应该怎样与客户沟通呢?通过情景对话引出每一环节可能用到的沟通技巧,模拟客户服务工作中可能出现的场景,从客户心理、服务态度、沟通礼仪、倾听、提问、处理抱怨、解决投诉和解答问题等角度,通过多个场景去全面、生动地展示各个环节中客服人员与客户电话去沟通的方法,训练过程中将客服人员代入到沟通情景中,增强学习画面感。
首先,在沟通中客服人员把握客户心理需求的能力非常重要。因为客服工作的目标是让客户满意,而只有满足了客户的心理需求,排除了客户的负面情绪,让客户在享受服务的同时获得一份愉悦的心情,才能给客户留下良好的印象。沟通的能力与客户的需求分不开,首先需要从如何寻找客户的需求开始,有效的开场白、通过询问探询顾客的需求、通过有效聆听了解客户的需求。
其次,就是倾听和询问。有人说沟通是倾听的艺术,这句话充分体现了倾听在沟通中的重要作用。倾听可以获取信息、发现问题,客服人员只有认真倾听,知道客户需要什么样的帮助和服务,客户的不满和抱怨在什么地方,才能对症下药,解决客户的问题。另外,认真倾听还是对客户尊重的一种表现,有利于营造良好的沟通氛围。因此,一名优秀的客服人员必须掌握良好的倾听技巧。
最后,处理客户抱怨。客服人员在工作中经常会听到客户的抱怨,只要客户所得到的产品或服务和他们的期望值之间存在距离,就会产生抱怨。客户投诉处理不当,会影响客户关系和客户感知,甚至还会影响到公司的社会形象,造成恶劣的影响,掌握处理客户抱怨的技巧对于每一位客服人员来说都非常有必要。
第二步:沟通训练套路化
针对客户服务工作中可能出现的沟通问题、客服异议等,通过情景对话将这些技巧套路化,使员工从中学到沟通的技能,掌握解决问题的方法。在客户服务和营销沟通中,常用的套路化技巧有:SPIN销售法、FABE话术、影响力话术、3F法则、三句半等。
第三步:沟通训练模板化
通过上面的技巧套路总结出“万能话术模板”,便于学员在实际工作情景中灵活套用。 下面举两个模板化的例子,图1为当客户抛出问题后客服人员如何接招并处理的技巧套路;图2为当客户提出异议或是投诉抱怨时,客服人员如何处理的技巧套路。掌握了简单的套路后可以将其运用在相同场景的不同问题的处理中,当客服人员遇到类似问题时就能够很顺畅的处理完成客户问题。
中国女排里约夺冠不仅是中国人的一份荣誉,当然中国女排带给我们的启发也不仅仅只有一支队伍、一个体系、一套方法那么简单!对于各行各业来说,女排成功的背后其中所蕴含的理念、方法和精神是一门值得我们好好学习和深入研究的课程。
本文刊载于《客户世界》2016年10月刊文章;原文作者周四维,本文作者作者单位为中移在线服务有限公司重庆分公司. 收起阅读 »
【开源项目】家聊 -- 一款基于环信开发专为老人打造的轻量级IM开源项目
写在前面的话:
简单来说,这是一款做来给家里老人用的APP,核心组件就是采用的环信sdk,感谢环信做的这么棒的sdk!!!感兴趣或者看过项目的人希望给出宝贵意见与我探讨,文章末尾有作者联系方式(放后面是确定你在联系我之前知道了家聊)
初衷:
很久之前想就教家里老人学习使用智能机,让他们能用App和家人交流沟通,但是发现市面上流行的社交软件对于他们来说学习成本太高。
这个项目属于轻量级的IM项目,聊天形式只有文字、语音、图片、短视频、实时音视频。这个软件的定位和市面上大多数社交软件不一样,我希望去掉那些复杂的社交元素,专门做一款能适合老人快速上手智能机的软件。
所以类似群聊、朋友圈那样的社交模块都没有做,力争每个功能的入口简单清晰,老人一眼就能看懂,所以产品逻辑不会特别复杂,想了解的同学可以clone下来运行看看(有时间我会打包个测试apk出来)。
项目特点:
项目里的业务架构类似MVP,在环信官方的基础上加了一些自己的实现,代码阅读更加顺畅。无论是做开源项目还是工作上的项目,我个人更倾向于能用原生实现就用原生实现,类似现在流行的RX系列、注解框架等我都没有采用(这里不是说不要去学,新技术当然值得去学,但是至于要不要在项目中采用需要自己或团队考量)
当然这么多做的前提是有把握做好,不要随随便便就崩溃,目的其实就是为了降低别人阅读或者接管代码时的学习成本,所以大家在看代码的时候应该不会有特别难理解的地方
主要功能:
- 聊天模块,包含文字聊天、语音聊天、发送图片、短视频、实时音频通话、实时视频通话。
- 通讯录:可获取系统通讯录,和环信好友关系整合。
- 拨号器:自定义的简单拨号盘,方便老人直接拨打电话
项目运行效果图:
联系作者:
如果发现项目bug或者对项目有好的建议,欢迎提交issue,或者通过下面的联系方式联系我.
*QQ:505515031 746604151
*邮箱:505515031@qq.com
*微信:Vanish520136
github地址:https://github.com/Vanish136/FamilyChat
oschina地址:http://git.oschina.net/vanish136/FamilyChat 收起阅读 »
草草们的忧伤:环信IM昵称和头像
在环信草草群(群号:340452063)中,无论是安卓还是IOS或者WebIM,每天遇到最多的问题就是“如何显示昵称和头像”,鉴于大家的墙裂需求,所以我最近花了点时间研究了相关解决方案,希望能跟大家一起探索。
运行效果
目标
集成环信IM的SDK后,能以最快方式,最少代码管理用户的昵称和头像。
解决方案
使用本地缓存(sqlite)和后端云实现头像和昵称的二级缓存
【参考】 http://docs.easemob.com/im/490integrationcases/10nickname#昵称和头像的显示与更新
计划
先在IOS上验证该方案的优缺点,待方案完善后,再将此模式复制到Android和WebIM上
项目快速集成
1. 按照简版Demo的方式在项目中快速集成环信IM功能
IOS快速集成环信IM - 基于官方的Demo优化,5分钟集成环信IM功能http://www.imgeek.org/article/825307886
2. 注册第三方后端云账号,使用数据存储服务
(1). 在第三方后端注册用户,进入控制台,创建应用(例如名称为【环信简版Demo】),点击【存储】按钮进入数据存储管理页面:
(2). 创建数据表UserWebInfo,并且按照新增三个字段(字段名开头必须小写):
openId String 环信ID
nickName String 用户昵称
avatarUrl String 用户头像(绝对路径)
其中,avatarUrl是app端上传头像到【_File】数据表后获取到的绝对路径:
(3). 在【设置】-> 【应用Key】页面中
复制AppID和AppKey替换AppDelagate里didFinishLaunchingWithOptions的key:
// 初始化web缓存配置参考: 简版demo中的AppDelegate+EaseMob.m第56行
[UserWebManager config:launchOptions
appId:@"utUG5ot9Y64dqJIFG9Ir2rqu-gzGzoHsz"
appKey:@"IbHhNkPo4gfrFFc3epCw3eG2"];
3. 上传用户头像和昵称到第三方后端云服务器
用户在app中调用开发者服务器API接口登录成功后,一般都会返回用户的属性信息(昵称和头像等),我们可以在这里上传用户信息到云服务器:
// 登录成功后,如果后端云没有缓存用户信息,则新增一个用户参考:简版demo中LoginViewController.m的第156行代码
[UserWebManager createUser:username nickName:nickName avatarUrl:avatarUrl];
4.显示用户昵称和头像
在需要显示用户昵称和头像的地方,调用UserCacheManager里的方法即可,具体调用地方,请在xcode里搜索简版Demo代码“[UserCacheManager ”,如图所示,在这里就不累赘了:
5.修改用户昵称和头像
(1). 更改头像
// 上传头像到后端云参考简版Demo中UserProfileEditViewController.m第181行代码
[UserWebManager updateCurrAvatar:orgImage completed:^(UIImage *imageData) {
[weakSelf hideHud];
if(!imageData){
[self showHint:@"更新头像失败~"];
return;
}
[weakSelf.headImageView imageWithUsername:kCurrEaseUserId placeholderImage:imageData];
[self showHint:@"更新头像成功~"];
}];
(2). 更新昵称
[UserWebManager updateCurrNick:@"小草" completed:^(BOOL isSucc) {参考简版Demo中UserProfileEditViewController.m第152行代码
if (weakSelf) {
UserProfileEditViewController *strongSelf = weakSelf;
[strongSelf hideHud];
if (isSucc) {
[strongSelf.tableView reloadData];
[strongSelf showHint:@"修改成功~"];
} else {
[strongSelf showHint:@"修改失败~" yOffset:0];
}
}
}];
6.二级缓存处理流程图
由于能力有限,此方案难免有不妥之处,欢迎大家拍砖。
环信互帮互助-非官方 340452063
Q&A
问:如何安装第三方后端云存储服务 SDK?
答:安装还是比较简单的,可以参考第三方的文档,有不明白的可以看下教程
问:使用第三方云存储服务是否稳定、安全,比如不久他关闭了app会不会受影响?
答:云服务厂商一般不会关闭,退一万步来说,即使第三方后端云停止服务了也会提前通知,我们也可以将接口换成我们开发者自己服务器的api。类似的第三方云存储服务还有MaxLeap、bmob。
收起阅读 »
初步引入easeui遇到的问题
- duplicate 项目中重复依赖了包
- .so文件报错找不到
- Dex问题
- Error:Configuration with name 'default' not found
这个问题应该是gradle版本问题,进工作目录修改app的gradle信息 收起阅读 »
环信移动客服v5.5更新:机器人支持物流场景智能应答,微博渠道支持自定义菜单。
环信移动客服v5.5已经正式发布,包括机器人支持物流场景智能应答以及微博渠道支持自定义菜单等新特性。环信智能机器人已经能够智能识别访客的物流相关的咨询,现在您可以为特定的物流意图(物流差错、物流咨询、物流查询、物流催促)设置相应的回复。其中,“物流查询”这一意图支持多轮问答,机器人能够自动为访客查询物流状态,并直接将查询结果回复给访客。在环信移动客服系统绑定微博认证账号后,可以设置微博账号私信页面的菜单,并且设置粉丝首次关注自动回复。
环信移动客服v5.5产品更新说明:
- 客服模式
“留言”页面支持播放语音留言
当收到APP访客端发送的语音留言时,可以直接在移动客服系统的留言页面进行播放。
“访客中心”支持连续查看历史会话记录
当访客与当前客服有多条历史会话记录时,客服可以在访客中心页面连续查看这些历史会话的消息。
在客服模式下,选择“访客中心”,点击某位访客,在详情页点击“互动记录”,点击任意历史会话,可查看该历史会话的消息。消息界面提示会话开始、会话结束时间,点击“更多历史消息”、“查看下一条历史会话”可分别查看之前、之后的历史会话。
访客轨迹分析(增值服务)
访客轨迹分析功能收集访客在网站浏览的轨迹。对来自Web渠道的访客,客服接起会话后,可以直接在聊天窗口了解到该访客在发起会话前的浏览轨迹,从而判断客户的兴趣范围和偏好。
“访客轨迹分析”与“全站访客统计”为增值服务,只需先开通“全站访客统计”功能,并且在您的网站上安装一个数据统计SDK,即可使用“访客轨迹分析”。如需开通这两个功能,请联系环信商务经理。
关于SDK安装流程引导,请参考文档:全站访客统计。
探索移动客服
新增“探索移动客服”页面,新版本上线的功能将在此页面进行展示,登录后即可查看,不错过移动客服的任何更新。
管理员模式
机器人支持物流场景智能应答
环信智能机器人已经能够智能识别访客的物流相关的咨询,现在您可以为特定的物流意图(物流差错、物流咨询、物流查询、物流催促)设置相应的回复。其中,“物流查询”这一意图支持多轮问答,机器人能够自动为访客查询物流状态,并直接将查询结果回复给访客。
在管理员模式,选择“智能机器人 > 机器人设置”,点击“场景智能应答”Tab页,将您需要机器人回答的物流意图全部勾选开通。未勾选时,表示不需要针对该物流意图进行相应的回复。
如果您对意图定义有疑问,不妨将鼠标放在问号上,了解它的详细定义哟。
以下为开启物流差错、物流咨询、物流查询、物流催促这些物流意图,并设置“物流查询”意图的问答方式为多轮问答后,访客端咨询示例:
“留言”页面支持播放语音留言
当收到APP访客端发送的语音留言时,可以直接在移动客服系统的留言页面进行播放。
注意:APP端发送语音留言的功能需要调用环信的留言API自行集成。
“当前会话”支持分配、关闭会话
管理员在当前会话页面监控客服与访客的聊天过程时,可以将会话分配给其他客服,也可以根据实际情况关闭会话。
“访客中心”支持连续查看历史会话记录
当访客与客服有多条历史会话记录时,管理员可以在访客中心页面连续查看这些历史会话的消息。
在管理员模式下,选择“访客中心”,点击某位访客,在详情页点击“互动记录”,点击任意历史会话,可查看该历史会话的消息。消息界面提示会话开始、会话结束时间,点击“更多历史消息”、“查看下一条历史会话”可分别查看之前、之后的历史会话。
微博渠道支持自定义菜单和首次关注自动回复
在移动客服系统绑定微博认证账号后,可以设置微博账号私信页面的菜单,并且设置粉丝首次关注自动回复。
在管理员模式下,选择“渠道管理 > 微博”,点击“自定义菜单”Tab页,可以对菜单进行设置。最多可以创建3个一级菜单,每个一级菜单均可以跳转至网页或创建最多5个二级菜单。当设置一级菜单跳转至网页时,不可以再在该一级菜单下创建二级菜单。
在管理员模式下,选择“渠道管理 > 微博”,点击“粉丝首次关注自动回复”Tab页,设置自动回复消息。目前仅可以选择文字方式回复。
探索移动客服
新增“探索移动客服”页面,新版本上线的功能将在此页面进行展示,登录后即可查看,不错过移动客服的任何更新。
作为管理员,您还可以通过此页面快速定位到系统的其他位置,例如:快速设置接入渠道、快速定位到收发消息相关的设置页面、一键查看历史会话或统计报表等。
多租户管理后台
多租户管理后台为增值服务,如需开通,请联系环信商务经理。
支持查看租户的历史会话
多租户管理后台增加“历史会话”功能,支持管理员查看各个租户下所有客服的历史会话。
登录多租户管理后台(kefuorg.easemob.com),进入“租户管理”页面,选择任意租户,点击“历史会话”,可以查看该租户的所有历史会话。点击任意一条会话,可以查看该会话的全部消息。
Android客服工作台
Android客服工作台V2.3版本已发布!可前往环信官网下载。
支持显示微信、微博表情
Android客服工作台支持显示微信、微博默认表情。
支持发送语音消息
使用Android客服工作台时,可以对APP渠道的会话直接回复语音消息,沟通更高效。
注意:网页、微信、微博渠道的访客无法收到语音消息。
移动客服Android SDK
移动客服Android SDK 1.0.1 发布了!该Android SDK基于IM SDK 3.x,登录、发消息速度更快。提供内置会话相关UI,集成后可立即给移动客服发送文本、语音、图片、文件消息。
支持双通道:已集成双通道功能,确保不丢消息;
极简集成:集成移动客服通用功能,只需5分钟。
集成指南:集成指南
环信移动客服更新日志http://docs.easemob.com/cs/releasenote/5.5
环信移动客服登陆地址http://kefu.easemob.com/ 收起阅读 »
谈谈iOS使用环信的几个问题
1. 不过,需要注意的是环信的文档上是这样说的
pod "Hyphenate_CN" 是导入不了的, 因为找不到这个库。当然很多人都会先pod search "Hyphenate" 再选择需要导入的版本。
2.昵称、头像的设置
关于怎样设置昵称头像 环信官方也给出了解决方案http://docs.easemob.com/im/490integrationcases/10nickname
关于方法二 我还是遇到了一些问题:
手机先后登入两个帐号 (帐号A 、帐号B),那么帐号B的会话列表中就会出现帐号A的会话 ,如果帐号A发起了和帐号B的会话,甚至还会出现帐号B自己和自己的会话(这个很不明白)。
NSArray *conversations = [[EMClient sharedClient].chatManager getAllConversations];
既然这个是获取当前登入帐号的所有会话,那么为什么会出现这种状况? 我想是不是环信服务器里并没有保存我们的会话,仅仅是保存在当前设备上了?
收起阅读 »
猿生态十城巡回沙龙丨大连
无猿不生态
猿生态十城巡回沙龙丨大连
2016.11.12 13:30-17:00
高新园区数码广场1号软件园8号楼coco space
感受DevOps全新开发运维模式
畅聊云计算常用框架和虚拟化技术
体验PHP全新的语言和Slim框架
更有特邀嘉宾带你一探Ruby不为人知的技术特性和编程哲学
活动议程:
13: 00 – 13: 30
活动签到
13: 30 – 16: 30
技术分享 + 实战演示
16: 30 – 17: 00
抽奖 + 自由交流
讲师介绍:
✦自带电脑:在实战演示环节,讲师们将带领大家现场写代码、做demo,建议带上电脑。
✦AA餐会:活动结束后,与讲师和现场小伙伴们共进晚餐,交流、交友~~活动现场报名喔;-)
✦✦✦✦✦✦✦✦
更多精彩即将上线
报名链接:
http://devhub.cc/api/h5/activity/d1641f6021837c6dd700d1a9a6e69dfa
收起阅读 »
环信大客户部总经理陈磊--下一代客户服务软件的三大核心驱动力
陈磊:非常高兴有这么一个机会在这里跟大家分享环信过去几年所做的事情。我本身是贵州人,地地道道的遵义人,二十多年前求学离开遵义,之后就很少回来。如果我们环信所做的事情能够为家乡做点贡献,我将感到非常的自豪。今天现场各位如需要环信能够与您合作共同拓展业务,我们将非常的高兴为您提供服务。
今天我演进的题目是“下一代客户服务软件的核心驱动力”。
在讲这个内容之前,我们回顾一下客户中心发展的历程。最早客户中心都是语音的,大家都是电话进行客服咨询。在2000年左右,随着互联网的发展,有了网页客服的新方式与客户进行沟通。随着移动互联网的发展以社交媒体如微信的的客服沟通方式逐步流行起来,同时移动端客服也正被大家所广泛采纳和接受,这些客服类型发展到现在,对所有的客户中心面临的挑战即是需要一个将呼叫中心、网页、微信、移动端多渠道全面集成的多渠道客服系统。客服行业发展中遇到的5个痛点,1.我们需要一个统一的平台,解决客服人员不用在不同的客服渠道系统间进行不停的切换;2.随着多渠道的客服的使用以后,有更多的客户跟客服人员之间进行了更为密集的接触,造成我们客服服务成本逐渐的上升;3.再一个传统的语音呼叫中心都是打电话的方式与客户沟通,通过电话的方式进行沟通时间是完全独占的模式,效率很低;4.在移动网络环境很差的情况下,如何保证客户通过移动端客服和客服人员之间进行不中断的交流,技术上有很大的挑战。5.我们传统的客服都是用语音的方式,但如很多家政业务的投诉时仅用语音是描述不清楚问题的,这个时候需就要富媒体的方式来解决体验差的问题。
刚才给大家回顾了一下呼叫中心发展的情况和面临的痛点,现在怎么解决这些问题?环信在过去三年多做了很多有益的探索,环信通过机器人技术、通过大数据和移动互联网技术来推动呼叫中心行业的整个转型发展。现在我着重的讲一下推动呼叫中心向下一代发展的三大核心驱动力。
(图)大家很熟悉,有这么多渠道,有传统的语音,有网页、APP、网络、微信、微博的接入,但大多都是来自移动端。未来我们最主要的趋势,客户最主要的访问渠道将都是来自于移动端。每年双11绝大部分的定单都是来自移动端,这个趋势势不可当。
1、呼叫中心技术成熟没有门槛。
2、网页客服也没有门槛。
3、微信的接入依赖于微信的接口,也没有门槛。
真正的难点是在移动端APP的客户,国内能做好这个移动端APP的客服仅有1、2家,现在的客户都在通过移动端来跟客服人员进行交流。在座的客服总监是不是做好这样的准备,在建立好移动端客服为客户提供服务。
我们环信在移动端APP客服通过这几年的实践我们已经发现,IM即时通讯是移动端客服的最佳体现。1,支持富媒体消息,表现能力强。2,IM沟通是典型的异步沟通方式。3,使用IM客服,消息必达。我们的环信内部一个客服人员可以同时服务20个人,相比传统是1比20的效率提高。环信通过它自己在移动互联网IM独特的技术,能够有效的解决客户在移动端与客服的交流。
(图)IM这种服务模式已被实践证明是所有的客户最为接受的模式。国美在线APP通过环信提供的APP内置客服很好的服务了上亿用户。
今天我们大家经常说的事情就是全媒体客服,但是大家在谈的实际上是多渠道接入其仅是全媒体客服的冰山一角。真正的全媒体客服的关注的是客户通过跨渠道进来以后真正的体验和旅程是什么样的?这里想让大家先了解一下客户声音这款产品,这是基于自然语言分析、人工智能技术透析客户行为,然后去提升改善客户旅程的这么一款产品。目前客户中心更为关注的即是客户的体验如何?
核心驱动力二,客户声音。我们把所有多渠道的数据进行分析,然后会牵扯很多企业的部门的合作,为所有的部门来提供服务。我们可以看到,对于客服部门实际上通过他的情感分析,会看出来客户的满意度有多少?客户提出的问题是什么?对与销售部门来说,可以知道产品销售的热点是在那里?对于市场部门是通过主题热点会提取发现下一个热点是什么,会帮助我们更好做市场活动。客户声音这个产品,环信通过这几年摸索,实际上在三个方面的客户实践体验做得比较好。
一、可以通过分析今天所有的对话当中去提取前二十个关注热点最多的主题,去分析热点的问题。
二、可以把所有的热点问题拿出来,他的情绪是什么样的?如果有负面情绪提出来,然后分析这些问题。
三、更重要的是把发现这些问题的对话找出来,找到客户再去跟客户沟通。通过客户声音产品将对于发现问题、分析问题和解决问题整个事件处理的闭环完全打通,这样可以更好的提高客户满意度。
通过上面的介绍,大家都已经看到越来越多的客户跟客服人员通过这么多的渠道进行了密集的接触,对于客服中心来说成本在不断的提升,就必须要有一有效的方式来解决人力成本的不断提升。智能机器人技术将会是改变这种情况所产生的颠覆性创新的技术。核心驱动力三:智能客服机器人,17年客服机器人就会成为客服服务中一个非常重要的环节。
对于不需要做人工标记和人工维护的机器人单轮对话,很多企业都没有很好利用:很多企业的机器人的知识库维护工作量巨大。比如通常的一个问题,有几十种问法,但答案都是一个,但机器人没有自学习能力,这样就要员工在每天工作结束后去逐条整理知识库。我们环信的机器人技术是具有自学习能力的人工智能技术,比如几种对话问的都是同样的问题,环信智能机器人能够自动识别回答,并自学习添加到知识库,无需人工逐条编辑词条整理知识库,有效的推动了智能机器人在客服中心的初步落地。但具备多轮对话功能的机器人其实才能再客服领域发挥更大价值,也是鉴定客服机器人是否成熟的重要标准,比如面临退货的问题,不知道订单号,机器人可能会通过手机号码来识别,只有机器人能够满足多轮对话,机器人的技术才能够真正的进入到实际的应用当中。
目前的智能机器人,从实际上技术水平上看,还不能达到完全替代人工,所以现阶段最具有效率的智能客服一定是人机混合模式,在关键时刻还需要人工进行实时的参与。
简单的介绍一下环信,环信公司成立3年多时间,是一家年轻的企业级服务软件提供商,并于2016年荣膺“Gartner 2016 Cool Vendor”。产品包括国内上线最早规模最大的即时通讯云平台——环信即时通讯云,以及移动端最佳实践的全媒体智能云客服平台——环信移动客服。截至2016年上半年,环信即时通讯云共服务了82149家App客户,SDK覆盖手机终端5.64亿,平台日发送消息5.57亿条。 环信移动客服共服务了29437家企业用户,现已覆盖包括电商、O2O、互联网金融、在线教育、在线旅游、移动医疗、智能硬件、游戏等领域的Top10客户,典型用户包括国美在线、58到家、楚楚街、海尔、神州专车、新东方、链家自如客、泰康在线、号码百事通等众多标杆企业。
全球最具权威的的IT研究咨询机构Gartner的行业发展报告应该是这个行业中各企业都遵从的一个标准。其在中国境内选择环信做为2016年SAAS服务领域的唯一的cool vendor厂家,这个荣誉是对我们环信最大的认可。
(图)环信联合Gartner共同推出了客服行业研究的白皮书:下一代客户服务软件趋势。白皮中的内容参考了环信近3万家客服用户的最佳实践及Gartner在这个领域的研究成果。如果大家需要的话可以到展台进行登记,英文版的会先出来,中文版的相应随后出来,我们邮寄给大家。
《全媒体客户中心管理》,是环信与蜜芽VP张艳老师一起所做的国内第一本关于全媒体客户服务的著作,书中内容也是参考了环信过去在客服领域的实践以及张艳老师多么行业积累的心得,如果大家需要也可以到我们的展台上领取。
今天我的演讲就这么多,非常感谢大家!
收起阅读 »
为什么有些APP自带廉价感
▍何为廉价
一辆4万元的车,我们可以说是便宜的车,但是鲜有人说是廉价的车。我们会说廉价的爱情,但是不会说便宜的爱情。
对于“廉价感”一词来说,与通常我们所说的“粗糙”、“便宜”等形容词不同,它是一个难以量化的心智形容词,而且几乎没有统一的判别标准可言。 而对于APP来说,怎样才能叫廉价呢?要解决这个问题,从反面说明简单不少:名贵的东西,从设计开始,就是为了“打败时间”的。为了更长时间保住用户,其任何一个细节都在向用户传递一件事:我能让你一直用下去。那么对于廉价来说,笔者认为,其产生于“仅活于短时间”,即这种产品让用户感觉:这玩意儿随便用用,很快就可以抛弃的。廉价的东西外壳一般都是迎合时下流行的,其余细节大多粗糙,易快速死亡。
▍为什么有些APP会自带廉价感
☛疲劳感
我们都会对身边每日接触到的事物产生各方面的疲劳感,这样的疲劳感虽然不会直接的带来“廉价”这个感觉。但是一旦出现了一个基本功能属性与之完全一致的产品时(抄袭、模仿、换皮的圈钱产品目前是最为常见的),我们会因为对旧事物的疲劳感,而产生“廉价”的感觉。
☛定位
多在于产品的生产者与开发者对于产品本身定位以及基本属性认识的不透彻。也就是过分的商业化(过分的商业化在于过于看重销售方面,而忽略对于产品本身的思考)。例如一款社交类APP最关键的是让用户体验到产品的易于结交性与便利交流性,那么无论是UI还是功能,我们首要着重是在好友交互上,而不是其他自认为牛逼的无用功能上,你在用户希望拥有良好体验的功能上做low了,APP的廉价感自然而生。
☛细节
“细节决定成败”,这句话放在APP上仍为真理。很多开发者通常都过于小看了用户,对于APP的细节末枝,很多用户其实都能敏感,而往往这些细节,就能决定你这款产品的命运:有不少APP在第一次使用时都会自动进入教程页面,但很多APP却没有跳过这样的选项或者根本不明显,让我们无法取消导致被迫浏览/进行完引导,而对于这种情况来说,有不少朋友是抱以厌烦态度的,我相信有不少的朋友遇到这种情况会弃坑,毕竟仍有大量同类产品在后方等待着。
☛质量
廉价未必是低劣,但低劣一定会让人感到廉价,质量差体验注定好不到哪里去。秒杀团购整点哄抢的时候,遇见闪退;传送\下载重要文件时出现程序异常,又要重来….很多时候,一个APP总是在关键的时候出现质量问题,这让人抓狂又无奈,这样的情况发生频率稍高,大部分用户一定会有“这东西很渣”心声,淘汰也是必然选择。
▍总结
对于竞争激烈的移动应用市场来说,同类产品太多,相应来说对比就更加明显。而其实廉价感的根本便产于比较,开发团队以怎样的态度来制作一款APP,最终是能够通过我们使用而体现出来的。用匠人的精神去打造一款产品,敲细节重质量,尽力严格的APP测试,这才能从根本消除一款APP可能带有的廉价感。
用没用料,决定了是否便宜;
用没用心,决定了是否廉价!
TestBird - 手游和App自动化测试平台 收起阅读 »
短信团购,低价高质:短信验证码进入3分时代!
稳定高效的验证码是注册转化的基础,鉴于环信的用户们短信验证码业务需求强烈,环信经过严格的短信服务商筛选,为环信的用户团购了低价高质的短信验证码服务,需要的小伙伴们请填写详细信息,我们将在12小时内安排技术支持专员为您服务。
短信验证码团购地址http://www.easemob.com/sms 收起阅读 »
iOS 环信3.2集成单聊教程
前言
1、本教程对应环信即时聊天 iOS SDK V3.2.0 (2016-10-15)
2、请自行注册好环信APP_ID和APP_KEY
3、请自行下载好环信即时聊天SDK对应的版本(iOS SDK V3.2.0)
一、集成环信SDK
1、导入SDK
下载SDK到本地,进行解压,包含以下几个文件。
如果你的项目中需要用到语音电话和语音视频请把HyphenateFullSDK拖入你的工程;
如果你的项目中只不需要语音电话和语音视频请把HyphenateSDK拖入你的工程;
这个两个只需要拖入一个,区别就是一个包含语音电话、视频,一个不不含,其他的都是一样的。
2、添加对应的依赖库
(1) 在 Build Phases -> Link Binary With Libraries 添加以下依赖库:
CoreMedia.framework
AudioToolbox.framework
AVFoundation.framework
MobileCoreServices.framework
ImageIO.framework
libc++.tbd
libz.tbd
libstdc++.6.0.9.tbd
libsqlite3.tbd
libiconv.tbd
如果你选择的是不包含语音电话、视频的SDK,最后一个依赖库(libiconv.tbd)不需添加。
(2) SDK 不支持 bitcode,向 Build Settings → Linking → Enable Bitcode 中设置 NO。
3、登录环信
在AppDelegate.m 中添加欢喜初始化和登录的代码,如果编译成功,则说明你导入SDK成功了。
#define EaseMob_Appkey @"1101#testnickname" //环信AppKey提醒:记得在plist文件中设置https请求喔
#import "AppDelegate.h"
#import "EMSDK.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//AppKey:注册的AppKey,详细见下面注释。
//apnsCertName:推送证书名(不需要加后缀),详细见下面注释。
EMOptions *options = [EMOptions optionsWithAppkey:EaseMob_Appkey];
options.apnsCertName = @"";
[[EMClient sharedClient] initializeSDKWithOptions:options];
EMError *error = [[EMClient sharedClient] loginWithUsername:@"yuancan001" password:@"123456"];
if (!error) {
NSLog(@"登录成功");
}
return YES;
}
4、添加EaseUI文件 要想实现环信的及时聊天,只加入SDK是不够的,还需要添加其他的一些相关的文件。回到我们之前下载环信SDK的文件中,有一个EaseUI的文件,把这个文件加入你的工程中。
这个文件夹中包含了一些与聊天相关的类,比如说聊天的界面、聊天的键盘等,总之是为了帮助开发者快速实现聊天功能。 编译一下,结果编译失败,因为还需要做一步操作,添加pch文件的路径。
EaseUI目录下有一个pch文件,你把它的路径添加到Prefix Header中。怎么添加呢?最简单的办法,就是先选择EaseUI-Prefix.pch文件,然后按住它,把它拖过去。不过这个要看人品,人品好一次就可以拖成功,如果没有拖成功,就多试几次。要是人品太差,就只能手动添加了
$(SRCROOT)/EaseMob3.2/EaseMob/EaseUI/EaseUI-Prefix.pch再编译一下,就可以成功了。
$(SRCROOT):这是一个宏,代表你这个项目文件的相对路径;
EaseMob3.2:这个是我的工程名,需要替换成你自己的工程名;
EaseMob/EaseUI/EaseUI-Prefix.pch:这个是pch文件在工程中的相对路径,需要替换成你自己对应的.
二、实现单聊
集成环信SDK,我们已经完成了第一步工作,接着我们来实现一下聊天的功能。
1、添加与聊天相关的文件
环信官方提供的Demo中集成了所有的功能,对于开发者来说既是一件好事也是一件坏事。之所以说是好事是因为所有功能都有,之所以说坏事是因为功能太多,都杂糅在一起,对于新手来说却是感觉无从下手。下面,就随我一起慢慢来深入了解环信。
实现单聊还需要添加一些文件,这些文件我们可以从官方的Demo中拷贝过来。我们需要添加的文件叫做 Chat,Chat目录下包含两个文件夹。ChatList里面的东西是与回话列表相关的,ChatView里面的东西是与聊天界面相关的 , 把Chat整个文件夹都拖入工程中。编译之后,你会发现会出现很多报错的,不要怀疑你自己,这是正常的。因为这些文件是从环信官方Demo中拷贝过来,里面用了很多其他的文件,但是我们不需要那些文件,没有添加到我们的工程中,所以会报错。其实,这几个步骤很关键,但是官方文档却没有说明,估计把新手坑死了,幸亏有小编来拯救你们,哈哈。这里好心的小编提供一个已经处理好的下载Chat文件,下载可以直接使用。不然,你就需要自己手动去注释一些报错的地方,知道编译成功。
2、修改pch文件
在我们之前用的那个EaseUI-Prefix.pch中添加一些头文件:
#ifdef __OBJC__3、测试单聊
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
//#import "ChatDemoUIDefine.h"
//#import "EMAlertView.h"
//#import "TTGlobalUICommon.h"
#import "EMSDKFull.h"
#import "EaseUI.h"
#endif
(1) 在AppDelegate.m 中创建一个UINavigationController :
#define EaseMob_Appkey @"1101#testnickname" //环信AppKey
#import "AppDelegate.h"
#import "EMSDK.h"
#import "ViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//AppKey:注册的AppKey,详细见下面注释。
//apnsCertName:推送证书名(不需要加后缀),详细见下面注释。
EMOptions *options = [EMOptions optionsWithAppkey:EaseMob_Appkey];
options.apnsCertName = @"";
[[EMClient sharedClient] initializeSDKWithOptions:options];
EMError *error = [[EMClient sharedClient] loginWithUsername:@"yuancan001" password:@"123456"];
if (!error) {
NSLog(@"登录成功");
}
ViewController *vc = [[ViewController alloc] init];
UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:vc];
self.window.rootViewController = navigation;
self.window.backgroundColor = [UIColor whiteColor];
return YES;
}
OK,完了,到点了吃中饭去了。
欢迎关注我的博客,原文地址
收起阅读 »
【产品快递】Web IM V1.1.3发布,支持自动重连
- 功能改进:
SDK支持 Windows SDK。http://www.easemob.com/download/im 新增黑名单功能。获取聊天室列表: 支持分页、下拉刷新,新增以下2个参数:pagenum 和 pagesize。调试更方便,webpack 支持开发和生产模式。`npm run dev`:开发模式,支持热加载,启动一个供调试的webserve http://localhost:3000。 `npm run prod`:生产模式,编译速度更快。群组增加以下功能:创建群组、修改群组名称、修改群组简介、群组成员管理、加入公开群。strophe 从 v1.2.2 升级到 v1.2.8,在生产模式使用 strophe-1.2.8.min.js, 在开发模式使用 strophe.js。
支持自动重连: 在 webim.config.js 文件中新增相关参数 `autoReconnectNumMax` 和`autoReconnectInterval`。
- Bug fixes:
DEMO
增加 `babel-core/browser-polyfill.js`文件,修复了 IE 不支持 HTML5 elements 的 bug。
修复了有未读消息时点击联系人不生效的bug。
修复了strophe.js v1.2.8在IE9中使用BOSH会报错的bug。
https://github.com/strophe/strophejs/issues/213
SDK
修复了存在大量离线消息时收发消息延迟的bug。客户端将发送ack应答消息的速度限制在5个/秒,不影响其他正常消息。
将心跳消息从空body的 json message 切换为 ping/pong iq。前者会作为离线消息被XMPP Server缓存。
webim体验:http://webim.easemob.com/
版本历史:更新日志
SDK下载:点击下载 收起阅读 »
环信连续三届荣膺“易观之星”大奖,人工智能大数据优势凸显
环信荣膺2016“易观之星”大奖
从“互联网化”到“互联网+”,从“拟人智能”到“数据是新能源”,易观的每一个理念都对产业带来重大改变。作为即时通讯云领域和SaaS客服领域的先行者,环信用即时通讯云场景化社交,连接人与人。用全媒体智能客服重构现代商业,连接人与企业。环信和易观一样在不断践行创新,每次突破都给行业带来了翻天覆地的变化。
环信移动客服首推的客户声音产品运用自然语言解析,人工神经网络深度学习等人工智能技术,对来自多种渠道的非结构化数据源进行客服业务的特征提取,主题聚类解析,情感分析建模。从而帮助企业挖掘和分析客户服务中的热点话题,发现服务运营问题,寻找畅销或问题产品,洞察销售机会。比如,在环信客户声音系统中,主题关键词热度越高,说明用户关注度就越高。关键词对应的情感越负面,说明用户的体验感就越差。企业可以优先解决用户最关心,体验感最差的产品和服务问题。环信客户声音系统可以帮助企业识别和改善客户旅程的各个阶段。
基于自然语言处理和机器学习技术的环信智能客服机器人,能够辅助或代替人工客服精准回答超过80%的常见问题,极大降低企业客服人力成本。环信智能机器人使用海量数据对模型进行训练,并借助客服系统中访客和客服的实时反馈来增强学习,精准识别用户意图,帮助人工客服回答各种问题无需人工标记和人工维护的机器人单轮会话,极大降低客服机器人的维护成本。同时,环信智能机器人支持上下文语义和多轮会话,并预装多行业的领域知识,如电商行业的物流状态查询模型,产品保修会话模型等。这种基于行业领域和业务模型的多轮会话能力,相比单轮会话,进一步扩展了客服机器人对复杂客服业务场景的自动支撑能力。
截止2016年上半年,环信已经服务了八万多家客户,现已覆盖包括电商、O2O、互联网金融、在线教育、在线旅游、移动医疗、智能硬件、游戏等领域的Top10客户,在客服领域的典型用户包括国美在线、58到家、楚楚街、海尔、神州专车、新东方、链家自如客、泰康在线等众多标杆企业。积累了大量人工智能和大数据在即时通讯云和客户服务行业落地的最佳实践。
随着“互联网+”国家战略的不断深化,人工智能的崛起以及大数据分析思想将助力企业拥抱更广阔的互联网+未来。近期,李克强总理在出席会议时表示:“以大数据为代表的创新意识和传统产业长期孕育的工匠精神相结合,使新旧动能融合发展,并带动改造和提升传统产业,有力推动虚拟世界和现实世界融合发展。”未来在技术和服务的双动力驱动下,大数据和人工智能产业的发展将更加迅速,更加产业化、垂直化和精准化。同时,企业级服务的大数据和人工智能时代也即将全面开启。
关于“易观之星”
被誉为大数据行业的“奥斯卡”,易观A10峰会传承至今已有8年历史。易观之星颁奖典礼作为A10峰会上最为瞩目的板块充分利用大数据进行行业洞察,基于易观千帆、易观方舟等易观大数据产品,以用户规模、企业增速等标准进行多重考评,用以表彰和鼓励创新有潜力的企业和应用。本届评选历时两个多月,历经资格征集、资格复核、终审评奖三轮审核,环信凭借其在即时通讯云领域的绝对优势以及SaaS客服领域的厚积薄发连续第三年荣膺“易观之星”大奖。 收起阅读 »
关于会话列表的置顶聊天
其实刚刚开始 ,我自己在想,我是不是要去做出类似于QQ那种的滑动,然后显示置顶和删除。
我就开始写,写完了之后然后去置顶,取消置顶,其实是有用的,但是为什么我到最后还是没有选择这个效果呢?
因为这个最后是要到Adapter里面去设置这两个按钮,我本人并不喜欢这东西放到Adapter里面,接下来强迫症来了,直接把代码全部删除,换一种思路..........我想到了微信,点击弹出一个菜单,和dialog很很像的一个功能。
好,来跟着我一起走一下思路。
首先是,要实现置顶聊天,那么我们就要有两个List集合,一个是置顶的,一个是不是置顶的,然后置顶的是需要一个小小的数据库去保存置顶的对话人的UserName;这里,环信给出了EMConversation的一个方法,带大家看看技术文档。
这里框出来的就是我们要用的至关重要的方法,特别重要,
看下这个文档里面说的非常清楚,也就是扩展字段,设置一个扩展字段我们才知道这条Conversation的特别之处,然后去判断这个会话有没有设置扩展消息,有的话,那就排到置顶的那个集合里面去。
接下来我们要准备的是数据库
也就是这两个东西,准备就绪,蓝后 ..... 要开始大动,也就是把关于会话列表里面的东西全部放到项目里面来。
所要动的就是这3个类,全部移动到项目中,因为数据库要在Adapter和ListView里面操作,这一步很简单,动动手就行。
那么这些全部做完之后,我们开始写代码了,仿照通讯录的数据库来
这里就是getset,然后在DemoHelper里面
蓝后,再Application里面去给它暴露出两个方法。
好了,数据库的东西是配置完成了,那么,问题就来了,怎么去启动数据库?
这样就添加了数据库,注意,这里添加了数据库之后,然后再去真正的写置顶的代码了。。。。
首先我们先看看会话列表界面
在setupView方法中,别忘了获取数据库里面的置顶会话。
这里直接贴出来了ConversationListFragment,这里就是把EaseUI里面的EaseConversationlistFragment里面的内容,然后BaseFragment也就是EaseBaseFragment里面的内容了。
主要加载会话的方法就是这个方法,主要代码就是synchronized里面的内容,这里很容易就能够理解For循环里面的内容,然后我们要在这里面判断,有没有会话是包含扩展字段的,有的话就将包含扩展字段的会话放入top_list这个集合里面;蓝后你们可以看到topList,这个List就是图10里面的topList,topMap也是图10里面的。蓝后,我们可以看到排序方法,也就是会话列表的排序方法(sortConversationByLastChatTime),这里我自己写了一个排序方法,并没有用到Pair。
其实这两个方法是一样的,一样的效果。
那么接下来,就是看看ConversationList
最主要的就是这个init方法,也没什么说的。。那么接下来就到ConversationAdapter
这里就和EaseUI里面的那个EaseConversationAdapter有点不一样了,EaseConversationAdapter里面是继承ArrayAdapter的,这里是继承BaseAdapter,在这里使用BaseAdapter为了方便大家能够理解。
我们只需要在getItem和getCount里面做点手脚就可以了
好了,到这里就完成了整个置顶会话的显示,那么接下来,我们就要写一下置顶功能了,这里很有必要说明下,个人意见,在写会话列表的时候,推荐使用一个Fragment去继承EaseConversationListFragment。继承之后我们就可以重写setUpView方法,在这方法里面我们进行一系列的操作。
这里就是用到的长按事件,然后显示一个Dialog,在Dialog里面去实现置顶功能的操作。这里由于代码过长,所以截两张图。。。。
图18主要就是Dialog的显示
在这里就是删除会话等这个按钮的点击事件。
在里就是置顶的点击事件了。。
好了 到这里已经完成了置顶的全部代码展示了。个人感觉还是很详细的,如果还是不懂,那就环信互帮互助-非官方 340452063来这,给你解答你的问题 收起阅读 »
聊天工具的架构分析
随着统一通信的发展,聊天工具有了更好的发展,其中要算手机和网上的即时聊天工具的发展了。手机主要是3G的开发,有了统一通信技术的支持,我们才可以实现第三代的通信,但是这里要说的另一个方面,关于聊天工具的。
下面就聊天工具开发聊聊现有聊天工具的架构,需要先说明的是TCP和UDP这两个协议,因为只有先确定了这两个最重要的协议,才可以确定一个即时聊天软件的架构。首先举两个例子,即时聊天软件MSN使用的就是TCP,然而QQ使用的是UDP协议。其实这两者的最大区别就是TCP的可靠保证,是它的三次握手机制,这一机制保证校验了数据,保证了他的可靠性。而UDP就没有了,所以不可靠。比如说,在MSN上,要传输文件,首先是发送文件,对方确定接受,然后再发送,这样,三次握手。但是UDP不同,它是直接发送,不管对方是否同意,还是会发送,所以很不安全,但是这是由于这样,也保证了传输的速度,不会受到安全性的限制。而TCP一般会保证发送和收到,更适合一些对安全性质需要较高的工具软件。但是为什么同样是即时聊天性质的软件,MSN使用的是TCP,而QQ的则是UDP呢?通过思考,我认为,国外的网络环境相对国内的好很多,安全性也有保证,而国内的网络环境不如国外,还有很多代理服务器,再加上网通和电信,造成了很多不便,如果使用的是TCP的话,那么我们很多用户将无法使用这个软件,或者是在传输文件和数据的时候将会遇到很多的困难,甚至无法传送文件,所以QQ使用了UDP。其实呢,大多聊天软件例如QQ,不光是使用了UDP,在某些方面也用到了TCP,就像QQ的文字聊天协议。
统一通信中即时聊天软件的架构,由三部分组成,DispatchServer(DS) Notification Server (NS)和Switchboard Server (SB)。
DS采用的负载均衡方式应该比较简单,通过DNS解析来做负载均衡。并且由于在DS上的连接都是短连接,保持时间非常短,所以应该DS服务器的数量应该不会很多。由于DS必须要返回一个可用的NS IP,那么内部应该还有其他种类的服务器来保存当前所有可用的NS服务器,以及这些NS服务器上的负载。通过DS这一层来为接下来的NS做负载均衡。NS连接均为长连接,所以在这一层上的负载由DS来调节。如果NS负载太大,新客户连接上DS时会返回其他相对空闲的NS服务器。当然NS服务器之间也有相互通讯的机制也是少不了的,比如上下线通知、对话发起等等。SB连接的时间介于NS和DS之间,其负载由NS来作控制。对话完成后和SB之间的连接就关闭了。不过由于所有的对话都在SB上进行,MS的服务器资源再强也会吃紧,所以现在新版的MSN Messenger都加入了P2P Message类型,在发起对话的时候会判断如果双方都支持sustain ,则会直接点对点连接连接,绕过SB这一层。
在及时软件的交互过程中,首先客户端向服务器发送一个请求登录令牌的数据包,服务器返回登录令牌。这个令牌是在服务器端生成的,和客户端的IP地址,版本信息等数据相关。在客户端得到登录令牌后,就会向服务器发送一个包含登录信息的登录请求,服务器首先会查看客户端的号码、IP地址和版本是否可以在本服务器上进行登录,如果可以就验证客户端的登录信息是否与服务器上保存的登录信息一致,如果一致就向客户端返回一个连接成功的数据包,不匹配则返回登录失败。这就是整个的登录的实现过程。
收起阅读 »
移动OA后台最方便的流程图js组件
谈到OA,我就要提一下其中最重要的一个部分“工作流引擎”。
js工作流组件很多,但是要找一款适合自己的却有点难,所以,咬咬牙,决定自己做一款。
本着“不重复造轮子”的原则,我打算还是基于gojs封装流程图组件比较现实一点。
基于GOJS封装的流程图设计(展示)工具类,主要分为两个工具类:
工具库依赖于go.js、jquery以及layer.js
http://gojs.net/
http://jquery.com/
http://layer.layui.com/
希望支持FlowDiagram的童鞋能够到Github给我们一个star_^
https://github.com/mengmakies/FlowDiagram
在线demo http://www.c3dn.net/gojs/samples/demo.html
流程设计器操作指南:
在任意位置双击设计器空白处:新建步骤;
选中步骤,单击右键:弹出右键菜单;
鼠标滑过步骤,显示连接点,拖动连接点即可创建新的连接线;
鼠标滑过步骤:显示tooltip。
流程图数据:
{ "class": "go.GraphLinksModel",
"modelData": {"position":"-5 -5"},
"nodeDataArray": [
{"key":"1", "text":"开始", "figure":"Circle", "fill":"#4fba4f", "stepType":1, "loc":"90 110"},
{"key":"2", "text":"结束", "figure":"Circle", "fill":"#CE0620", "stepType":4, "loc":"770 110"},
{"key":"3", "text":"填写请假信息 ", "loc":"210 110", "remark":""},
{"key":"4", "text":"部门经理审核 ", "loc":"370 110", "remark":""},
{"key":"5", "text":"人事审核 ", "loc":"640 110", "remark":""},
{"key":"6", "text":"副总经理审核 ", "loc":"510 40", "remark":""},
{"key":"7", "text":"总经理审核 ", "loc":"500 180", "remark":""}
],
"linkDataArray": [
{"from":"1", "to":"3"},
{"from":"3", "to":"4"},
{"from":"4", "to":"5"},
{"from":"5", "to":"2"},
{"from":"4", "to":"6", "key":"1001", "text":"小于5天 ", "remark":"", "condition":"Days<5"},
{"from":"6", "to":"5"},
{"from":"4", "to":"7", "key":"1002", "text":"大于5天 ", "remark":"", "condition":"Days>5"},
{"from":"7", "to":"5"}
]}
1.流程图设计 flow-desinger.js
var areaFlow = document.getElementById('mySavedModel');
var myDesigner= new FlowDesigner('myFlowDesignerDiv');// 流程图设计器
myDesigner.initToolbar('myPaletteDiv');// 初始化控件面板
myDesigner.displayFlow(areaFlow.value);// 在设计面板中显示流程图
2.流程图展示 flow-display.js
var areaFlow = document.getElementById('mySavedModel');详细代码请参考目录下的html文件:/gojs1.6.10/site/samples/_demo.html
var myDisplay = new FlowDisplay('myDisplayDiv');// 流程图显示器
var flowPath = '3,4,6,5';// 3,4,6,5是步骤的id,最后一个步骤为"待处理"或"已完成"的步骤
var isCompleted = false;// "待处理"或"已结束"
myDisplay.loadFlow(areaFlow.value);// 显示流程图
myDisplay.animateFlowPath(flowPath, isCompleted);// 动画显示流程路径
http://git.oschina.net/markies/FlowDiagram/raw/master/gojs1.6.10/site/samples/_demo.html
收起阅读 »
猿生态十城巡回沙龙丨天津
开发环境、测试环境、生产环境存在着怎样的鸿沟?如何通过DevOps既保持服务的稳定运行,又为开发者提供便利?在轻松跨越C10K需求的今天,怎样快速基于Wordpress打造全平台软件?如何基于OpenResty快速实现高性能Web服务器?...... 无猿不生态猿生态十城巡回沙龙
精彩继续 10月29日 天津市南开区白堤路42号百豪视听广场3楼草帽众创空间
活动报名:点击报名
活动议程
13: 00 – 13: 30 活动签到
13: 30 – 16: 30 技术分享+实战演示
16: 30 – 17: 00 抽奖+自由交流讲师介绍
Tips
✦自带电脑:在实战演示环节,讲师们将带领大家现场写代码、做demo,建议带上电脑。
✦AA餐会:活动结束后,与讲师和现场小伙伴们共进晚餐,交流、交友~~活动现场报名喔;-)
本场活动将通过云犀直播,在斗鱼、战旗、爱奇艺、熊猫TV等多个平台全程同步直播,扫描下方二维码即可收看
收起阅读 »