你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> 用 JSQMessagesViewController 創建一個 iOS 聊天 App - 第 1 部分

用 JSQMessagesViewController 創建一個 iOS 聊天 App - 第 1 部分

編輯:IOS開發綜合

在本教程中,我將介紹如何創建一個簡單的 iOS 聊天 App(用 swift 和 Syncano)。我們將從最基本的功能開始——發送、接收消息,將消息保存到服務器,然後再進入用戶賬號和認證等主題。

我們會在後端用到 Syncano 及其 iOS 庫,前端使用 JSQMessagesViewController 庫。

在第一部分,我們將包含創建新項目,添加 JSQMessagesViewController(然後在上面顯示一些測試消息)。在第二部分,我們將數據存到服務器並實時同步(當新消息一存到數據庫就立即顯示,不需要任何刷新操作)。最後,在第三部分,我們將增加用戶認證功能——注冊、登錄並向用戶顯示正確的信息。

創建新項目

實現,創建新項目。打開 Xcode,創建一個 Single View Application 項目。項目名稱輸入 SyncanoChat。語言選擇 Swift。

安裝 CocoaPods

要使用 Syncano iOS 庫和 JSQMessagesViewController,我們必須使用 CocoaPods。

安裝 CocoaPods

如果你沒有安裝過 CocoaPods,需要在終端下安裝它:

sudo gem install cocoapods

輸入密碼,回車,等待安裝完成。

導入庫

在終端程序下,進入剛剛創建的項目目錄,例如:

cd ~/path/to/my/project/SyncanoChat

初始化 Cocoapods:

pod init

編輯 Podfile 文件:

open Podfile

在文件中導入所需庫(在 target ‘SyncanoChat’ do 和 end 之間),然後取消注釋 use_frameworks 一行,或者直接替換文件內容為:

# Uncomment this line to define a global platform for your project
# platform :ios, '8.0'
# Uncomment this line if you're using Swift
use_frameworks!

target 'SyncanoChat' do
pod 'syncano-ios'
pod 'JSQMessagesViewController'

end

target 'SyncanoChatTests' do

end

target 'SyncanoChatUITests' do

end

保存文件,關閉文本編輯器(我們不會再修改這個文件了),在終端中輸入:

pod install

當命令執行完成,關閉 Xcode,然後打開 Workspace 文件:

open SyncanoChat.xcworkspace

運行程序,確保沒有任何錯誤發生!

添加 Objective-C 橋接頭文件

這一步不是必須的,如果你沒有取消注釋 use_frameworks! 一行的話。如果是這樣的話,跳到下一步。

如果因為某種原因,你無法使用 Cocoapods 的 use_frameworks! 特性(動態庫)或者 你寧願使用靜態庫,則你必須添加橋接頭文件。

使用菜單:

File -> New -> File

選擇 Cocoa class,點擊 Next,隨便輸入一個類名(我們不會用到這個類),比如 Test,將語言修改為 Objective-C,然後點 Next。

當問到是否創建一個 Objective_C bridging header 時,選擇 Yes。

這會在默認位置創建2個文件。然後在 Xcode 中選擇這個文件並刪除它。

當問到是否將2個文件放到垃圾桶時,選擇 Move to Trash。

注意在創建類文件的同時,Xcode 也會創建一個 SyncanoChat-Bridging-Header.h 的橋接頭文件。打開這個文件,加入2行:

#import 
#import 

保存文件,再次編譯項目已確認編譯通過。現在,你可以在 Swift 代碼中使用這兩個庫了。

Message Controller

子類化 JSQMessagesViewController

現在開始使用 JSQMessagesViewController。在 XCode 項目導航窗口中,打開 ViewController.swift。

目前它還是一個 UIViewController 子類,將它改成 JSQMessagesViewController子類:

import UIKit

class ViewController: JSQMessagesViewController {
//...
// rest of the class
//...
}

如果你沒有使用橋接頭文件,你可能需要在 import UIKit 下加 2 個 import 語句,如下所示:

import UIKit
import JSQMessagesViewController
import syncano_ios

編譯項目,確認 Xcode 能連接到所有文件並能夠識別出 JSQMessagesViewController 類。

添加屬性

現在加幾個變量,用於存儲消息數據和 UI 組件:

messages:用於存放接收消息和發出的消息。因為每當我們發送或接收到一條消息時,messages 中都會添加這條消息,因此它是可變的。 incomingBubble:JSQMessagesViewController 會用到它,用於定義接收消息的背景圖片,我們不會改變它,因此它定義為常量。 outgoingBubble:JSQMessagesViewController 會用到它,用於定義已發出的消息的背景圖片,我們不會改變它,因此它定義為常量。

