用 JSQMessagesViewController 创建一个 iOS 聊天 App - 第 2 部分
在本教程中,我将介绍怎样创建一个简单的 iOS 聊天 App(用 swift 和 Syncano)。
在第一部分,我们创建了新的项目,并加入了一个 JSQMessagesViewController(然后在上面显示一些測试消息)。
在第二部分,我们将数据存到server并实时同步(当新消息一存到数据库就马上显示,不须要不论什么刷新操作)。
假设你错过了第一部分,你能够去这里阅读。
你能够从第一部分開始,也能够从这里下载第一部分的代码然后開始。
注意,这个项目使用了 CocoaPods,假设你没实用过它。不知道怎样安装它——请參考第一部分。
加入 Syncano
接下来是让人兴奋的环节了——真正将消息发送到后台并接受其它人发送的消息。
注冊 Syncano
假设你还没有账号,请到这里注冊——它仅仅须要花费你 10 秒钟的时间。仅仅须要你提供一个邮箱地址和password。
配置 Syncano
到这里登录你的 Syncano 账号。
假设你还没有一个 Syncano 实例(一个实例就是一个项目) 。或者你准备用一个空实例,你能够创建一个新实例:

记住你的实例名称,然后选择它。
然后新建一个类。用这个类保存全部消息:

类名输入 Message,并设置下面字段为:
- text : String
- senderid : String
- attachment : File

我们还须要加入一个频道(Chanel),频道是用来对数据进行实时同步的。
进入 Channels 页面,加入一个频道。频道名字命名为 Messages。other permissions 设置为 publish。

最后,创建一个 API key,API key 用于连接数据库。描写叙述字段随便填写,但 Ignore ACL 必须设置为 True(将右边的开关拉到 ON 位置)。

key 设置完后,记下 key——我们会在后面用到它。
在项目中加入 Syncano
首先。我们须要一个 Syncano 对象,指定连接中要使用的实例名和 API key。这个对象是全部连接共享的。此外还须要一个 Channel 对象用于数据同步。在 ViewController 中加入它们:
let syncanoChannelName = "messages"
class ViewController: JSQMessagesViewController {
let syncano = Syncano.sharedInstanceWithApiKey(YOUR_API_KEY, instanceName: YOUR_INSTANCE_NAME)
let channel = SCChannel(name: syncanoChannelName)
//...
}
将 YOUR_API_KEY 和 YOUR_INSTANCE_NAME 替换成你先前记下的值。
假设你的频道名称和我的不同,也要替换它。
下载和发送消息
在開始和 Syncano 交互之前。我们还须要定义一个类,用于映射我们在 Dashboard 中创建的类。
在 Xcode 中新建一个 Cocoa 类,类名为 Message,继承 SCDataObject。语言为 Swift:

编辑 Message.swift 为:
import UIKit
import syncano_ios
class Message: SCDataObject {
var text = ""
var senderId = ""
var attachment : SCFile?
override class func extendedPropertiesMapping() -> [NSObject: AnyObject] {
return [
"senderId":"senderid"
]
}
}
我们将类定义成和 Dashboard 中定义的类一样。唯一不同的是。senderId 使用了驼峰命名法。而在 Syncano 上全部的名字都是小写字母的。因此我们告诉 Syncano 这个属性的名字略微有点不同(通过这样的方式,我们的属性名能够保持 iOS 的命名规范)。
在 ViewController.swift 中加入一个扩展:
//MARK - Syncano
extension ViewController {
func sendMessageToSyncano(message: JSQMessage) {
let messageToSend = Message()
messageToSend.text = message.text
messageToSend.senderId = self.senderId
messageToSend.channel = syncanoChannelName
messageToSend.other_permissions = .Full
messageToSend.saveWithCompletionBlock { error in
if (error != nil) {
//Super cool error handling
}
}
}
func downloadNewestMessagesFromSyncano() {
Message.please().giveMeDataObjectsWithCompletion { objects, error in
if let messages = objects as?
[Message]! {
self.messages = self.jsqMessagesFromSyncanoMessages(messages)
self.finishReceivingMessage()
}
}
}
func jsqMessageFromSyncanoMessage(message: Message) -> JSQMessage {
let jsqMessage = JSQMessage(senderId: message.senderId, senderDisplayName: message.senderId, date: message.created_at, text: message.text)
return jsqMessage
}
func jsqMessagesFromSyncanoMessages(messages: [Message]) -> [JSQMessage] {
var jsqMessages : [JSQMessage] = []
for message in messages {
jsqMessages.append(self.jsqMessageFromSyncanoMessage(message))
}
return jsqMessages
}
}
这些方法用于和 Syncano 进行通讯。
- sendMessageToSyncano(message: JSQMessage) 将一个 JSQMessage 对象转换成 Syncano 对象然后提交给 Syncano。注意,在设置 senderId 和 text 字段之后还要设置 chanel 字段——channel 用于实时同步。以及 other_permissions 字段——用于指定谁有权訪问这个对象——这里设为 Full,表示全部人。
- downloadNewestMessagesFromSyncano() 用于下载最新的消息,用server的消息替换掉原来的 messages 数组。
- jsqMessageFromSyncanoMessage(message: Message) 和 jsqMessagesFromSyncanoMessages(messages: [Message]) 方法用于在 Message 类和 JSQMessage 类之间进行转换。
接下来我们改动代码,让用户输入的消息能够发送到 Syncano。在 didPressSendButton 方法中调用 sendMessageToSyncano 方法:
override func didPressSendButton(button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: NSDate!) {
let message = JSQMessage(senderId: senderId, senderDisplayName: senderDisplayName, date: date, text: text)
self.messages += [message]
self.sendMessageToSyncano(message)
self.finishSendingMessage()
}
然后,将測试消息替换成真正的 Syncano 消息。
在 viewDidLoad 方法中我们会下载最新的消息。注意,我们已经删除了之前加入的測试消息:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.setup()
self.downloadNewestMessagesFromSyncano()
}
执行程序,你会看到一个空白的窗体。那是由于在server上还没有不论什么聊天消息。发送几条消息然后重新启动 App ——你将看到消息已经存进了server。你能够登入你的 Syncano Dashboard 查看这些消息是否都保存到了 Message 类中。
实时!
这个 App 另一个实时功能没有实现,即每当server收到一条消息,client就能马上收到。
我们能够在后台每隔几秒就刷新一下消息列表。但更好的办法是使用 Syncano 频道。
在 setup() 方法中从频道中获取聊天消息:
func setup() {
self.senderId = UIDevice.currentDevice().identifierForVendor?
.UUIDString
self.senderDisplayName = UIDevice.currentDevice().identifierForVendor?.UUIDString
self.channel.delegate = self
self.channel.subscribeToChannel()
}
我们将频道的托付设置为 self,因此须要让 self 实现 SCChannelDelegate 协议。
在ViewController.swift 中新增一个扩展:
//MARK - Channels
extension ViewController : SCChannelDelegate {
func addMessageFromNotification(notification: SCChannelNotificationMessage) {
let message = Message(fromDictionary: notification.payload)
if message.senderId == self.senderId {
//we don't need to add messages from ourselves
return
}
self.messages.append(self.jsqMessageFromSyncanoMessage(message))
self.finishReceivingMessage()
}
func updateMessageFromNotification(notification: SCChannelNotificationMessage) {
}
func deleteMessageFromNotification(notification: SCChannelNotificationMessage) {
}
func chanellDidReceivedNotificationMessage(notificationMessage: SCChannelNotificationMessage!) {
switch(notificationMessage.action) {
case .Create:
self.addMessageFromNotification(notificationMessage)
case .Delete:
self.deleteMessageFromNotification(notificationMessage)
case .Update:
self.updateMessageFromNotification(notificationMessage)
default:
break
}
}
}
总结
这部分的内容就到此为止了,我们的 App 还是一个半成品。如今,你能够和朋友分享它,也能够继续第三部分。
这部分的代码在这里下载。
在第三部分。我们将学习怎样让用户注冊和通过验证,以及 UI 的改动,怎样将不同用户发送的消息有差别地显示。
敬请关注!
假设你有不论什么问题。请 tweet 我。
用 JSQMessagesViewController 创建一个 iOS 聊天 App - 第 2 部分的更多相关文章
- 如何用 React Native 创建一个iOS APP?(三)
前两部分,<如何用 React Native 创建一个iOS APP?>,<如何用 React Native 创建一个iOS APP (二)?>中,我们分别讲了用 React ...
- 如何用 React Native 创建一个iOS APP?(二)
我们书接上文<如何用 React Native 创建一个iOS APP?>,继续来讲如何用 React Native 创建一个iOS APP.接下来,我们会涉及到很多控件. 1 AppRe ...
- 如何用 React Native 创建一个iOS APP?
诚然,React Native 结合了 Web 应用和 Native 应用的优势,可以使用 JavaScript 来开发 iOS 和 Android 原生应用.在 JavaScript 中用 Reac ...
- 一个先进的App框架:使用Ionic创建一个简单的APP
原文 http://www.w3cplus.com/mobile/building-simple-app-using-ionic-advanced-html5-mobile-app-framewor ...
- 搭建QQ聊天通信的程序:(1)基于 networkcomms.net 创建一个WPF聊天客户端服务器应用程序 (1)
搭建QQ聊天通信的程序:(1)基于 networkcomms.net 创建一个WPF聊天客户端服务器应用程序 原文地址(英文):http://www.networkcomms.net/creating ...
- 教你动手做一个 iOS 越狱 app
前言 俗话说得好, 万事开头难. 仅仅是上图一个如此简单地不能再简单的小app, 其实都不算是app, 只是注入了一段代码进系统中, 等到特定的函数方法调用的时候就会被我们hook掉, 执行我们写的代 ...
- 使用ionic framework创建一个简单的APP
ionic是一个以cordova为基础的html5前端框架,功能强大,能够快速做出与原生开发相似的应用. 一,安装和配置 1,安装(前提:cordova环境配置完成) npm install -g i ...
- Cordova 系列之创建一个iOS项目
1.打开终端 2.输入命令 $ cd Desktop (PS:Desktop表示放在桌面,你可以选择放任意位置) 3.$ cordova create HelloWorld com.example. ...
- 两行代码快速创建一个iOS主流UI框架
本框架适用于 使用 NavigationController+UITabBarController 的APP 框架QLSNavTab , GitHub地址:https://github.com/qia ...
随机推荐
- HTML 表单 存为EXCEL文件时 中文显示乱码
在做宣传品发放系统时,需求要把数据库查询的记录生成表单并转存excel文件. 在转存的EXCEL文件中文显示乱码,表格和其他字符正常,检查后发现是创建EXCEL文件打开模式不对 之前: myfile ...
- Python--10、线程
线程 每个进程里都有一个控制线程,进程不是一个执行单位,线程是执行单位,进程是资源单位(资源隔离).进程下可以开多个线程,多线程共享进程内的资源.创建线程的速度比创建进程的速度快,因为创建线程不需要再 ...
- 这辈子写过的比较有意思的几个sql
递归 with myRecursion as( select * from recursion where id=1 union all select r.* from myRecursion m,r ...
- UI开发模式对比:JSP、Android、Flex
前一篇文章分析了Java平台下不同类型WEB框架对开发模式的影响,多数Java领域的WEB框架都是聚焦于服务端MVC的实现,这些框架对View的支持,通常是基于标准的JSP或类似JSP的模板技术如Fr ...
- 深入浅出的 SQL Server 查询优化
目前网络数据库的应用已经成为最为广泛的应用之一了,并且关于数据库的安全性,性能都是企业最为关心的事情.数据库渐渐成为企业的命脉,优化查询就解决了每个关于数据库应用的性能问题,在这里microsoft ...
- Resetting the SMC & PRAM
Resetting the SMC & PRAM on portables with a battery you should not remove on your own 1. Shut d ...
- 使用ScriptManager服务器控件前后台数据交互
前台页面信息: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebFor ...
- nginx配置https转发的一个例子
server { listen ; #https默认端口不是80,而是443 server_name www.test.com; ssl on; ssl_certificate cert/.pem; ...
- httpd-vhosts.conf
## VirtualHost example:# Almost any Apache directive may go into a VirtualHost container.# The first ...
- c/c++排坑(3) -- c/c++中的switch语句
switch语句的简单介绍 一个 switch 语句允许测试一个变量等于多个值时的情况.每个值称为一个 case,且被测试的变量会对每个 switch case 进行检查. switch(expres ...