iOS
Migration

Migration from v2

The iOS SDK 3.0 (v3) has been fully changed from the 2.0 and supports your chat solution on any mobile apps and websites. The structure has been improved and the performance has increased dramatically.

  • The OpenChannel and GroupChannel classes have been added for an open channel and a group channel related features respectively.
  • The UserMessage, FileMessage and AdminMessage have been added to handle various types of messages.
  • Event callbacks and new instances for various types of queries have been neatly arranged.

We strongly recommend that you move to v3 from the previous version with the following migration guides.


Installation

If you are using CocoaPods, just change the version of dependencies in Podfile at the app level (not the project level).

Light Color Skin
Copy
// v2 
target 'YOUR_TARGET' do
    pod 'SendBirdSDK', '~> 2.2'
end

// v3
target 'YOUR_TARGET' do
    pod 'SendBirdSDK', '~> 3.0'
end

Authentication

Initialization

You still need to initialize SendBird once when your app begins.

Light Color Skin
Copy
// v2
[SendBird initAppId:APP_ID];

// v3
[SBDMain initWithApplicationId:APP_ID];

Login

The login is no longer used in v3. Calling the connect just once after the init is finished is all you have to do.

Light Color Skin
Copy
// v2
[SendBird loginWithUserId:USER_ID andUserName:USER_NAME]; // When you allow guest login.
[SendBird loginWithUserId:USER_ID andUserName:USER_NAME andUserImageUrl:USER_IMAGE_URL andAccessToken:ACCESS_TOKEN]; // When you allow only permitted user login.

[SendBird setEventHandlerConnectBlock:^(SendBirdChannel *channel) {
    // Connect handler block.
} errorBlock:^(NSInteger code) {

}
...

}];

// v3
[SBDMain connectWithUserId:self.userIdTextField.text completionHandler:^(SBDUser * _Nullable user, SBDError * _Nullable error) { 
    // When you allow guest login.
}];

[SBDMain connectWithUserId:USER_ID accessToken:ACCESS_TOKEN completionHandler:^(SBDUser * _Nullable user, SBDError * _Nullable error) {
    // When you allow only permitted user login.
}];

If you want to update user information such as nickname, profile image or APNS push tokens, now you can use the updateCurrentUserInfoWithNickname:profileImage: ... : or registerDevicePushToken:completionHandler: methods after a connection is established.


Open channel (previously an open chat channel)

From v3, we've changed to call an open chat channel as an open channel. Members who have entered an open channel are referred to as participants of the channel. The SBDOpenChannel and SBDOpenChannelListQuery handle an open channel related features.

Retrieve a list of channels

Light Color Skin
Copy
// v2
self.channelListQuery = [SendBird queryChannelList];
[self.channelListQuery nextWithResultBlock:^(NSMutableArray *queryResult) {

}];

// v3
self.openChannelListQuery = [SBDOpenChannel createOpenChannelListQuery];
[self.openChannelListQuery loadNextPageWithCompletionHandler:^(NSArray<SBDOpenChannel *> * _Nullable channels, SBDError * _Nullable error) {

}];

Connect to a channel

You don't have to do anything to connect to each open channel in v3. All required connections are automatically made once you have called connect after init. Plus, entering an open channel is much simpler in v3. In v2, you needed to fetch channel URL and call join, queryMessageList and connect.

Light Color Skin
Copy
// v2
[SendBird joinChannel:CHANNEL_URL];
[[SendBird queryMessageListInChannel:CHANNEL_URL prevWithMessageTs:LLONG_MAX andLimit:LIMIT resultBlock:^(NSMutableArray *queryResult) {
    if (queryResult != nil) {
        // Connect to SendBird with max messages timestamp to receive new messages since last query.
        [SendBird connectWithMessageTs:MAX_MESSAGE_TIMESTAMP];
    } 
}];

// v3
[SBDOpenChannel getChannelWithUrl:CHANNEL_URL completionHandler:^(SBDOpenChannel * _Nullable channel, SBDError * _Nullable error) {
    [channel enterChannelWithCompletionHandler:^(SBDError * _Nullable error) {

    }];
}];

Disconnect from a channel

You don't have to do anything to disconnect an open channel in v3. All connections are automatically disconnected when you call disconnect on application termination. If you want a user to leave the open channel, just call exit.

Light Color Skin
Copy
// v2
SendBird.leave(CHANNEL_URL);
SendBird.disconnect();

// v3
[SBDOpenChannel getChannelWithUrl:CHANNEL_URL completionHandler:^(SBDOpenChannel * _Nullable channel, SBDError * _Nullable error) {
    [channel exitChannelWithCompletionHandler:^(SBDError * _Nullable error) {

    }];
}];

Send a message to a channel

The Mentioned message is NOT currently supported in v3.

Light Color Skin
Copy
// v2
[SendBird sendMessage:MESSAGE];
[SendBird sendMessage:MESSAGE withData:DATA];

[SendBird uploadFile:FILE type:TYPE hasSizeOfFile:SIZE withCustomField:CUSTOM_FIELD uploadBlock:^(SendBirdFileInfo *fileInfo, NSError *error) {
    [SendBird sendFile:fileInfo];
}];

// v3
[openChannel sendUserMessage:MESSAGE data:DATA completionHandler:^(SBDUserMessage * _Nullable userMessage, SBDError * _Nullable error) {
        
}];
[openChannel sendFileMessageWithBinaryData:FILE filename:FILE_NAME type:FILE_TYPE size:FILE_SIZE data:CUSTOM_DATA completionHandler:^(SBDFileMessage * _Nullable fileMessage, SBDError * _Nullable error) {
    
}];

Receive messages through an event delegate

The SBDChannelDelegate replaces blocks of [SendBird setEventHandler...]. Multiple delegates are allowed.

Light Color Skin
Copy
// v2
[SendBird setEventHandlerConnectBlock:^(SendBirdChannel *channel) {

} errorBlock:^(NSInteger code) {

} ...

}];