增加上述屬性:

    let incomingBubble = JSQMessagesBubbleImageFactory().incomingMessagesBubbleImageWithColor(UIColor(red: 10/255, green: 180/255, blue: 230/255, alpha: 1.0))
    let outgoingBubble = JSQMessagesBubbleImageFactory().outgoingMessagesBubbleImageWithColor(UIColor.lightGrayColor())
    var messages = [JSQMessage]()

添加測試消息

在我們引入 Syncano 之前,我們加一些測試數據用於顯示。

在 ViewController 中新增一個方法:

func reloadMessagesView() {
   self.collectionView?.reloadData()
}

這個方法用於刷新消息列表,我們將加載列表封裝為單獨的方法。

在 ViewController.swift 加入一個擴展:

//MARK - Setup
extension ViewController {
    func addDemoMessages() {
        for i in 1...10 {
            let sender = (i%2 == 0) ? "Server" : self.senderId
            let messageContent = "Message nr. \(i)"
            let message = JSQMessage(senderId: sender, displayName: sender, text: messageContent)
            self.messages += [message]
        }
        self.reloadMessagesView()
    }

    func setup() {
        self.senderId = UIDevice.currentDevice().identifierForVendor?.UUIDString
        self.senderDisplayName = UIDevice.currentDevice().identifierForVendor?.UUIDString
    }
}

setup 方法用於將設備唯一 ID 指定給 senderID 和 senderDisplayName —— 二者都是 JSQMessagesViewController 所必須的,用於區分消息是誰所發以及發給誰。

在 viewDidLoad 方法中調用這兩個方法:

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.setup()
        self.addDemoMessages()
    }

運行 App。它不會顯示任何東西,但我們用於顯示的測試消息已經准備好了。

實現 JSQMessagesViewController 協議

我們必須實現幾個方法,尤其是 JSQMessagesCollectionViewDataSource 協議方法。

在 ViewController.swift 中增加一個擴展:

//MARK - Data Source
extension ViewController {

    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.messages.count
    }

    override func collectionView(collectionView: JSQMessagesCollectionView!, messageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageData! {
        let data = self.messages[indexPath.row]
        return data
    }

    override func collectionView(collectionView: JSQMessagesCollectionView!, didDeleteMessageAtIndexPath indexPath: NSIndexPath!) {
        self.messages.removeAtIndex(indexPath.row)
    }

    override func collectionView(collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageBubbleImageDataSource! {
        let data = messages[indexPath.row]
        switch(data.senderId) {
        case self.senderId:
            return self.outgoingBubble
        default:
            return self.incomingBubble
        }
    }

    override func collectionView(collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource! {
        return nil
    }
}

這些方法分別用於告訴 JSQMessagesViewController:

- 有多少條消息要顯示(即 messages 數組中的消息條數)
- 每一行都分別顯示哪條消息
- 當一條消息被刪除時做些什麼(從 messages 數組中移除)
- 每一條消息顯示什麼樣的氣泡(如果是我們發出的消息顯示表示“發出消息”的氣泡圖片,否則顯示表示“接收消息”的氣泡圖片)
- 頭像上要顯示什麼(這裡返回的是 Nil,也就是說不顯示頭像)

運行 App,現在它會顯示測試消息了!如果點擊工具欄中的按鈕,會導致 App 崩潰。

### 處理按鈕事件

要解決 App 崩潰的問題,必須實現兩個方法,一個用於處理左邊的媒體按鈕事件,一個用於處理右邊的發送按鈕事件。在 ViewController.swift 中添加一個擴展:

```swift
//MARK - Toolbar
extension ViewController {
    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.finishSendingMessage()
    }

    override func didPressAccessoryButton(sender: UIButton!) {

    }
}

當點擊發送按鈕時,我們將輸入內容添加到 messages 並刷新 UI。而在 didPressAccessoryButton(_) 方法中,我們什麼也不干,只是讓 App 不再崩潰而已。

總結

你已經完成了一個聊天 App 的所有界面,可以發送消息或看到別人發送的消息了。

在第二部分,我們繼續學習和 Syncano 打交道,包括保存消息到服務器,以及消息的實時同步。

你可以在 GitHub 上下載這部分的源代碼。

如果你有任何問題,請 tweet 我。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved