Я реализую чат между водителем и пользователем в приложении такси. Я получаю сообщение от API и отображаю его в чате, но чат переворачивается в зависимости от идентификатора последнего сообщения
Я просто хочу добавить входящие сообщения в левой части экрана.
import Foundation
import MessageKit
class ChatViewController: MessagesViewController {
private lazy var loader:UIView = {
return createActivityIndicator(UIScreen.main.focusedView ?? self.view)
}()
@IBOutlet weak var topView: UIView!
let imageView : UIImageView = {
let iv = UIImageView()
iv.image = UIImage(named:"backgroundImg")
iv.contentMode = .scaleAspectFill
return iv
}()
var userId = NSNumber()
var providerId = NSNumber()
var rideId = NSNumber()
var timer = Timer()
override func viewDidLoad() {
super.viewDidLoad()
member = Member(name: "User", color: .headingGold)
messagesCollectionView.messagesDataSource = self
messagesCollectionView.messagesLayoutDelegate = self
messageInputBar.delegate = self
messagesCollectionView.messagesDisplayDelegate = self
var topSafeAreaHeight: CGFloat = 0
var bottomSafeAreaHeight: CGFloat = 0
let window = UIApplication.shared.windows[0]
if #available(iOS 11.0, *) {
let safeFrame = window.safeAreaLayoutGuide.layoutFrame
topSafeAreaHeight = safeFrame.minY
bottomSafeAreaHeight = safeFrame.maxY
} else {
topSafeAreaHeight = 10
}
self.topView.frame = CGRect(x: 10, y: topSafeAreaHeight, width: self.view.frame.size.width-20, height: 60)
self.topView.layer.cornerRadius = 10
self.messagesCollectionView.contentInset = UIEdgeInsets(top: topView.frame.maxY, left: 0, bottom: 70, right: 0)
messagesCollectionView.backgroundView = imageView
func backgroundColor(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> UIColor {
return isFromCurrentSender(message: message) ? UIColor.myGold : UIColor.headingGold
}
getChatHistory()
self.timer = Timer.scheduledTimer(timeInterval: 6.0, target: self, selector: #selector(getChatHistory), userInfo: nil, repeats: true)
}
override func viewDidAppear(_ animated: Bool) {
view.bringSubviewToFront(topView)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(true)
timer.invalidate()
}
@objc func getChatHistory(){
self.messages = []
let request = NSMutableURLRequest(url: NSURL(string: "\(ServiceConstants.baseUrl+ServiceConstants.MD_GET_CHAT)?request_id=\("\(self.rideId)")&user_id=\(self.userId)")! as URL)
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("XMLHttpRequest", forHTTPHeaderField: "X-Requested-With")
let tokenStr:NSString = UserDefaults.standard.value(forKey: "tokentype") as! NSString
let accessStr:NSString = UserDefaults.standard.value(forKey: "accesstoken") as! NSString
let str = NSString(format: "%@ %@", tokenStr, accessStr) as String
request.addValue(str, forHTTPHeaderField: "Authorization")
let session = URLSession.shared
// self.loader.isHidden = false
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
// DispatchQueue.main.async {
// self.loader.isHidden = true
//
// }
if (error != nil) {
print(error!)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse!)
do {
if let jsonResult = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary {
print(jsonResult)
let messagesArray = jsonResult["messages"] as! NSArray
for dictVal in messagesArray
{
if let str = dictVal as? [String:AnyObject]
{
let msg = str["message"] as! String
let type = str["type"] as! String
self.member = Member(name: type, color: .myGold)
let newMessage = Message(
member: self.member,
text: msg,
messageId: UUID().uuidString)
// self.messageCallback(newMessage)
self.messages.append(newMessage)
}
}
DispatchQueue.main.async{
self.messagesCollectionView.reloadData()
self.messagesCollectionView.scrollToBottom(animated: true)
}
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
})
dataTask.resume()
}
func sendMsg(msg:String){
let parameters:[String:String] = ["user_id":"\(userId)","provider_id":"\(providerId)","request_id":"\(rideId)","type":"up","message":"\(msg)"]
let url = URL(string: ServiceConstants.baseUrl + ServiceConstants.MD_SEND_CHAT_MSG)!
let session = URLSession.shared
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("XMLHttpRequest", forHTTPHeaderField: "X-Requested-With")
let tokenStr:NSString = UserDefaults.standard.value(forKey: "tokentype") as! NSString
let accessStr:NSString = UserDefaults.standard.value(forKey: "accesstoken") as! NSString
let str = NSString(format: "%@ %@", tokenStr, accessStr) as String
request.addValue(str, forHTTPHeaderField: "Authorization")
do{
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
}catch let error
{
print(error.localizedDescription)
}
self.loader.isHidden = false
let task = session.dataTask(with: request, completionHandler: {data, response, error in
DispatchQueue.main.async {
self.loader.isHidden = true
}
print(response as Any)
guard error == nil else{return}
guard let data = data else{return}
do{
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:Any]
{
print(json)
}
}catch let error
{
print(error.localizedDescription)
}
})
task.resume()
}
var messages: [Message] = []
var member: Member!
@IBAction func backBtnAction(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
}
extension ChatViewController: MessagesDataSource {
func numberOfSections(
in messagesCollectionView: MessagesCollectionView) -> Int {
return messages.count
}
func currentSender() -> Sender {
return Sender(id: member.name, displayName: member.name)
}
func messageForItem(
at indexPath: IndexPath,
in messagesCollectionView: MessagesCollectionView) -> MessageType {
return messages[indexPath.section]
}
func messageTopLabelHeight(
for message: MessageType,
at indexPath: IndexPath,
in messagesCollectionView: MessagesCollectionView) -> CGFloat {
return 12
}
func messageTopLabelAttributedText(
for message: MessageType,
at indexPath: IndexPath) -> NSAttributedString? {
return NSAttributedString(
string: message.sender.displayName,
attributes: [.font: UIFont.systemFont(ofSize: 12)])
}
}
extension ChatViewController: MessagesLayoutDelegate {
func heightForLocation(message: MessageType,
at indexPath: IndexPath,
with maxWidth: CGFloat,
in messagesCollectionView: MessagesCollectionView) -> CGFloat {
return 0
}
}
extension ChatViewController: MessagesDisplayDelegate {
func configureAvatarView(
_ avatarView: AvatarView,
for message: MessageType,
at indexPath: IndexPath,
in messagesCollectionView: MessagesCollectionView) {
let message = messages[indexPath.section]
let color = message.member.color
avatarView.backgroundColor = color
}
}
extension ChatViewController: MessageInputBarDelegate {
func messageInputBar(
_ inputBar: MessageInputBar,
didPressSendButtonWith text: String) {
sendMsg(msg: text)
member = Member(name: "up", color: .myGold)
let newMessage = Message(
member: member,
text: text,
messageId: UUID().uuidString)
messages.append(newMessage)
inputBar.inputTextView.text = ""
messagesCollectionView.reloadData()
messagesCollectionView.scrollToBottom(animated: true)
}
}
struct Member {
let name: String
let color: UIColor
}
struct Message {
let member: Member
let text: String
let messageId: String
}
extension Message: MessageType {
var sender: Sender {
return Sender(id: member.name, displayName: member.name)
}
var sentDate: Date {
return Date()
}
var kind: MessageKind {
return .text(text)
}
}
Это мой класс для chatViewController, и это мой первый опыт работы с messageKit. Возможно, мне не хватает чего-то простого или тривиального ..