// v3
@interface ChattingViewController : UIViewController<SBDChannelDelegate>

@end

@implementation OpenChannelChattingViewController

- (void)initViewController {
    [SBDMain addChannelDelegate:self identifier:self.description];
}

- (void)dismissCurrentViewController {
    [SBDMain removeChannelDelegateForIdentifier:self.description];
}

- (void)channel:(SBDBaseChannel * _Nonnull)sender didReceiveMessage:(SBDBaseMessage * _Nonnull)message {

}

@end

Load previous messages in a channel

Light Color Skin
Copy
// v2
[[SendBird queryMessageListInChannel:CHANNEL_URL prevWithMessageTs:LLONG_MAX andLimit:LIMIT resultBlock:^(NSMutableArray *queryResult) {

}];

// v3
SBDMessageListQuery *query = [self.channel createMessageListQuery];
[query loadNextMessagesFromTimestamp:EARLIEST_MESSAGE_TIMESTAMP limit:LIMIT reverse:REVERSE_ORDER completionHandler:^(NSArray<SBDBaseMessage *> * _Nullable messages, SBDError * _Nullable error) {
    
}];

Retrieving a list of all participants of a channel

Participants means online users in a certain open channel. Once a user leaves the open channel, the user is no longer participant of that channel and query does not include him/her.

Light Color Skin
Copy
// v2
SendBirdMemberListQuery *query = [SendBird queryMemberListInChannel:CHANNEL_URL];
[query nextWithResultBlock:^(NSMutableArray *queryResult) {
        
} errorBlock:^(NSError *error) {
    
}];

// v3
self.query = [self.channel createParticipantListQuery];
[self.query loadNextPageWithCompletionHandler:^(NSArray<SBDUser *> * _Nullable users, SBDError * _Nullable error) {

}];

Group channel (previously a messaging channel)

From v3, we call a messaging channel as a group channel. Users having joined a group channel are referred to as members of the channel. The SBDGroupChannel and SBDGroupChannelListQuery classes handle the features related to group channels.

Create a channel

All startMessaging related methods are replaced by createChannel and createChannelWithUserIds.

Light Color Skin
Copy
// v2
[SendBird startMessagingWithUserIds:USER_IDS];

// v3
[SBDGroupChannel createChannelWithUserIds:USER_IDS isDistinct:YES/NO completionHandler:^(SBDGroupChannel * _Nullable channel, SBDError * _Nullable error) {

}];

Retrieving a list of channels

Light Color Skin
Copy
// v2
self.channelListQuery = [SendBird queryMessagingChannelList];
[self.channelListQuery nextWithResultBlock:^(NSMutableArray *queryResult) {

}];

// v3
self.groupChannelListQuery = [SBDGroupChannel createMyGroupChannelListQuery];
self.groupChannelListQuery.limit = LIMIT;
self.groupChannelListQuery.order = SBDGroupChannelListOrderChronological;
self.groupChannelListQuery.includeEmptyChannel = YES/OR;

[self.groupChannelListQuery loadNextPageWithCompletionHandler:^(NSArray<SBDGroupChannel *> * _Nullable channels, SBDError * _Nullable error) {

}];

Connect to a channel

You don't have to do anything to connect to each group channel in v3. All required connections are automatically made once you have called connect after init.

Light Color Skin
Copy
// v2
[[SendBird queryMessageListInChannel:CHANNEL_URL] loadWithMessageTs:LLONG_MAX prevLimit:PREV_LIMIT andNextLimit:NEXT_LIMIT resultBlock:^(NSMutableArray *queryResult) {
    [SendBird joinChannel:CHANNEL_URL];
    [SendBird connectWithMessageTs:MAX_MESSAGE_TIMESTAMP];
} endBlock:^(NSError *error) {

}];

// v3
// Do nothing.

Disconnect a channel

You don't have to do anything to disconnect a group channel in v3. All connections are automatically disconnected when you call disconnect on application termination.

Light Color Skin
Copy
// v2
[SendBird disconnect];

// v3
// Do nothing.

Invite users to a channel

Light Color Skin
Copy
// v2
[SendBird inviteMessagingWithChannelUrl:CHANNEL_URL andUserIds:USER_ID];

// v3
[self.groupChannel inviteUserId:USER_IDS completionHandler:^(SBDError * _Nullable error) {
    
}];

Remove a user from channel members

Light Color Skin
Copy
// v2
[SendBird endMessagingWithChannelUrl:CHANNEL_URL];

// v3
[channel leaveChannelWithCompletionHandler:^(SBDError * _Nullable error) {

}];

Send a message to a channel

The Mentioned message is NOT currently supported in v3.

Light Color Skin
Copy
// v2
[SendBird sendMessage:MESSAGE];
[SendBird sendMessage:MESSAGE withData:DATA];

[SendBird uploadFile:FILE type:TYPE hasSizeOfFile:SIZE withCustomField:CUSTOM_FIELD uploadBlock:^(SendBirdFileInfo *fileInfo, NSError *error) {
    [SendBird sendFile:fileInfo];
}];

// v3
[groupChannel sendUserMessage:MESSAGE data:DATA completionHandler:^(SBDUserMessage * _Nullable userMessage, SBDError * _Nullable error) {
        
}];
[groupChannel sendFileMessageWithBinaryData:FILE filename:FILE_NAME type:FILE_TYPE size:FILE_SIZE data:CUSTOM_DATA completionHandler:^(SBDFileMessage * _Nullable fileMessage, SBDError * _Nullable error) {
    
}];

Receive messages

The SBDChannelDelegate replaces blocks of [SendBird setEventHandler...]. Multiple delegates are allowed.

Light Color Skin
Copy
// v2
[SendBird setEventHandlerConnectBlock:^(SendBirdChannel *channel) {

} errorBlock:^(NSInteger code) {

} ...

}];

