I came across what looks like a very complex and customizable library that would be very useful for any application that wants to create a messaging system. JSQMessagesViewController on Github . While I was trying to implement the library myself, I ran into some problems. Alone, I do not quite understand the terminology of โprotocolsโ and โclassesโ (I am a little versed in classes). The first problem was that I could not use PFObjects in the CollectionView, because the JSQMessage instance should go through most of the custom methods. Now I know how to take in PFObject to get properties from this, for example
self.eachMessage = [self.messages objectAtIndex:indexPath.row];
self.eachMessage[@"message"]
self.eachMessage[@"sender"]
The JSQMessage class has custom properties that will represent PFObject properties, for example
JSQMessage *message = [[JSQMessage alloc] init];
message.senderId
message.senderDisplayName
message.text
message.date
The thing is, in the JSQMessage custom class ... all of these properties are read-only. Iโm sure I can go in and change it so that I can assign them exactly what I want, but here Iโm missing something. I will attach everything in my .h and .m files. When I send a message , the only thing that comes is text, and I believe that this is because it rises when it comes from textView on the input tab.
.h file
#import <UIKit/UIKit.h>
#import <JSQMessagesViewController/JSQMessages.h>
#import <Parse/Parse.h>
#import <JSQMessagesViewController/JSQMessagesBubbleImageFactory.h>
@interface ConvoViewController : JSQMessagesViewController
@property (strong, nonatomic) NSMutableArray *messages;
@property (strong, nonatomic) PFUser *sender;
@property (strong, nonatomic) PFUser *receiver;
@property (strong, nonatomic) JSQMessage *eachMessage;
@property (strong, nonatomic) PFObject *aMessage;
@property (strong, nonatomic) JSQMessagesBubbleImageFactory *bubbleImage;
@end
.m file
- (void)viewDidLoad {
[super viewDidLoad];
self.inputToolbar.contentView.textView.keyboardAppearance = UIKeyboardAppearanceDark;
self.inputToolbar.backgroundColor = [UIColor colorWithWhite:0 alpha:0.9];
self.collectionView.collectionViewLayout.incomingAvatarViewSize = CGSizeZero;
self.collectionView.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero;
self.senderId = self.sender.objectId;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:YES];
PFQuery *messages1 = [PFQuery queryWithClassName:@"Messages"];
[messages1 whereKey:@"sender" equalTo:self.sender];
[messages1 whereKey:@"receiver" equalTo:self.receiver];
PFQuery *messages2 = [PFQuery queryWithClassName:@"Messages"];
[messages2 whereKey:@"sender" equalTo:self.receiver];
[messages2 whereKey:@"receiver" equalTo:self.sender];
PFQuery *allMessages = [PFQuery orQueryWithSubqueries:@[messages1, messages2]];
[allMessages findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
self.messages = [objects mutableCopy];
[self.collectionView reloadData];
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - Send Button
- (void)didPressSendButton:(UIButton *)button withMessageText:(NSString *)text senderId:(NSString *)senderId senderDisplayName:(NSString *)senderDisplayName date:(NSDate *)date {
[JSQSystemSoundPlayer jsq_playMessageSentSound];
JSQMessage *message = [[JSQMessage alloc] initWithSenderId:self.sender.objectId
senderDisplayName:self.sender.username
date:[NSDate date]
text:text];
[self.messages addObject:message];
NSLog(@"%@", text);
[self finishSendingMessageAnimated:YES];
}
#pragma mark - JSQMessages Data Source methods
- (id<JSQMessageData>)collectionView:(JSQMessagesCollectionView *)collectionView messageDataForItemAtIndexPath:(NSIndexPath *)indexPath
{
return [self.messages objectAtIndex:indexPath.row];
}
- (id<JSQMessageBubbleImageDataSource>)collectionView:(JSQMessagesCollectionView *)collectionView messageBubbleImageDataForItemAtIndexPath:(NSIndexPath *)indexPath
{
JSQMessage *message = [self.messages objectAtIndex:indexPath.item];
if ([message.senderId isEqualToString:self.senderId]) {
return [self.bubbleImage incomingMessagesBubbleImageWithColor:[UIColor orangeColor]];
}
return [self.bubbleImage outgoingMessagesBubbleImageWithColor:[UIColor grayColor]];
}
#pragma mark - Collection View
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.messages.count;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (UICollectionViewCell *)collectionView:(JSQMessagesCollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
JSQMessagesCollectionViewCell *cell = (JSQMessagesCollectionViewCell *)[super collectionView:collectionView cellForItemAtIndexPath:indexPath];
self.eachMessage = [self.messages objectAtIndex:indexPath.row];
cell.textView.text = self.eachMessage.text;
if ([self.eachMessage.senderId isEqualToString:self.senderId]) {
cell.textView.textColor = [UIColor blackColor];
} else {
cell.textView.textColor = [UIColor whiteColor];
}
cell.cellTopLabel.text = [NSString stringWithFormat:@"@%@", self.eachMessage.senderId];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM/dd/yy h:mm a"];
cell.cellBottomLabel.text = [dateFormatter stringFromDate:self.eachMessage.date];
cell.textView.linkTextAttributes = @{ NSForegroundColorAttributeName : cell.textView.textColor,
NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle | NSUnderlinePatternSolid) };
return cell;
}