//前言:仿weixin实现一个即时通讯的案例,支持版本7.0以上

"准备工作 创建项目时使用git"
/*
显示隐藏文件,看到git的文件夹
defaults write com.apple.finder AppleShowAllFiles Yes && killall Finder
defaults write com.apple.finder AppleShowAllFiles No && killall Finder 设置git的(全局)用户与邮箱
git config --global user.name Fung
git config --global user.email fung@qq.com
*/ /**
掌握的知识点
1.配置应用程序的iPad与iPhone的各个设备的AppIcon 2.配置应用程序的iPad与iPhone的各个设备的启动图片(LaunchImage)
*/ 一、设置AppIcon与LaunchImage
> 设置iPhone-iOS8./iOS7. iPad-iOS7.0的AppIcon
> 设置LaunchImage时,
a> Xcode6在TARGETS中去除Launch Sreen File里的值
b> 在Lauch Images Source中添加在assests中的启动图片
c> iPhone横屏与iPad横屏的启动图片不设置
d> iPad1024x768图片不设置
"因为微信资源包没有找到对应尺寸的图片,说明有些启动图片可以不用设置"
"微信iPad运行,如果是横屏启动时,是没有显示图片的" 二、实现登录排版
> 创建一个Login.storyboard,使用导航控制器包装登录控制器
> 自定义导航控制器,设置导航条背景与状态栏样式
> 添加登录框容器,使用AutoLayout,固定大小,顶点间距,水平居中
> 使用Images.xcassets对登录按钮的背景图片进行slicing(切片操作)
> 设置密码的文本输入框样式
*设置borderStyle = UITextBorderStyleNone;"storyboard设置,提醒为什么不能设置高度"
*设置textFiled的高度42 *设置backgroudImage为拉伸后的图片"代码实现,因为背景图片放在xcassets时,xcode会崩溃" *设置密码文件框左边的图片
设置图片控制的尺寸、图片内容模式
设置文本框的leftViewMode为总是显示(UITextFieldViewModeAlways)"否则不显示左边的view" > 对控制器view进行拖拽手势监听实现上,实现登录输入框的上下滑动及反弹 "注:提交git版-微信目录结构分层+登录界面排版" 三、注册界面排版
> 添加一个注册框容器,设置顶部,左边,右边距离固定,高度固定
> 添加手机与密码文本输入框、注册按钮,并设置背影图片,文字居中显示
> 设置按钮的可用状态
"注"
> 判断当前设置是否为iphone,如果为iphone,注册框容器的左右两边间距为10
//[UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone
> 设置导航条Item的样式-白色字体 四、实现其它登录排版
>在登录界面的底部添加 "其它方式登录>"按钮
> 将"注册界面"的视图拷贝到新的控制器
> 去除横屏,这样在ipad上可以旋转,iphone上不可以 五、完成主界面排版[MainStoryboard]
> 微信、通讯录、发现、我[拖四个导航控制器到Tabbar控制器]
> 设置tabbarBtn的背景及文字,及导航栏的背景
微信 tabbar_mainframe/tabbar_mainframeHL
通讯录 tabbar_contacts/tabbar_contactsHL
发现 tabbar_discover/tabbar_discoverHL
我 tabbar_me/tabbar_meHL
"注:选设置普通状态的图片与文件,有时间再自定义tabbar"
> 设置全局的状态栏样式
*在info.plist中添加View controller-based status bar appearance=NO
*在自定导航控制器是设置[UIApplication shareApplication].statusBarStyle = UIStatusBarStyleLightContent
*设置导航栏标题 字体为粗体18/颜色为白色,
iOS7或者iOS以上使用NSFontAttributeName/NSForegroundColorAttributeName属性
iOS7以下UITextAttributeFont/UITextAttributeColor
//前言:仿weixin实现一个即时通讯的案例,支持版本7.0以上
/*
日志 git log
恢复指定版本 git reset --hard 版本号
查看指令使用记录 git reflog
*/ "未完成"
/*
* 前题:备置mysql密码时参照 "资源/MySql命令行/设置mysql的root密码"
*/
六、使用xmpp框架实现登录功能
> 导入框架
a> 导入CocoaLumberjack 日志框架 "无须依赖"
b> 导入CocoaAsyncSocket 底层网络框架,实现异步socket网络通讯
"依赖:CFNetwork&Security框架"
c> 导入KisssXML XML解析框架
依赖libxml2.dylib
"还需要配置编译选项""
"Other Linker Flags = -lxml2"
"Header Search Path = /usr/include/libxml2"
e> libidn 直接导入
f> 导入下面四个文件夹
Authentication
Categories
Core
Utilities
"依赖libresolv.dylib"
g> 添加Extensions
h> 将Sample_XMPPFramework.h导入,并将其改名为XMPPFramework.h
"注在xcode6中系统有的Framework可以不用添加,但是dylib一定要添加" > 实现登录
*> 选分析登录的步骤
*> 初始化xmppStream核心类,并添加代理为全局队列dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, )
*> 连接服务器时,设置主机,端口与登录账号[先写死代码]
*> 在"代理中连接成功"时发送密码[先写死代码]
*> 在"代理中授权成功"时, 打印
*> 在"代理中授权失败"时, 打印
*> 在"代理中授权成功"时,通知用户上线
*> 官方把登录数据放在沙盒里 "我们放在单例对象"
*> 登录成功用block的方式通知 "其它方式登录控制器"
*> 在其它方式登录控制器中,用MBProgessHUB 显示进度,"在IPad中显示一定要用toView的显示方法,因为窗口没有横竖屏的概念,只有控制器的view才有横竖屏的概念"
*> 隐藏HUB时,引出block是在子线程调用的,不能直接刷新UI
*> 接收block的成功登录时,切换到主界面,"在切换到主界面前,要清除当前模态窗口" 强调自己写的block引用控制器时,要用__weak 七、使用xmpp框架实现注册功能
*> 先分析注册的步骤,与登录形成一个对比
*> 在AppDelegate中添加用户注册的方法
*> 在AppDelegate中添加一个userRegister的属性
*> "连接服务器,连接成功后判断userRegister在代理中做登录还是注册的操作"
*> 在代理中监听注册成功还是失败,再以block的方式通知"注册控制器"
*> "注册控制器" 再以 "代理的方式" 通知 "登录控制器",并设置label的注册后的帐号
*> 抽取 "其它登录控制器" 登录的代码 到一个父类,实现登录 八、细节
> 用户注销[断开连接,回到登录界面]
*> 通知用户下线、断开连接、显示登录界面 > 用户登录过,未注销,不管是程序在后台还是重新启动,直接来到主界面
> 用户登录过,未注销,退出台后时与服务器断开连接,获取焦点时获取自动
"在UserInfo单例中添加一个login属性来记录登录状态"
> 登录界面设置上次登录的帐号 九、自动登录提示
> 分析自动登录监听中的情况
/*
1.开始连接服务器
2.连接失败
3.登录成功
4.登录失败
*/ > 在历史控制器中添加通知监听
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(autoLoginStatus:) name:WXAutoLoginStatusNotification object:nil];
> 在APPDelegate中发送通知 > "自动登录时延迟两秒登录,好演示效果,连接的主机用域名比较慢" > 转圈圈指示器是否转还是停止,应该放在主线程中 十、socket后台支持
/*
* 注 iOS8不用写支持也可以后台支持
* iOS7 和 iOS8 下都要演示
*/
> "Required background modes"的key,值设置为voip,来指定类型
> xmppStream.enableBackgroundingOnSocket = YES
> xmpp代理接收到消息时,如果不在前台实现本地通知
[UIApplication sharedApplication] applicationState] != UIApplicationStateActive
设置本地通知的内容(用户名\n内容前多少个字) 声音(default) > 在iOS8要注册通知类型registerUserNotificationSettings
//模块

