445 lines
15 KiB
Mathematica
445 lines
15 KiB
Mathematica
|
// ----------------------------------------------------------------------
|
|||
|
// Copyright (C) 2021 即时通讯网(52im.net) & Jack Jiang.
|
|||
|
// The MobileIMSDK_TCP (MobileIMSDK v6.x TCP版) Project.
|
|||
|
// All rights reserved.
|
|||
|
//
|
|||
|
// > Github地址: https://github.com/JackJiang2011/MobileIMSDK
|
|||
|
// > 文档地址: http://www.52im.net/forum-89-1.html
|
|||
|
// > 技术社区: http://www.52im.net/
|
|||
|
// > 技术交流群: 215477170 (http://www.52im.net/topic-qqgroup.html)
|
|||
|
// > 作者公众号: “即时通讯技术圈】”,欢迎关注!
|
|||
|
// > 联系作者: http://www.52im.net/thread-2792-1-1.html
|
|||
|
//
|
|||
|
// "即时通讯网(52im.net) - 即时通讯开发者社区!" 推荐开源工程。
|
|||
|
// ----------------------------------------------------------------------
|
|||
|
|
|||
|
#import "MainViewController.h"
|
|||
|
#import "ConfigEntity.h"
|
|||
|
#import "ToolKits.h"
|
|||
|
#import "ClientCoreSDK.h"
|
|||
|
#import "LocalDataSender.h"
|
|||
|
#import "ErrorCode.h"
|
|||
|
#import "Protocal.h"
|
|||
|
#import "AutoReLoginDaemon.h"
|
|||
|
#import "KeepAliveDaemon.h"
|
|||
|
#import "QoS4ReciveDaemon.h"
|
|||
|
#import "QoS4SendDaemon.h"
|
|||
|
#import "ChatBaseEventImpl.h"
|
|||
|
#import "ChatInfoTableViewCellDTO.h"
|
|||
|
#import "ChatInfoTableViewCell.h"
|
|||
|
#import "UIViewController+Ext.h"
|
|||
|
#import "IMClientManager.h"
|
|||
|
#import "AppDelegate.h"
|
|||
|
#import "ProtocalType.h"
|
|||
|
|
|||
|
|
|||
|
////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
#pragma mark - 静态常量
|
|||
|
////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
|||
|
static const int TABLE_CELL_COLOR_BLACK = 0;
|
|||
|
static const int TABLE_CELL_COLOR_BLUE = 1;
|
|||
|
static const int TABLE_CELL_COLOR_BRIGHT_RED = 2;
|
|||
|
static const int TABLE_CELL_COLOR_RED = 3;
|
|||
|
static const int TABLE_CELL_COLOR_GREEN = 4;
|
|||
|
|
|||
|
|
|||
|
////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
#pragma mark - 私有API
|
|||
|
////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
|||
|
@interface MainViewController ()
|
|||
|
{
|
|||
|
// cht info time
|
|||
|
NSDateFormatter *hhmmssFormat;
|
|||
|
}
|
|||
|
|
|||
|
// 用于主界面表格的数据显示
|
|||
|
@property (nonatomic, retain) NSMutableArray* chatInfoList;
|
|||
|
|
|||
|
@end
|
|||
|
|
|||
|
|
|||
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
#pragma mark - 本类的代码实现
|
|||
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
|||
|
@implementation MainViewController
|
|||
|
|
|||
|
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
|
|||
|
{
|
|||
|
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]))
|
|||
|
{
|
|||
|
//
|
|||
|
}
|
|||
|
return self;
|
|||
|
}
|
|||
|
|
|||
|
- (void)viewDidLoad
|
|||
|
{
|
|||
|
[super viewDidLoad];
|
|||
|
|
|||
|
// 设置顶部导航标题栏为不透明,否则在ios7以上系统会挡住下方的页面内容
|
|||
|
self.navigationController.navigationBar.translucent = NO;
|
|||
|
self.title = @"MobileIMSDK_TCP Demo";
|
|||
|
|
|||
|
// chat info time
|
|||
|
hhmmssFormat = [[NSDateFormatter alloc] init];
|
|||
|
[hhmmssFormat setDateFormat:@"HH:mm:ss"];
|
|||
|
|
|||
|
// 表格基本设置
|
|||
|
self.chatInfoList = [[NSMutableArray alloc] init];
|
|||
|
self.tableView.delegate = self;
|
|||
|
self.tableView.dataSource = self;
|
|||
|
|
|||
|
// just for debug START
|
|||
|
[self initObserversForDEBUG];
|
|||
|
// just for debug END
|
|||
|
}
|
|||
|
|
|||
|
- (void)viewDidUnload
|
|||
|
{
|
|||
|
[super viewDidUnload];
|
|||
|
}
|
|||
|
|
|||
|
-(void)viewWillAppear:(BOOL)animated
|
|||
|
{
|
|||
|
[super viewWillAppear:animated];
|
|||
|
|
|||
|
// Refresh MobileIMSDK userId to show
|
|||
|
[self refreshConnecteStatus];
|
|||
|
|
|||
|
// just for debug START
|
|||
|
// Refresh MobileIMSDK background status to show
|
|||
|
[self refreshMobileIKSDKThreadStatusForDEBUG];
|
|||
|
// just for debug END
|
|||
|
|
|||
|
// 将当前账号显示出来
|
|||
|
self.myUserId.text = [ClientCoreSDK sharedInstance].currentLoginUserId;
|
|||
|
}
|
|||
|
|
|||
|
- (IBAction)signOut:(id)sender
|
|||
|
{
|
|||
|
// 退出登陆
|
|||
|
[self doLogout];
|
|||
|
// 退出程序
|
|||
|
[self doExit];
|
|||
|
}
|
|||
|
|
|||
|
- (IBAction)send:(id)sender
|
|||
|
{
|
|||
|
[self doSendMessage];
|
|||
|
}
|
|||
|
|
|||
|
- (void) refreshConnecteStatus
|
|||
|
{
|
|||
|
BOOL connectedToServer = [ClientCoreSDK sharedInstance].connectedToServer;
|
|||
|
if(connectedToServer) {
|
|||
|
self.connectStatus.text = @"通信正常";
|
|||
|
self.connectStatus.textColor = [UIColor colorWithRed:91/255.0f green:198/255.0f blue:72/255.0f alpha:1];
|
|||
|
[self.connectStatusIcon setImage:[UIImage imageNamed:@"green"]];
|
|||
|
}
|
|||
|
else{
|
|||
|
self.connectStatus.text = @"连接断开";
|
|||
|
self.connectStatus.textColor = [UIColor colorWithRed:255/255.0f green:0/255.0f blue:255/255.0f alpha:1];
|
|||
|
[self.connectStatusIcon setImage:[UIImage imageNamed:@"red"]];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
- (void)doSendMessage
|
|||
|
{
|
|||
|
NSString *dicStr = self.messageField.text;
|
|||
|
if ([dicStr length] == 0)
|
|||
|
{
|
|||
|
[self E_showToastInfo:@"提示" withContent:@"请输入消息内容!" onParent:self.view];
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
NSString *friendIdStr = self.friendId.text;
|
|||
|
if ([friendIdStr length] == 0)
|
|||
|
{
|
|||
|
[self E_showToastInfo:@"提示" withContent:@"请输入对方id!" onParent:self.view];
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
[self showIMInfo_black:[NSString stringWithFormat:@"我对%@说:%@", friendIdStr, dicStr]];
|
|||
|
|
|||
|
// 发送消息
|
|||
|
int code = [[LocalDataSender sharedInstance] sendCommonDataWithStr:dicStr toUserId:friendIdStr qos:YES fp:nil withTypeu:-1];
|
|||
|
if(code == COMMON_CODE_OK)
|
|||
|
{
|
|||
|
// [self showToastInfo:@"提示" withContent:@"您的消息已成功发出。。。"];
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
NSString *msg = [NSString stringWithFormat:@"您的消息发送失败,错误码:%d", code];
|
|||
|
[self E_showToastInfo:@"错误" withContent:msg onParent:self.view];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
- (void)doLogout
|
|||
|
{
|
|||
|
// 发出退出登陆请求包
|
|||
|
int code = [[LocalDataSender sharedInstance] sendLoginout];
|
|||
|
if(code == COMMON_CODE_OK)
|
|||
|
{
|
|||
|
[self E_showToastInfo:@"提示" withContent:@"注销登陆请求已完成。。。" onParent:self.view];
|
|||
|
[self refreshConnecteStatus];
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
NSString *msg = [NSString stringWithFormat:@"注销登陆请求发送失败,错误码:%d", code];
|
|||
|
[self E_showToastInfo:@"错误" withContent:msg onParent:self.view];
|
|||
|
}
|
|||
|
|
|||
|
//## BUG FIX: 20170713 START by JackJiang
|
|||
|
// 退出登陆时记得一定要调用此行,不然不退出APP的情况下再登陆时会报 code=203错误哦!
|
|||
|
[[IMClientManager sharedInstance] resetInitFlag];
|
|||
|
//## BUG FIX: 20170713 END by JackJiang
|
|||
|
}
|
|||
|
|
|||
|
- (void)doExit
|
|||
|
{
|
|||
|
UIWindow *window = CurAppDelegate.window;
|
|||
|
[UIView animateWithDuration:1.0f animations:^{
|
|||
|
window.alpha = 0;
|
|||
|
window.frame = CGRectMake(0, window.bounds.size.width, 0, 0);
|
|||
|
} completion:^(BOOL finished) {
|
|||
|
exit(0);
|
|||
|
}];
|
|||
|
//exit(0);
|
|||
|
}
|
|||
|
|
|||
|
//=============================================================================== just for 信息显示 START
|
|||
|
#pragma mark - 以下代码用于在Demo下方的信息内容表格里显示即时通讯相关信息
|
|||
|
|
|||
|
- (void) showIMInfo_black:(NSString*)txt
|
|||
|
{
|
|||
|
[self showIMInfo:txt withColorType:TABLE_CELL_COLOR_BLACK];
|
|||
|
}
|
|||
|
|
|||
|
- (void) showIMInfo_blue:(NSString*)txt
|
|||
|
{
|
|||
|
[self showIMInfo:txt withColorType:TABLE_CELL_COLOR_BLUE];
|
|||
|
}
|
|||
|
|
|||
|
- (void) showIMInfo_brightred:(NSString*)txt
|
|||
|
{
|
|||
|
[self showIMInfo:txt withColorType:TABLE_CELL_COLOR_BRIGHT_RED];
|
|||
|
}
|
|||
|
|
|||
|
- (void) showIMInfo_red:(NSString*)txt
|
|||
|
{
|
|||
|
[self showIMInfo:txt withColorType:TABLE_CELL_COLOR_RED];
|
|||
|
}
|
|||
|
|
|||
|
- (void) showIMInfo_green:(NSString*)txt
|
|||
|
{
|
|||
|
[self showIMInfo:txt withColorType:TABLE_CELL_COLOR_GREEN];
|
|||
|
}
|
|||
|
|
|||
|
- (void) showIMInfo:(NSString*)txt withColorType:(int)colorType
|
|||
|
{
|
|||
|
ChatInfoTableViewCellDTO *dto = [[ChatInfoTableViewCellDTO alloc] init];
|
|||
|
dto.colorType = colorType;
|
|||
|
dto.content = [NSString stringWithFormat:@"[%@] %@", [hhmmssFormat stringFromDate:[[NSDate alloc] init]], txt];
|
|||
|
[self.chatInfoList addObject:dto];
|
|||
|
[self.tableView reloadData];
|
|||
|
|
|||
|
// 自动显示最后一行
|
|||
|
NSInteger s = [self.tableView numberOfSections];
|
|||
|
if (s<1) return;
|
|||
|
NSInteger r = [self.tableView numberOfRowsInSection:s-1];
|
|||
|
if (r<1) return;
|
|||
|
NSIndexPath *ip = [NSIndexPath indexPathForRow:r-1 inSection:s-1];
|
|||
|
[self.tableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionBottom animated:YES];
|
|||
|
}
|
|||
|
//=============================================================================== just for 信息显示 END
|
|||
|
|
|||
|
//=============================================================================== just for debug START
|
|||
|
#pragma mark - 以下代码用于DEBUG时显示各种状态
|
|||
|
|
|||
|
- (void) refreshMobileIKSDKThreadStatusForDEBUG
|
|||
|
{
|
|||
|
[self showDebugStatusImage:([[AutoReLoginDaemon sharedInstance] isAutoReLoginRunning]?1:0) forImageView:self.iviewAutoRelogin];
|
|||
|
[self showDebugStatusImage:([[KeepAliveDaemon sharedInstance] isKeepAliveRunning]?1:0) forImageView:self.iviewKeepAlive];
|
|||
|
[self showDebugStatusImage:([[QoS4SendDaemon sharedInstance] isRunning]?1:0) forImageView:self.iviewQoSSend];
|
|||
|
[self showDebugStatusImage:([[QoS4ReciveDaemon sharedInstance] isRunning]?1:0) forImageView:self.iviewQoSReceive];
|
|||
|
}
|
|||
|
|
|||
|
- (void) initObserversForDEBUG
|
|||
|
{
|
|||
|
[self setupAnimationForStatusImage:self.iviewAutoRelogin];
|
|||
|
[self setupAnimationForStatusImage:self.iviewKeepAlive];
|
|||
|
[self setupAnimationForStatusImage:self.iviewQoSSend];
|
|||
|
[self setupAnimationForStatusImage:self.iviewQoSReceive];
|
|||
|
|
|||
|
[[AutoReLoginDaemon sharedInstance] setDebugObserver:[self createObserverCompletionForDEBUG:self.iviewAutoRelogin]];
|
|||
|
[[KeepAliveDaemon sharedInstance] setDebugObserver:[self createObserverCompletionForDEBUG:self.iviewKeepAlive]];
|
|||
|
[[QoS4SendDaemon sharedInstance] setDebugObserver:[self createObserverCompletionForDEBUG:self.iviewQoSSend]];
|
|||
|
[[QoS4ReciveDaemon sharedInstance] setDebugObserver:[self createObserverCompletionForDEBUG:self.iviewQoSReceive]];
|
|||
|
}
|
|||
|
|
|||
|
- (void) setupAnimationForStatusImage:(UIImageView *)iv
|
|||
|
{
|
|||
|
iv.animationImages = [NSArray arrayWithObjects:
|
|||
|
[UIImage imageNamed:@"green_light.png"],
|
|||
|
[UIImage imageNamed:@"green.png"],
|
|||
|
nil];
|
|||
|
iv.animationDuration = 0.5;
|
|||
|
iv.animationRepeatCount = 1;
|
|||
|
}
|
|||
|
|
|||
|
- (ObserverCompletion) createObserverCompletionForDEBUG:(UIImageView *)iv
|
|||
|
{
|
|||
|
ObserverCompletion clp = ^(id observerble ,id data) {
|
|||
|
int status = [(NSNumber *)data intValue];
|
|||
|
[self showDebugStatusImage:status forImageView:iv];
|
|||
|
};
|
|||
|
|
|||
|
return clp;
|
|||
|
}
|
|||
|
|
|||
|
- (void) showDebugStatusImage:(int)status forImageView:(UIImageView *)iv
|
|||
|
{
|
|||
|
if(iv.hidden)
|
|||
|
iv.hidden = NO;
|
|||
|
if(status == 1)
|
|||
|
{
|
|||
|
// 确保先stop ,否则正在动画中时此时设置图片则只会停在动画的最后一帧
|
|||
|
if([iv isAnimating])
|
|||
|
[iv stopAnimating];
|
|||
|
[iv setImage:[UIImage imageNamed:@"green.png"]];
|
|||
|
}
|
|||
|
else if(status == 2)
|
|||
|
{
|
|||
|
[iv setImage:[UIImage imageNamed:@"green.png"]];
|
|||
|
if([iv isAnimating])
|
|||
|
[iv stopAnimating];
|
|||
|
[iv startAnimating];
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// 确保先stop ,否则正在动画中时此时设置图片则只会停在动画的最后一帧
|
|||
|
if([iv isAnimating])
|
|||
|
[iv stopAnimating];
|
|||
|
[iv setImage:[UIImage imageNamed:@"gray.png"]];
|
|||
|
}
|
|||
|
}
|
|||
|
//=============================================================================== just for debug END
|
|||
|
|
|||
|
//=============================================================================== 有关主界面表格的托管实现方法 START
|
|||
|
#pragma mark - Table view delegate
|
|||
|
|
|||
|
// 根据显示内容计算行高
|
|||
|
- (CGSize)_calculateCellSize:(NSIndexPath *)indexPath
|
|||
|
{
|
|||
|
// 列寬
|
|||
|
CGFloat contentWidth = self.tableView.frame.size.width;
|
|||
|
if(self.chatInfoList == nil)
|
|||
|
return CGSizeMake(contentWidth, 16);
|
|||
|
ChatInfoTableViewCellDTO * item = [self.chatInfoList objectAtIndex:indexPath.section];
|
|||
|
|
|||
|
// 用何種字體進行顯示
|
|||
|
//### Bug FIX: 此字号设为12时,在iPhone5C(iOS7.0(11A466))真机上会出现字体显示不全的bug(下偏),
|
|||
|
// 但其它真机包括模拟器上却不会,难道是iOS7.0的bug?-- By Jack Jiang 2015-09-16
|
|||
|
UIFont *font = [UIFont systemFontOfSize:14];
|
|||
|
// 該行要顯示的內容
|
|||
|
NSString *content = item.content;
|
|||
|
// 計算出顯示完內容需要的最小尺寸
|
|||
|
CGSize size = [content sizeWithFont:font constrainedToSize:CGSizeMake(contentWidth, 1000) lineBreakMode:NSLineBreakByCharWrapping];
|
|||
|
|
|||
|
// NSLog(@"-------计算出的高度=%f", size.height);
|
|||
|
|
|||
|
return size;
|
|||
|
}
|
|||
|
|
|||
|
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
|||
|
{
|
|||
|
return self.chatInfoList == nil?0:[self.chatInfoList count];
|
|||
|
}
|
|||
|
|
|||
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
|||
|
{
|
|||
|
return 1;
|
|||
|
}
|
|||
|
|
|||
|
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
|
|||
|
{
|
|||
|
return [self _calculateCellSize:indexPath].height;
|
|||
|
}
|
|||
|
|
|||
|
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
|||
|
{
|
|||
|
if(self.chatInfoList == nil)
|
|||
|
return nil;
|
|||
|
|
|||
|
ChatInfoTableViewCellDTO * item = [self.chatInfoList objectAtIndex:indexPath.section];
|
|||
|
|
|||
|
// 表格单元可重用ui
|
|||
|
static NSString *idenfity=@"Cell";
|
|||
|
ChatInfoTableViewCell * cell=[tableView dequeueReusableCellWithIdentifier:idenfity];
|
|||
|
if(cell==nil) {
|
|||
|
NSArray* arr = [[NSBundle mainBundle] loadNibNamed:@"ChatInfoTableViewCell" owner:self options:nil];
|
|||
|
for (id obj in arr) {
|
|||
|
if ([obj isKindOfClass:[ChatInfoTableViewCell class]]) {
|
|||
|
cell = (ChatInfoTableViewCell*)obj;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 利表格单元对应的数据对象对ui进行设置
|
|||
|
cell.lbContent.text = item.content;
|
|||
|
NSInteger colorType = item.colorType;
|
|||
|
UIColor *cellColor = nil;
|
|||
|
switch(colorType)
|
|||
|
{
|
|||
|
case TABLE_CELL_COLOR_BLUE:
|
|||
|
cellColor = [UIColor colorWithRed:0/255.0f green:0/255.0f blue:255/255.0f alpha:1];
|
|||
|
break;
|
|||
|
case TABLE_CELL_COLOR_BRIGHT_RED:
|
|||
|
cellColor = [UIColor colorWithRed:255/255.0f green:0/255.0f blue:255/255.0f alpha:1];
|
|||
|
break;
|
|||
|
case TABLE_CELL_COLOR_RED:
|
|||
|
cellColor = [UIColor colorWithRed:255/255.0f green:0/255.0f blue:0/255.0f alpha:1];
|
|||
|
break;
|
|||
|
case TABLE_CELL_COLOR_GREEN:
|
|||
|
cellColor = [UIColor colorWithRed:0/255.0f green:128/255.0f blue:0/255.0f alpha:1];
|
|||
|
break;
|
|||
|
case TABLE_CELL_COLOR_BLACK:
|
|||
|
default:
|
|||
|
cellColor = [UIColor colorWithRed:0/255.0f green:0/255.0f blue:0/255.0f alpha:1];
|
|||
|
break;
|
|||
|
}
|
|||
|
if(cellColor != nil)
|
|||
|
cell.lbContent.textColor = cellColor;
|
|||
|
|
|||
|
// ** 设置cell的lable高度
|
|||
|
CGRect rect = [cell.textLabel textRectForBounds:cell.textLabel.frame limitedToNumberOfLines:0];
|
|||
|
// 設置顯示榘形大小
|
|||
|
rect.size = [self _calculateCellSize:indexPath];
|
|||
|
// 重置列文本區域
|
|||
|
cell.lbContent.frame = rect;
|
|||
|
|
|||
|
return cell;
|
|||
|
}
|
|||
|
|
|||
|
// 点击表格行时要调用的方法
|
|||
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
|||
|
{
|
|||
|
// do nothing
|
|||
|
|
|||
|
// 自动取消选中状态,要不然看起来很丑
|
|||
|
[self performSelector:@selector(deselectTableViewCell) withObject:nil afterDelay:0.5f];
|
|||
|
}
|
|||
|
|
|||
|
- (void)deselectTableViewCell
|
|||
|
{
|
|||
|
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
|
|||
|
|
|||
|
}
|
|||
|
//=============================================================================== 有关主界面表格的托管实现方法 END
|
|||
|
|
|||
|
@end
|