2

I want to make a private chat with Parse and Pubnub. When a user receives an image from another friend, he can click on "reply by message", that opens a new view, and here is the private chat between the 2 friends. I use "BubbleView" in framework for giving an iOS messaging aspect. How can I make a private channel in Pubnub ? I've added

PFUser *user = [PFUser currentUser];

channel = [PNChannel channelWithName:user.objectId];

but that affects only the channel to the user who are using the app, not channel for the 2 persons ... ? With my code I can receive my own message, the console says : PubNub (xxxxxxxxxx) SUBSCRIBED ON CHANNELS: ( "PNChannel(xxxxxxxxx) objectID(user from parse who are using the app)" Message received: the message i've sent

Here is my code :

ChatViewController.h :

#import "MessagesViewController.h"
#import "PNImports.h"

@interface ChatViewController : MessagesViewController

@property (strong, nonatomic) NSMutableArray *messages;

@end

ChatViewController.m :

#import "ChatViewController.h"
#import <Parse/Parse.h>

@interface ChatViewController ()

@end
PNChannel *channel;
id message;
NSDate *receiveDate;
NSString *text;
@implementation ChatViewController

#pragma mark - View lifecycle
- (void)viewDidLoad
{

    [super viewDidLoad];
    self.title = @"Messages";
    self.messages = [[NSMutableArray alloc] initWithObjects:
                     @"Testing some messages here.", @"lol",
                     nil];
    UIButton *exitButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [exitButton addTarget:self action:@selector(backToInboxView) forControlEvents:UIControlEventTouchUpInside];
    [exitButton setTitle:@"Inbox" forState:UIControlStateNormal];
    exitButton.frame = CGRectMake(0.0, 0.0, 60, 60);
    [self.view addSubview:exitButton];

    // #1 Define client configuration
    PNConfiguration *myConfig = [PNConfiguration configurationForOrigin:@"pubsub.pubnub.com"
                                                             publishKey:@"demo"
                                                           subscribeKey:@"demo"
                                                              secretKey:nil];
    // #2 make the configuration active
    [PubNub setConfiguration:myConfig];
    // #3 Connect to the PubNub
    [PubNub connect];

   }


#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.messages.count;
}

#pragma mark - Messages view controller
- (BubbleMessageStyle)messageStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return (indexPath.row % 2) ? BubbleMessageStyleIncoming : BubbleMessageStyleOutgoing;
}

- (NSString *)textForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return [self.messages objectAtIndex:indexPath.row];
}

- (void)sendPressed:(UIButton *)sender withText:text
{
    [self.messages addObject:text];
    if((self.messages.count - 1) % 2)
        [MessageSoundEffect playMessageSentSound];
    else
        [MessageSoundEffect playMessageReceivedSound];
    PFUser *user       = [PFUser currentUser];
    channel = [PNChannel channelWithName:user.objectId];
    // Receive Messages Sent to Me!
    [PubNub subscribeOnChannel:channel];
    // Send a Message to Sally
    [PubNub sendMessage:text toChannel:channel];
    [self finishSend];
}

- (void)backToInboxView{
    [self.navigationController popToRootViewControllerAnimated:YES];
}


@end

and in Appdelegate.m :

- (void)pubnubClient:(PubNub *)client didSubscribeOnChannels:(NSArray *)channels {
    NSLog(@"DELEGATE: Subscribed to channel:%@", channels);
}
- (void)pubnubClient:(PubNub *)client didReceiveMessage:(PNMessage *)message {
    NSLog(@"Message received: %@", message.message);
}
Vjardel
  • 1,065
  • 1
  • 13
  • 28
  • You could create a chat object on parse that contains the two users. Then you could use the object id of that chat as the pubnub channel. This way you can query all of a users chats and know which channels to listen for. This could be useful if another user starts a chat and this user hasn't been notified yet. Not sure if that helps or not. – Logan Dec 02 '14 at 18:33
  • @Logan good idea, but how to create a chat object on parse that contains the two users? – Vjardel Dec 02 '14 at 18:44
  • You could just create new object, like `PFObject *chat = [PFObject objectWithClassName:@"Chat"]` then add the users: `chat[@"users"] = @[[PFUser currentUser], otherUser];`. Once this is set up, you can do a query like `query whereKey:@"users" equalTo:[PFUser currentUser]];` and it will get all chats where the current user is included. – Logan Dec 02 '14 at 18:50
  • @Logan It's a real good idea, but I don't know how to store the PFUser of the otherUser :( Can you reply on : http://stackoverflow.com/questions/27297817/how-to-store-pfuser-objectid-with-recipientid – Vjardel Dec 04 '14 at 15:41
  • @Logan Can you help me about to store the PFUser of the otherUser ? I'll be glad to have just this, thanks Logan ! – Vjardel Dec 05 '14 at 15:02
  • How do you send the message to the other user? Do you have a reference to the user object or the objectId? – Logan Dec 05 '14 at 15:06
  • @Logan I have just the PFUser currentUser objectId, but I don't know how to store the PFUser otherUser (user object or objectId). Here is my case : User A sends an image to User B. User B sees and opens on inbox the image from user A. User B tap on "reply" button and then he can send another image to user A. I can't find PFUser of the otherUser (user A). I hope you'll understand :) – Vjardel Dec 05 '14 at 15:20
  • @Logan You can find my code for inbox class in this URL : http://stackoverflow.com/questions/27297817/how-to-store-pfuser-objectid-with-recipientid – Vjardel Dec 05 '14 at 15:22
  • Ok, you'll have to store some reference to User A in your message. For example if UserA sends a MessageObject to userB, there should be a field on MessageObject that points to User A. I often use author, so MessageObject[@"author"] = userA. Then when UserB receives the message, they can get user a by saying UserA = receivedMessage[@"author"] and send back that way. Make sense? – Logan Dec 05 '14 at 15:25
  • @Logan Yes that make a perfect sense, I will try tonight, thanks again, I come back to you if I've any problem ! – Vjardel Dec 05 '14 at 15:43

1 Answers1

1

Although in JavaScript, this is an extremely detailed tutorial on how to implement chat functionality (with private + public channels) with PubNub:

http://www.pubnub.com/blog/javascript-private-chat-api-with-access-control/

The same features exist for the PubNub ObjectiveC client.

PubNub channels alone are just channels -- there is no attribute on a channel that says a channel is private or public. To simulate "private", you can create hard-to-guess names for private channels (and don't give those names out), but over time, thats not the most secure solution.

To really make a PubNub channel private, use the PAM feature (as detailed in the tutorial). This will allow you to grant and revoke authorization tokens to specific channels, so even if someone does guess a private channel name, they cannot access it without knowing the auth token.

To lock it down even more, you can use built-in encryption, and with that running over a secure (SSL) PubNub connection, you've got a pretty secure and scaleable solution.

Geremy
  • 2,415
  • 1
  • 23
  • 27