在本教程中,我將介紹如何創建一個簡單的 iOS 聊天 App(用 swift 和 Syncano)。
在第一部分,我們創建了新的項目,並添加了一個 JSQMessagesViewController(然後在上面顯示一些測試消息)。
在第二部分,我們將數據存到服務器並實時同步(當新消息一存到數據庫就立即顯示,不需要任何刷新操作)。
如果你錯過了第一部分,你可以去這裡閱讀。你可以從第一部分開始,也可以從這裡下載第一部分的代碼然後開始。
注意,這個項目使用了 CocoaPods,如果你沒有用過它,不知道如何安裝它——請參考第一部分。
接下來是讓人興奮的環節了——真正將消息發送到後台並接受其他人發送的消息。
如果你還沒有賬號,請到這裡注冊——它只需要花費你 10 秒鐘的時間,只需要你提供一個郵箱地址和密碼。
到這裡登錄你的 Syncano 賬號。
如果你還沒有一個 Syncano 實例(一個實例就是一個項目) ,或者你准備用一個空實例,你可以創建一個新實例:
記住你的實例名稱,然後選擇它。
然後新建一個類,用這個類保存所有消息:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPjxpbWcgYWx0PQ=="" src="/uploadfile/Collfiles/20160302/2016030209173074.png" title="\" />
類名輸入 Message,並設置以下字段為:
text : String senderid : String attachment : File我們還需要添加一個頻道(Chanel),頻道是用來對數據進行實時同步的。
進入 Channels 頁面,添加一個頻道。頻道名字命名為 Messages,other permissions 設置為 publish。
最後,創建一個 API key,API key 用於連接數據庫。描述字段隨便填寫,但 Ignore ACL 必須設置為 True(將右邊的開關拉到 ON 位置)。
key 設置完後,記下 key——我們會在後面用到它。
首先,我們需要一個 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() 用於下載最新的消息,用服務器的消息替換掉原來的 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()
}
運行程序,你會看到一個空白的窗口。那是因為在服務器上還沒有任何聊天消息。發送幾條消息然後重啟 App ——你將看到消息已經存進了服務器。你可以登入你的 Syncano Dashboard 查看這些消息是否都保存到了 Message 類中。
這個 App 還有一個實時功能沒有實現,即每當服務器收到一條消息,客戶端就能立即收到。
我們可以在後台每隔幾秒就刷新一下消息列表,但更好的辦法是使用 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 我。