一、自动连接模块
> 当用户网络不稳定时,如果断线,自动连接
> 打开自动连接模块在xmppframework.h文件中打开XMPPReconncet
> 在设置xmppStream时,开始自动连接并"激活"
> "引用官方示例程序的teardown方法" 释放资源 二、电子名片模块与头像模块
> "查看电子名片的模型文件,数据结构"
> 什么是电子名片模块/头像模块
> 在xmppframework.h中打开电子名片模块/头像模块的头文件
> 在设置xmppStream中,设置电子名片模块/头像模块并激活,
"获取用户的个人信息,里面是不是有头像,也一并获取"
> 在teardownxmppStream做相应的资源释放
> 在 "Me"中打印 doc,不要使用SimPhodlers
> 在document看CoreData生成的数据库,用SQLiteManager查看
> 在"我" 中添加静态单元格,显示图片与账号
/*
》XMPPvCardTemp *myvCard = xmppDelegate.vCardModule.myvCardTemp;
》warning 看PPT,查看有些数据是没有解析的
》取消头像,显示日志,使用XMLJSON格式化工具格式化,解释电子名片的电话未解析
*/ 三、电子名片详细页面进行设置
> 进入详细页面进行静态表格的排版
> 绑定数据
> 如果识别不同类型cell的点击,设置每个cell的tag不同
> 点击cell,取消选择中、进行头相选择
> "编辑信息界面,传一个cell到编辑控制控制器,在调用代理时时调用
[self.profileCell layoutSubviews];//重新刷新cell就会显示detailTextLabel,因为没文件,默认是不会创建label"
> 保存数据 四、获取好友列表(花名册)
> "查看花名册的模型文件,数据结构"
> 在xmppframework中打开花名册模块
> setupXmppStream中添加花名册模块
> teardown中释放花名删模块
> 在联系人控制串获取好友列表
/**
* 获取好友列表时,一定要添加过滤条件?,因为多人登录,可能用同一个数据库?
* 答案不会,演示数据,每次登录会清除以前的好友,做得不够好,实际开发自己创建数据库来管理
*/
> "使用CoreData的普通方式获取好友列表"
> 使用NSFetchedResultsController 获取好友列表
> "在cell中演示sectionNum的在线状态,然后在排序中多添加个sectionNum的升序",从而演示出NSFetchedResultsController的作用 > 获取头像 自定联系人Cell
if (friend.photo) {
cell.imageView.image = friend.photo;
}else{
NSData *data = [xmppDelegate.vCardAvatarModule photoDataForJID:friend.jid];
if (data) {
cell.imageView.image = [UIImage imageWithData:data];
}else{
cell.imageView.image = [UIImage imageNamed:@"login_defaultAvatar"];
}
} 五、添加好友+删除好友
> TextField左边的图片放在分类里
> 是否添加为手机号友
/**注:写在分类UITextField里
NSString *telRegex = @"^1[3578]\\d{9}$";
NSPredicate *prediate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", telRegex];
return [prediate evaluateWithObject:self.text];
*/ > 不能添加自己为好友
> 添加的好友已经存在
[xmppDelegate.rosterStorage userExistsWithJID:friendJid xmppStream:xmppDelegate.xmppStream]
[xmppDelegate.roster subscribePresenceToUser:friendJid]; > 删除好友
[xmppDelegate.roster removeUser:friend.jid] 六、聊天界面排版
> 使用VFL排行聊天表格与输入框
tableViewHConst "H:|-0-[tableView]-0-|"
inputViewHConst "H:|-0-[inputView]-0-|"
vConst "V:|-0-[tableView]-0-[inputView(50)]-0-|" > 键盘监听,判断iphone还是ipad 再判断ipad的是横屏还是竖屏
UIInterfaceOrientationIsPortrait(self.interfaceOrientation)
#define iSiPhoneDevice ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)
"重点"
> 返回按钮监听
*> 设置textfiel的代理 实现textViewDidChange
*> 判断是否有换行符 "\n"
*> 有就去除掉首尾的空白字符和换行字符
[textView.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; // 七、获取聊天消息+发送聊天消息
"聊天消息模块:什么是聊天消息模块,xmpp帮我们做数据存储 查看0135模块的数据结构"
> xmppframework.h中打开消息归档模块与消息数据存储
> 在setupXmppStream中消息归档模块与消息数据存储
> 在teardown中释放消息归档模块与消息数据存储
> 在通讯录控制器传递好友jid到聊天控制器
> 从数据库加载聊天数据,一次性加载全部"使用NSFecthResultsController"
"强调:查询时要带条件,一定要属于当前登录用户与好友的聊天记录"
> 发送消息
XMPPMessage *message = [XMPPMessage messageWithType:@"chat" to:self.friendJid];
[message addBody:msg];
[xmppDelegate.xmppStream sendElement:message]; > 聊天数据滚动到底部
> 讲解怎么判断自己发送的消息还是别人发的消息 八、实现输入框随文字的伸缩 九、实现图片的发送级语音发送的原理
#pragma mark 发送图片
-(void)sendImage:(UIImage *)image{
XMPPMessage *msg = [XMPPMessage messageWithType:@"chat" to:self.friendJid];
NSData *data = UIImagePNGRepresentation(image);
[msg addBody:@"image"];
XMPPElement *attachment = [XMPPElement elementWithName:@"attachment" stringValue:[data base64EncodedStringWithOptions:]];
[msg addChild:attachment]; [[WXXMPPTools sharedWXXMPPTools].xmppStream sendElement:msg];
} #parm mark cell显示
XMPPMessage *xmppMsg = msg.message;
chatCell.imageView.image = nil;
if ([msg.body isEqual:@"image"]) {
NSArray *child = xmppMsg.children;
for (XMPPElement *node in child) {
if([[node name] isEqualToString:@"attachment"]){
NSString *base64 = [node stringValue];
NSData *imageData = [[NSData alloc] initWithBase64EncodedString:base64 options:];
chatCell.imageView.image = [UIImage imageWithData:imageData];
} } } 第二种
[message addAttributeWithName:@"bodyType" stringValue:@"image"];
[xmppMsg attributeStringValueForName:@"bodyType"] 邮箱解析
NSArray *emailEles = [self elementsForName:@"EMAIL"];
if (emailEles.count != ) {
NSXMLElement *email = emailEles[];
NSXMLElement *userID = [email elementForName:@"USERID"];
return @[[userID stringValue]];
} NSArray *emailEles = [self elementsForName:@"EMAIL"];
if (emailEles.count != && emails.count!=) {
NSXMLElement *email = emailEles[];
NSXMLElement *userID = [NSXMLElement elementWithName:@"USERID" stringValue:emails[] ];
[email removeElementForName:@"USERID"];
[email addChild:userID];
}

IOS XMPP总结的更多相关文章

  1. iOS XMPP 通信协议实现 图形化直观感受

    第一次随笔,实在不知写点什么有用的东西,那就分享一下本人最近的研究所得吧! 是关于iOS-XMPP-通信协议的实现,具体代码比较复杂,三言两句也实在难表达清楚,网上已有很多关于iOS XMPP协议的讲 ...

  2. ios xmpp开发应用后台模式接收聊天信息处理方案

    ios xmpp开发应用后台模式接收聊天信息 最近在使用xmppframwork来实现一个聊天应用,碰到了一个问题,应用进入后台以后,就接收不到消息了: 怎么样才能使应用被切到后台时,应用中的网络连接 ...

  3. iOS xmpp协议实现聊天之openfire的服务端配置(一)

    今天弄这个openfire服务端的配置直接苦了一逼,只是好在最后最终配置好了.首先感谢@月光的尽头的博客给了我莫大的帮助. 切入正题,首先说一下iOS xmpp协议实现聊天openfireserver ...

  4. ios xmpp 发送语音图片解决方案

    ios xmpp 发送语音,图片解决方案,有需要的朋友可以参考下. 目前做IM多是用的xmpp. 因为项目需求需要实现语音和图片的发送. 发送语音图片有三种方法. 1,xmpp smack.文件传输方 ...

  5. iOS XMPP Framework 中文概述

    本篇文章翻译XMPP Framework中的Overview of the XMPP Framework部分 介绍 The framework is divided into 2 parts: 1. ...

  6. iOS - XMPP 的使用

    1.XMPP XMPP 是一个基于 Socket 通信的即时通讯的协议,它规范了即时通信在网络上数据的传输格式,比如登录,获取好友列表等等的格式.XMPP 在网络传输的数据是 XML 格式. 开发架构 ...

  7. iOS - XMPP Openfire 服务器的搭建

    前言 提前下载好相关软件,且安装目录最好安装在全英文路径下.如果路径有中文名,那么可能会出现一些莫名其妙的问题. 提前准备好的软件: jdk-8u91-macosx-x64.dmg mysql-5.7 ...

  8. 【iOS XMPP】使用XMPPFramewok(五):好友列表

    转自:http://www.cnblogs.com/dyingbleed/archive/2013/05/17/3082226.html 好友列表 好友列表,在 XMPP 中被称为 roster,花名 ...

  9. 【iOS XMPP】使用XMPPFramewok(四):收发消息

    转自:http://www.cnblogs.com/dyingbleed/archive/2013/05/16/3075105.html 收发消息 接收消息 通过实现 - (void)xmppStre ...

  10. 【iOS XMPP】使用XMPPFramewok(二):用户登录

    转自:http://www.cnblogs.com/dyingbleed/archive/2013/05/10/3069397.html 用户登录 准备工作 比较知名的开源XMPP服务器:一个是Ope ...

随机推荐

  1. Scrum 冲刺博客第四篇

    一.当天站立式会议照片一张 二.每个人的工作 (有work item 的ID),并将其记录在码云项目管理中 昨天已完成的工作 新建立了一个list页面用来显示题目,并且创建了列表用来进行题目的存放,将 ...

  2. zabbix自动发现与自动注册及SNMP监控

    自动发现与自动注册 自动发现:zabbix Server主动发现所有客户端,然后将客户端登记自己的小本本上,缺点zabbix server压力山大(网段大,客户端多),时间消耗多. 自动注册:zabb ...

  3. 从CentOS官网下载系统镜像详细教程

      很多新手小白鼠想学习CentOS系统,但是不知道镜像去哪里搞,随便去个第三方发现要么要注册,要么各种广告病毒,或者好不容易找到官网,点进去一看却一脸懵逼,不仅全英文,有些专业术语也不懂啊,不要担心 ...

  4. [转] .NET中六个重要的概念:栈、堆、值类型、引用类型、装箱和拆箱

    为何要转载 一来是最近面试了几家公司,发现问的还都是这些的基础知识,二来是为了复习对.NET技术的基础拾遗达到温故知新的效果. 为什么有人说,不动笔不读书.我现在也是深有体会了,看过的东西不一定会记得 ...

  5. [转] SQL函数说明大全

    from http://www.cnblogs.com/moss_tan_jun/archive/2010/08/23/1806861.html 一旦成功地从表中检索出数据,就需要进一步操纵这些数据, ...

  6. c# 根据父节点id,找到所有的子节点数据

    转自:https://blog.csdn.net/q107770540/article/details/7708418 查的是表 Model_info中父节点为p_id时找到所有的子节点的集合 //通 ...

  7. 四、闭锁之CountDownLatch

    一.简介 闭锁是Java的一种同步工具类.我们在程序运行过程中,某个任务需要等待其它一个到多个的任务全部完成才会执行,这个等待的期间就叫做闭锁. CountDownLatch是闭锁的一种实现,它支持一 ...

  8. java核心技术-IO

    一 .IO 1.1 流的简单介绍和分类 Java流操作的相关的类和接口: Java流类图结构: 四个抽象基类分别为:InputStream .OutputStream .Reader .Writer: ...

  9. 关于react-router-dom的一些记录

    最近在做的新项目使用的技术栈是 React+AntDesign,本篇主要记录在实践过程中使用react-router-dom时遇到的一些方法的总结. 1.HashRouter和BrowserRoute ...

  10. Date()函数的用法