今天带来的是智能聊天机器人实现(源码+解析), 和上一篇教程一样, 当你没有女朋友的时候, 可以用它来打发时间。这里的API是图灵机器人提供的, 实现一个十分强大的机器人。
具体功能包括:
• 支持聊天对话、智能问答
• 拥有笑话、天气、公交等丰富功能
• 支持自然语言处理及语义理解
• 数十亿知识库数据,应有尽有
源码已经传到git上了, 欢迎下载学习。
下载链接: https://github.com/colin1994/tulingIOS
如果你觉得这篇文章看起来稍微还有些吃力,或者想要系统地学习人工智能,那么推荐你去看床长人工智能教程。非常棒的大神之作,教程不仅通俗易懂,而且很风趣幽默。点击这里可以查看教程。
这个小demo的界面是仿微信的。只不过是简化版的, 包括表情, 语音什么的, 都省略了。
对于界面这一块, 我这里不多做介绍, 因为这并不是本教程主要内容。毕竟, 这个界面到自己实际项目中的时候, 肯定是需要自定义的。
这里简要介绍一下。
该界面分成两部分:
1. UITableView: 显示聊天列表, 其中, 左边的是机器人回答, 右边是自己的提问。
另外, 列表的每个cell, 由头像和文字组成。 这个cell是自定义的, 详细可以自己查看源码。
列表添加:
-
//add UItableView
-
self.tableView=[[
UITableView alloc]initWithFrame:
CGRectMake(
0,
44,
self.view.frame.size.width,
self.view.frame.size.height
-88) style:
UITableViewStylePlain];
-
[
self.tableView registerClass:[ChartCell
class] forCellReuseIdentifier:cellIdentifier];
-
self.tableView.separatorStyle=
UITableViewCellSeparatorStyleNone;
-
self.tableView.allowsSelection =
NO;
-
self.tableView.backgroundView = [[
UIImageView alloc] initWithImage:[
UIImage imageNamed:
@"chat_bg_default.jpg"]];
-
self.tableView.dataSource=
self;
-
self.tableView.delegate=
self;
-
[
self.view addSubview:
self.tableView];
键盘添加:
-
//add keyBorad
-
self.keyBordView=[[KeyBordVIew alloc]initWithFrame:
CGRectMake(
0,
self.view.frame.size.height
-44,
self.view.frame.size.width,
44)];
-
self.keyBordView.delegate=
self;
-
[
self.view addSubview:
self.keyBordView];
另外, 键盘涉及弹出和收起操作操作, 这个需要在视图载入之前, 注册通知, 响应相关操作。
1.注册通知
-
//注册通知, 键盘收起, 弹出
-
[[
NSNotificationCenter defaultCenter] addObserver:
self selector:
@selector(keyboardShow:) name:
UIKeyboardWillShowNotification object:
nil];
-
[[
NSNotificationCenter defaultCenter] addObserver:
self selector:
@selector(keyboardHide:) name:
UIKeyboardWillHideNotification object:
nil];
-
//键盘弹出响应
-
-(
void)keyboardShow:(
NSNotification *)note
-
{
-
CGRect keyBoardRect=[note.userInfo[
UIKeyboardFrameEndUserInfoKey]
CGRectValue];
-
CGFloat deltaY=keyBoardRect.size.height;
-
-
[
UIView animateWithDuration:[note.userInfo[
UIKeyboardAnimationDurationUserInfoKey] floatValue] animations:^{
-
-
self.view.transform=
CGAffineTransformMakeTranslation(
0, -deltaY);
-
}];
-
}
-
-
//键盘收起响应
-
-(
void)keyboardHide:(
NSNotification *)note
-
{
-
[
UIView animateWithDuration:[note.userInfo[
UIKeyboardAnimationDurationUserInfoKey] floatValue] animations:^{
-
self.view.transform =
CGAffineTransformIdentity;
-
}];
-
}
用过一些第三方API的都知道, 通常我需要先注册成为它的用户, 才能获取对应的key, 以便调用API。
图灵也不例外, 你需要先注册成为图灵用户, 然后有相关教程, 教你如何获取自己的key, 以及正确的URL。这里就不重复了。图灵机器人官网链接
例如, 我这个demo里面的key是:6c2cfaf7a7f088e843b550b0c5b89c26
对应的API是:http://www.tuling123.com/openapi/api?key=6c2cfaf7a7f088e843b550b0c5b89c26&&info=%@
所以, 你只要把这里的key替换成你自己的就可以了。
这里使用了第三方网络请求库ASI 和 json格式数据解析库 JsonKit。
在导入ASI的时候, 如果你的项目是ARC, 那么, 请将对应的文件设置成支持ARC即可。 (-fno-objc-arc)
另外, 要导入一些框架
SystemConfiguration.framework
MobileCoreServices.framework
CFNetwork.framework
libz.dylib
接着就能利用ASI调用图灵API,再利用jsonkit解析返回的数据了。
具体实现如下:
-
//每当编辑完问题后
-
//1. 显示自己的问题 messageType=1
-
//2. 调用API,返回结果
-
-(
void)KeyBordView:(KeyBordVIew *)keyBoardView textFiledReturn:(
UITextField *)textFiled
-
{
-
-
//显示自己的问题
-
ChartCellFrame *cellFrame=[[ChartCellFrame alloc]init];
-
ChartMessage *chartMessage=[[ChartMessage alloc]init];
-
-
chartMessage.icon=
@"icon01.png";
-
chartMessage.messageType=
1;
-
chartMessage.content=textFiled.text;
-
cellFrame.chartMessage=chartMessage;
-
-
[
self.cellFrames addObject:cellFrame];
-
[
self.tableView reloadData];
-
-
//滚动到当前行
-
[
self tableViewScrollCurrentIndexPath];
-
-
//利用用户问题, 查询结果
-
-
//API请求格式。 具体格式见图灵官网
-
//6c2cfaf7a7f088e843b550b0c5b89c26 替换成你申请的key即可
-
NSString* urlString = [
NSString stringWithFormat:
@"http://www.tuling123.com/openapi/api?key=6c2cfaf7a7f088e843b550b0c5b89c26&&info=%@", textFiled.text];
-
-
//NSUTF8StringEncoding编码。 避免中文错误
-
urlString = [urlString stringByAddingPercentEscapesUsingEncoding:
NSUTF8StringEncoding];
-
//调用API
-
NSURL *url = [
NSURL URLWithString:urlString];
-
testRequest = [ASIHTTPRequest requestWithURL:url];
-
[testRequest setDelegate:
self];
-
[testRequest startAsynchronous];
-
-
textFiled.text=
@"";
-
myTextField = textFiled;
-
}
-
-
#pragma mark - 返回机器人回答
-
//调用API完毕, 返回图灵回答结果
-
//1. 收起键盘
-
//2. 显示回答内容
-
- (
void)requestFinished:(ASIHTTPRequest *)request
-
{
-
-
//收起键盘
-
[myTextField resignFirstResponder];
-
-
// 当以文本形式读取返回内容时用这个方法
-
// 解析返回的json数据
-
NSString *responseString = [request responseString];
-
self.testDic = [responseString objectFromJSONString];
-
self.testArr = [testDic objectForKey:
@"text"];
-
-
-
//显示回答内容
-
ChartCellFrame *cellFrame=[[ChartCellFrame alloc]init];
-
ChartMessage *chartMessage=[[ChartMessage alloc]init];
-
-
chartMessage.icon=
@"icon02.png";
-
chartMessage.messageType=
0;
-
chartMessage.content=[
NSString stringWithFormat:
@"%@",
self.testArr];
-
cellFrame.chartMessage=chartMessage;
-
-
[
self.cellFrames addObject:cellFrame];
-
[
self.tableView reloadData];
-
-
//滚动到当前行
-
[
self tableViewScrollCurrentIndexPath];
-
-
}
-
-
// API请求失败
-
- (
void)requestFailed:(ASIHTTPRequest *)request
-
{
-
NSError *error = [request error];
-
NSLog(
@"error --- %@",error);
-
-
UIAlertView *alert_ = [[
UIAlertView alloc]initWithTitle:
@"提示" message:
@"无网络可用,请检查网络状态" delegate:
self cancelButtonTitle:
@"知道了" otherButtonTitles:
nil];
-
[alert_ show];
-
}