parse docs ios objective-c iphone parse.com pfobject

ios - docs - Usando JSQMessagesViewController con Parse.com



docs parse platform (1)

Me encontré con lo que parece ser una biblioteca muy compleja y personalizada que sería muy útil para cualquier aplicación que quiera tener un sistema de mensajería integrado. JSQMessagesViewController en Github . Mientras intentaba implementar la biblioteca por mi cuenta, tuve algunos problemas. Uno. No entiendo muy bien la terminología de "protocolos" y "clases" (entiendo un poco sobre clases). El primer problema fue que no pude usar PFObjects en CollectionView porque una instancia de JSQMessage debe pasarse a través de la mayoría de los métodos personalizados. Ahora, sé cómo tomar un PFObject y obtener las propiedades de ese tipo

self.eachMessage = [self.messages objectAtIndex:indexPath.row]; //each message self.eachMessage[@"message"] //message from the PFObject self.eachMessage[@"sender"] //sender from the PFObject

La clase JSQMessage tiene propiedades personalizadas que representarían las propiedades del PFObject como

JSQMessage *message = [[JSQMessage alloc] init]; //initialize it message.senderId //could be the objectId of the user message.senderDisplayName //the user''s username message.text //text of the message message.date //time sent of the message

El caso es que, en la clase personalizada JSQMessage ... todas estas propiedades son de solo lectura. Estoy seguro de que puedo entrar y cambiar eso para poder asignarles exactamente lo que quiero, pero debe haber algo que me falta aquí. Adjuntaré todo en mis archivos .h y .m. Cuando envío un mensaje, lo único que aparece es el texto, y creo que es así porque se inicia cuando proviene de textView en la barra de herramientas de entrada.

.h Archivo

#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 Archivo

- (void)viewDidLoad { [super viewDidLoad]; //Color of the keyboard (Dark to match everything else) self.inputToolbar.contentView.textView.keyboardAppearance = UIKeyboardAppearanceDark; //Color the inputview background self.inputToolbar.backgroundColor = [UIColor colorWithWhite:0 alpha:0.9]; //Delete the avatars appearing next to the messages self.collectionView.collectionViewLayout.incomingAvatarViewSize = CGSizeZero; self.collectionView.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero; //Set the senderID self.senderId = self.sender.objectId; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:YES]; //Query for part of the messages PFQuery *messages1 = [PFQuery queryWithClassName:@"Messages"]; [messages1 whereKey:@"sender" equalTo:self.sender]; [messages1 whereKey:@"receiver" equalTo:self.receiver]; //Query for other part of messages PFQuery *messages2 = [PFQuery queryWithClassName:@"Messages"]; [messages2 whereKey:@"sender" equalTo:self.receiver]; [messages2 whereKey:@"receiver" equalTo:self.sender]; //Combine those queries PFQuery *allMessages = [PFQuery orQueryWithSubqueries:@[messages1, messages2]]; [allMessages findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { self.messages = [objects mutableCopy]; [self.collectionView reloadData]; }]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } #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 the actual message at each indexpath.row return [self.messages objectAtIndex:indexPath.row]; } - (id<JSQMessageBubbleImageDataSource>)collectionView:(JSQMessagesCollectionView *)collectionView messageBubbleImageDataForItemAtIndexPath:(NSIndexPath *)indexPath { /** * You may return nil here if you do not want bubbles. * In this case, you should set the background color of your collection view cell''s textView. * * Otherwise, return your previously created bubble image data objects. */ 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 { //Number of messages return self.messages.count; } - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { //Number of sections return 1; } - (UICollectionViewCell *)collectionView:(JSQMessagesCollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { //Creating or initial cell for the number of index paths (number of messages) JSQMessagesCollectionViewCell *cell = (JSQMessagesCollectionViewCell *)[super collectionView:collectionView cellForItemAtIndexPath:indexPath]; //Put our messages dictionaries into PFObject so we can put them into individual cells self.eachMessage = [self.messages objectAtIndex:indexPath.row]; //Put the message object into the textView''s text property cell.textView.text = self.eachMessage.text; //Setting the text color of the message bubble based upon the sender if ([self.eachMessage.senderId isEqualToString:self.senderId]) { cell.textView.textColor = [UIColor blackColor]; } else { cell.textView.textColor = [UIColor whiteColor]; } //Set the top label to the person who sent the message cell.cellTopLabel.text = [NSString stringWithFormat:@"@%@", self.eachMessage.senderId]; //Format the bottom label to a readable date NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"MM/dd/yy h:mm a"]; cell.cellBottomLabel.text = [dateFormatter stringFromDate:self.eachMessage.date]; //If there is a link of some sorts in the message cell.textView.linkTextAttributes = @{ NSForegroundColorAttributeName : cell.textView.textColor, NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle | NSUnderlinePatternSolid) }; //What we return into the collectionview return cell; }


Aquí hay parte de mi código. Los archivos completos son grandes y mi jefe no estará contento si los comparto. :-)

Así es como cargué mi DemoData en mi DemoMessagesViewController :

self.demoData = [[DemoModelData alloc] init]; self.demoData.users = @{self.senderId:self.senderDisplayName, self.targetUserId:self.targetUserName}; UIImage *tempImg = [HTTPServerKaDost fetchImageFromUrlString:userProfile.profilePicUrl]; //replace with your code to load image JSQMessagesAvatarImage *srcImage = [JSQMessagesAvatarImageFactory avatarImageWithImage:tempImg diameter:kJSQMessagesCollectionViewAvatarSizeDefault]; tempImg = [HTTPServerKaDost fetchImageFromUrlString:self.targetUserImageFullUrl]; JSQMessagesAvatarImage *destImage = [JSQMessagesAvatarImageFactory avatarImageWithImage:tempImg diameter:kJSQMessagesCollectionViewAvatarSizeDefault]; self.demoData.avatars = @{self.senderId:srcImage, self.targetUserId:destImage}; [self.demoData loadMessages];

dentro del método loadMessages (agregado por mí dentro de DemoModelData Class), crea objetos JSQMessage :

JSQMessage *msg = [[JSQMessage alloc] initWithSenderId:[msgDict valueForKey:@"sender"] senderDisplayName:[msgDict valueForKey:@"fname"] date:dateT text:[msgDict valueForKey:@"data"]]; [self.messages addObject:msg];

y cada vez que desee actualizar la vista de chat, llame a esto dentro de DemoMessagesViewController :

[self finishReceivingMessageAnimated:YES]; [self scrollToBottomAnimated:YES];