// v3
@interface ChattingViewController : UIViewController<SBDChannelDelegate>

@end

@implementation OpenChannelChattingViewController

- (void)initViewController {
    [SBDMain addChannelDelegate:self identifier:self.description];
}

- (void)dismissCurrentViewController {
    [SBDMain removeChannelDelegateForIdentifier:self.description];
}

- (void)channel:(SBDBaseChannel * _Nonnull)sender didReceiveMessage:(SBDBaseMessage * _Nonnull)message {

}

@end

Load previous messages

Light Color Skin
Copy
// v2
[[SendBird queryMessageListInChannel:CHANNEL_URL prevWithMessageTs:LLONG_MAX andLimit:LIMIT resultBlock:^(NSMutableArray *queryResult) {

}];

// v3
SBDMessageListQuery *query = [self.channel createMessageListQuery];
[query loadNextMessagesFromTimestamp:EARLIEST_MESSAGE_TIMESTAMP limit:LIMIT reverse:REVERSE_ORDER completionHandler:^(NSArray<SBDBaseMessage *> * _Nullable messages, SBDError * _Nullable error) {
    
}];

Monitoring multiple channels

The SBDChannelDelegate replaces blocks of [SendBird registerNotificationHandlerMessagingChannel...]. For details, please refer to Event Handler.

Light Color Skin
Copy
// v2
[SendBird registerNotificationHandlerMessagingChannelUpdatedBlock:^(SendBirdMessagingChannel *channel) {
    
} mentionUpdatedBlock:^(SendBirdMention *mention) {
    
}];

// v3
@interface ChattingViewController : UIViewController<SBDChannelDelegate>

@end

@implementation OpenChannelChattingViewController

- (void)initViewController {
    [SBDMain addChannelDelegate:self identifier:self.description];
}

- (void)dismissCurrentViewController {
    [SBDMain removeChannelDelegateForIdentifier:self.description];
}
@end

Retrieve a list of all members of a channel

Light Color Skin
Copy
// v2
[messagingChannel members];

// v3
[messagingChannel members];

Typing Indicators

Light Color Skin
Copy
// v2
[SendBird typeStart];
[SendBird typeEnd];

// v3
[groupChannel startTyping];
[groupChannel endTyping];

Retrieve the read receipts of members

From v3, various of methods to get read receipt are possible. You can get a timestamp for a certain member just like in v2 or the automatically calculated read receipt as well.

Light Color Skin
Copy
// v2
long timestamp = [messagingChannel getLastReadMillis:USER_ID];

// v3
long timestamp = [groupChannel getLastSeenAtByUserId:USER_ID];
int unreadCount = [channel getReadReceiptOfMessage:msg];

Broadcast the read status of a message

Light Color Skin
Copy
// v2
[SendBird markAsRead];

// v3
[groupChannel markAsRead];

Channel metadata

Metadata and metacounter can be created, updated and read in v3 by counter parts of methods in v2.

Light Color Skin
Copy
// v2
[SendBird queryChannelMetaDataWithChannelUrl:CHANNEL_URL] setMetaData:DATA_DICTIONARY resultBlock:^(NSDictionary *response) {
    
} endBlock:^(NSInteger code) {
    
}];
[SendBird queryChannelMetaDataWithChannelUrl:CHANNEL_URL] getMetaDataWithKeys:KEYS resultBlock:^(NSDictionary *response) {
    
} endBlock:^(NSInteger code) {
    
}];

