# Quick Start Guide

## MessageType Protocol
The driving force behind **MessageKit** is the `MessageType` protocol which provides the minimum requirements for your own native message model. The `MessageType` protocol has the following 4 required properties:

```Swift
public protocol MessageType {

    var sender: Sender { get }

    var messageId: String { get }

    var sentDate: Date { get }

    var kind: MessageKind { get }
}
```
First, each `MessageType` is required to have a `SenderType` which contains two properties, `senderId` and `displayName`:
### Sender
```Swift
public protocol SenderType {

    var senderId: String { get }
    
    var displayName: String { get }
}

```
**MessageKit** uses the `SenderType` type to determine if a message was sent by the current user or to the current user.

Second, each message must have its own `messageId` which is a unique `String` identifier for the message.

Third, each message must have a `sentDate` which represents the `Date` that each message was sent.

Fourth, each message must specify what kind of message it is through the `kind: MessageKind` property:
### [MessageKind](https://github.com/MessageKit/MessageKit#default-cells)

`MessageKind` has 8 different cases representing the types of messages that **MessageKit** can display.

- `text(String)` - Use this case if you just want to display a normal text message without any attributes.
  - **NOTE**: You must also specify the `UIFont` you want to use for this text by setting the `messageLabelFont` property of the `textMessageSizeCalculator` in `MessagesCollectionViewFlowLayout`.

- `attributedText(NSAttributedString)` - Use this case if you want to display a text message with attributes.
  - **NOTE**: It is recommended that you use `attributedText` for text messages.

- `emoji(String)` - Use this case to display a message that only contains emoji.
  - **NOTE**: You must also specify the `UIFont` you want to use for this text by setting the `messageLabelFont` property of the `emojiMessageSizeCalculator` in `MessagesCollectionViewFlowLayout`.

- `photo(MediaItem)` - Use this case to display a photo message.

- `video(MediaItem)` - Use this case to display a video message.

- `location(LocationItem)` - Use this case to display a location message.

- `audio(AudioItem)` - Use this case to display an audio message.

- `contact(ContactItem)` - Use this case to display a contact message.

# MessagesViewController

## Subclassing MessagesViewController
To begin using **MessageKit** you first need to subclass `MessagesViewController`:
```Swift
class ChatViewController: MessagesViewController {
	override func viewDidLoad() {
		super.viewDidLoad()
	}
}
```
**NOTE**: If you override any of the `UIViewController` lifecycle methods such as `viewDidLoad`, `viewWillAppear`, `viewDidAppear`, make sure to call the superclass implementation of these methods.

## Displaying Messages in your MessagesViewController
In order to start displaying messages in your `MessagesViewController` subclass, you NEED to conform to the following 3 protocols:

1. `MessagesDataSource`
2. `MessagesLayoutDelegate`
3. `MessagesDisplayDelegate`

```Swift
class ChatViewController: MessagesViewController {
	override func viewDidLoad() {
		super.viewDidLoad()
		messagesCollectionView.messagesDataSource = self
		messagesCollectionView.messagesLayoutDelegate = self
		messagesCollectionView.messagesDisplayDelegate = self
	}
}
```

### MessagesDataSource

You must implement the following 3 methods to conform to `MessagesDataSource`:

```Swift

public struct Sender: SenderType {
    public let senderId: String

    public let displayName: String
}

// Some global variables for the sake of the example. Using globals is not recommended!
let sender = Sender(senderId: "any_unique_id", displayName: "Steven")
let messages: [MessageType] = []

extension ChatViewController: MessagesDataSource {

	var currentSender: SenderType {
		return Sender(senderId: "any_unique_id", displayName: "Steven")
	}

	func numberOfSections(in messagesCollectionView: MessagesCollectionView) -> Int {
		return messages.count
	}

	func messageForItem(at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageType {
		return messages[indexPath.section]
	}
}
```
**NOTE**: If you look closely at the implementation of the `messageForItem` method you'll see that we use the `indexPath.section` to retrieve our `MessageType` from the array as opposed to the traditional `indexPath.row` property. This is because the default behavior of **MessageKit** is to put each `MessageType` is in its own section of the `MessagesCollectionView`. 

If you want to override this behavior, you can specify the number of items in each section through the `numberOfItems` method of `MessagesDataSource`.

As you can see **MessageKit** does not require you to return a `MessagesCollectionViewCell` like the traditional `UITableView` or `UICollectionView` API. All that is required is for you to return your `MessageType` model object. We take care of applying the model to the cell for you.

### MessagesLayoutDelegate & MessagesDisplayDelegate

The `MessagesLayoutDelegate` and `MessagesDisplayDelegate` don't require you to implement any methods as they have default implementations for everything. You just need to make your `MessagesViewController` subclass conform to these two protocols and set them in the `MessagesCollectionView` object.

```Swift
extension ChatViewController: MessagesDisplayDelegate, MessagesLayoutDelegate {}
```
