用 JSQMessagesViewController 创建一个 iOS 聊天 App

在本教程中,我将介绍怎样创建一个简单的 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

原文地址:https://www.cnblogs.com/jzssuanfa/p/7157053.html