Search code examples
rubymotionsendbird

SendBird chat SDK Rubymotion integration


I am trying to integrate the SendBird SDK chat with Rubymotion (via its CocoaPod).

The initial steps work fine and I have been able to add the pod to my Rakefile (using motion-cocoapods) and compile with no issues, login users and create a messaging channel. However, the event handler has me stumped.

These are the steps i have been able to translate from the SendBird docs:

Initialize in app delegate

SendBird Objective C:

#import <SendBirdSDK/SendBirdSDK.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // ...
    NSString *APP_ID = @"<YOUR_APP_ID>"; // You could get it from SendBird Dashboard.
    [SendBird initAppId:APP_ID];
    // ...
    return YES;
}

Rubymotion:

APP_ID = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx"
SendBird.initAppId(APP_ID)

Login to SendBird when signing in / registering in my app

SendBird Objective C:

- (void)viewDidLoad
{    
    // other setup code
    [SendBird loginWithUserId:USER_ID andUserName:USER_NICKNAME];   
}

Rubymotion:

(I store user information in Auth.current_user hash once logged in)

SendBird.loginWithUserId(Auth.current_user["id"],andUserName:Auth.current_user["name"])

Create a Messaging Channel and setup an event handler

SendBird Objective C:

[SendBird startMessagingWithUserId:targetUserId]; // 1 on 1 channel

// In your event handler
[SendBird setEventHandlerConnectBlock:^(SendBirdChannel *channel) {
    // Callback for [SendBird connectWithTS:] or [SendBird connect:]
} errorBlock:^(NSInteger code) {
    // Error occured due to bad APP_ID (or other unknown reason)
} channelLeftBlock:^(SendBirdChannel *channel) {
    // Callback for [SendBird leaveChannel:]
} messageReceivedBlock:^(SendBirdMessage *message) {
    // Received a regular chat message
} fileReceivedBlock:^(SendBirdFileLink *fileLink) {
    // Received a file
} messagingStartedBlock:^(SendBirdMessagingChannel *channel) {
    // Callback for [SendBird startMessagingWithUserId:] or [SendBird inviteMessagingWithChannelUrl:]
} messagingUpdatedBlock:^(SendBirdMessagingChannel *channel) {
    // Callback for [SendBird inviteMessagingWithChannelUrl:]
} messagingEndedBlock:^(SendBirdMessagingChannel *channel) {
    // Callback for [SendBird endMessagingWithChannelUrl:]
} allMessagingEndedBlock:^ {
    // Callback for [SendBird endAllMessaging:]
} readReceivedBlock:^(SendBirdReadStatus *status) {
    // When ReadStatus has been received
} messageDeliveryBlock:^(BOOL send, NSString *message, NSString *data, NSString *tempId{
   // To determine the message has been successfully sent.
} mutedMessagesReceivedBlock:^(SendBirdMessage *message) {
   // When soft-muted messages have been received
} mutedFileReceivedBlock:^(SendBirdFileLink *message) {
   // When soft-muted files have been received
}];

Rubymotion:

Here i get in trouble. I am able to create the messaging channel but I have no idea how to write that Objective-C event handler in Rubymotion. The online translator at http://objc2rubymotion.herokuapp.com/ fails due to the ^ and * syntax. Any help is appreciated.

SendBird.startMessagingWithUserId(id_of_target_user)

#Event Handler

EDIT:

A friend who knows more Rubymotion than I do pointed me in the right direction and so now I have the following event handler:

SendBird.startMessagingWithUserId(2)

SendBird.setEventHandlerConnectBlock(
    -> (channel) {
            # handle connect
    },
    messagingStartedBlock: -> (channel) {
      mp "channel created:" + channel.to_s
    })

However this fails with a NoMethodError:

2016-08-03 19:48:58.711 faces_ios_v1[75673:798798] chat_screen.rb:24:in `on_load': undefined method `setEventHandlerConnectBlock:messagingStartedBlock:' for SendBird:Class (NoMethodError)
    from screen_module.rb:39:in `view_did_load'
    from view_controller.rb:15:in `viewDidLoad'
2016-08-03 19:48:58.723 faces_ios_v1[75673:798798] *** Terminating app due to uncaught exception 'NoMethodError', reason: 'chat_screen.rb:24:in `on_load': undefined method `setEventHandlerConnectBlock:messagingStartedBlock:' for SendBird:Class (NoMethodError)
    from screen_module.rb:39:in `view_did_load'
    from view_controller.rb:15:in `viewDidLoad'

If I don't include messagingStartedBlock in the Event Handler I get the following error:

2016-08-03 19:35:20.120 faces_ios_v1[74958:793380] chat_screen.rb:14:in `on_load': undefined method `setEventHandlerConnectBlock' for SendBird:Class (NoMethodError)
    from screen_module.rb:39:in `view_did_load'
    from view_controller.rb:15:in `viewDidLoad'
2016-08-03 19:35:20.132 faces_ios_v1[74958:793380] *** Terminating app due to uncaught exception 'NoMethodError', reason: 'chat_screen.rb:14:in `on_load': undefined method `setEventHandlerConnectBlock' for SendBird:Class (NoMethodError)
    from screen_module.rb:39:in `view_did_load'
    from view_controller.rb:15:in `viewDidLoad'

This makes no sense, as setEventHandlerConnectBlock should clearly be a method of the SendBird class.

The relevant SendBird SDK documentation can be found here:

https://docs.sendbird.com/ios#messaging_channel


Solution

  • Okay this was solved after a lot of help from a friend.

    It turns out that the SendBird Event Handler method needs to be passed ALL event blocks or it will not work. So this will work:

      SendBird.startMessagingWithUserId(2)
    
        SendBird.setEventHandlerConnectBlock(
      -> (channel) { },
      errorBlock: -> (code) { },
      channelLeftBlock: -> (channel) { },
      messageReceivedBlock: -> (message) { },
      systemMessageReceivedBlock: -> (message) { },
      broadcastMessageReceivedBlock: -> (message) { },
      fileReceivedBlock: -> (file_link) { },
      messagingStartedBlock: -> (channel) {
        mp "Messaging started"
        mp channel
       },
      messagingUpdatedBlock: -> (channel) { },
      messagingEndedBlock: -> (channel) { },
      allMessagingEndedBlock: -> { },
      messagingHiddenBlock: -> (channel) { },
      allMessagingHiddenBlock: -> { },
      readReceivedBlock: -> (status) { },
      typeStartReceivedBlock: -> (status) { },
      typeEndReceivedBlock: -> (status) { },
      allDataReceivedBlock: -> (sendBirdDataType, count) { },
      messageDeliveryBlock: -> (send, message, data, temp_id) { },
      mutedMessagesReceivedBlock: -> (message) { },
      mutedFileReceivedBlock: -> (message) { }
    )
    

    and will output:

    "Messaging started"
    #<SendBirdMessagingChannel:0x10f9bcdc0>
    

    Once i get this integration working, I will upload a tutorial / github project.

    I will post back the link as a comment once it is done