Search code examples
iosobjective-cjsqmessagesviewcontroller

JSQMessagesViewController - Send text Message with Attached Images File


I am using JSQMessagesViewController for sending and receiving messages.It works well for text Messages. Is it possible to send Text Message with attached Image File using JSQMessagesViewController Framework.

The attached image file should be shown, when it is clicked on. Something like this.

Send messages should be shown like this in Message window.

enter image description here

For Sending Photo

- (void)addPhotoMediaMessage
{
   JSQPhotoMediaItem *photoItem = [[JSQPhotoMediaItem alloc] initWithImage:[UIImage imageNamed:@"goldengate"]];
   JSQMessage *photoMessage = [JSQMessage messageWithSenderId:kJSQDemoAvatarIdSquires
                                               displayName:kJSQDemoAvatarDisplayNameSquires
                                                     media:photoItem];
  [self.messages addObject:photoMessage];
}

Sending text Message

- (void)didPressSendButton:(UIButton *)button
       withMessageText:(NSString *)text
              senderId:(NSString *)senderId
     senderDisplayName:(NSString *)senderDisplayName
                  date:(NSDate *)date
{
    [JSQSystemSoundPlayer jsq_playMessageSentSound];
    JSQMessage *message = [JSQMessage messageWithSenderId:senderId
                                          displayName:senderDisplayName
                                                 text:text];
   [self.messages addObject:message];
   [self finishSendingMessageAnimated:YES];
   [self receiveAutoMessage];
}

Solution

  • To accomplish this task you will have to create a custom cell and then use that cell in your CollectionView

    First of all subclass the JSQMessage class to something like following to keep the data for the image urls(attachments) -

    class ChatMessage: JSQMessage {
    
        internal var attachments : [NSURL]?
    
        init(senderId: String!, senderDisplayName: String!, date: NSDate!, text: String!, attachments: [NSURL]?) {
            self.attachments = attachments
            super.init(senderId: senderId, senderDisplayName: senderDisplayName, date: date, text: text)
        }
    
        init(senderId: String!, senderDisplayName: String!, date: NSDate!, media: JSQMessageMediaData!) {
            super.init(senderId: senderId, senderDisplayName: senderDisplayName, date: date, media: media)
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        } 
    
    }
    

    Now you will have to use this class for all your chat messages.

    Next, you will have to create a custom xib file for your custom cell. In that xib you will add a label and image view for the message text and attachment icon.

    Now create a class representing your custom cell. It will be something as follows -

    class CustomCell: UICollectionViewCell {
        @IBOutlet weak var topLabel: UILabel!
        @IBOutlet weak var bottomLabel: UILabel!
        @IBOutlet weak var containerView: UIView!
        @IBOutlet weak var dataLabel: UILabel!
        @IBOutlet weak var attachmentIcon: UIImage!
    
        override func awakeFromNib() {
            super.awakeFromNib()
        }
    }
    

    Now we have to use this CustomCell in our JSQMessagesViewController subclass.

    In viewDidLoad register your nib with the collection view

    self.collectionView.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellWithReuseIdentifier: "CustomCell")
    

    Now you can finally use your custom cell -

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let message = messages[indexPath.item]
    
        if message.attachments.count() != 0 {
            let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CustomCell", forIndexPath: indexPath) as! CustomCell
    
            cell.containerView.backgroundColor = UIColor.jsq_messageBubbleBlueColor()
            cell.containerView.layer.cornerRadius = 15
            return cell
        }
    
        else {
            // Add code here for the normal cell
        }
    }
    

    This should successfully render your custom cell.

    Finally on tapping the custom view cell you can segue to a new VC (dont forget to pass your images data) and show the images appropriately.