// v3
[channel createMetaData:DATA_DICTIONARY completionHandler:^(NSDictionary<NSString *,NSString *> * _Nullable metaData, SBDError * _Nullable error) {

}];
[channel updateMetaData:DATA_DICTIONARY completionHandler:^(NSDictionary<NSString *,NSObject *> * _Nullable metaData, SBDError * _Nullable error) {
          
}];
[channel getMetaDataWithKeys:KEYS completionHandler:^(NSDictionary<NSString *,NSObject *> * _Nullable metaData, SBDError * _Nullable error) {
         
}];

Channel metacounter

Light Color Skin
Copy
// v2
[SendBird queryChannelMetaCounterWithChannelUrl:CHANNEL_URL] increaseMetaCounterWithKey:KEY andAmount:AMOUNT resultBlock:^(NSDictionary<NSString*,NSNumber*> *response) {
    
} endBlock:^(NSInteger code) {
    
}];
[SendBird queryChannelMetaCounterWithChannelUrl:CHANNEL_URL] getMetaCounterWithKeys:KEYS resultBlock:^(NSDictionary *response) {
    
} endBlock:^(NSInteger code) {
    
}];

// v3
[channel increaseMetaCounters:COUNTER_DICTIONARY completionHandler:^(NSDictionary<NSString *,NSNumber *> * _Nullable metaCounters, SBDError * _Nullable error) {

}];
[channel getMetaCountersWithKeys:KEYS completionHandler:^(NSDictionary<NSString *,NSNumber *> * _Nullable metaCounters, SBDError * _Nullable error) {
                                        
}];

Event handler

From v3, the SendBirdEventHandler, SendBirdSystemEventHandler and SendBirdNotificationHandler are replaced by the SBDChannelDelegate. Please refer to Event Handler for details.


Push notifications

From v3, you have to call registerDevicePushToken:completionHandler: method explicitly after connection is made to register push tokens. Please refer to Push Notifications for details.

Light Color Skin
Copy
// v2 (AppDelegate.m)
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
    // We recommend to run the below code when the notification setting of your app is a default value or the setting is true.
    [SendBird registerForRemoteNotifications:devToken];
}

// v3 (AppDelegate.m)
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
    // ...

    // Save devToken to your own global variable.
    [SBDMain registerDevicePushToken:tempPushToken completionHandler:^(SBDPushTokenRegistrationStatus status, SBDError * _Nullable error) {
        if (error == nil) {
            if (status == SBDPushTokenRegistrationStatusPending) {
                // Registration is pending.
                // If you get this status, invoke `+ registerDevicePushToken:completionHandler:` with `[SBDMain getPendingPushToken]` after connection.
            }
            else {
                // Registration succeeded.
            }
        }
        else {
            // Registration failed.
        }
    }];
}

// v3 (ViewController.m)
[SBDMain connectWithUserId:self.userIdTextField.text completionHandler:^(SBDUser * _Nullable user, SBDError * _Nullable error) {
    [SBDMain registerDevicePushToken:[SBDMain getPendingPushToken] completionHandler:^(SBDPushTokenRegistrationStatus status, SBDError * _Nullable error) {
        if (error == nil) {
            if (status == SBDPushTokenRegistrationStatusPending) {
                NSLog(@"Push registration is pending.");
            }
            else {
                NSLog(@"APNS Token is registered.");
            }
        }
        else {
            NSLog(@"APNS registration failed.");
        }
    }];
}];