MixdeskHelp Center
Skip to content

Developer Documentation

SDK for iOS

Last updated Jun 11, 2025

On this page

This guide assumes basic experience developing iOS apps and familiarity with the relevant concepts.

Read the full guide before starting integration.

Before development, download the official demo and use it as a reference.

Use the latest SDK version where possible.

  • Check Mixdesk on GitHub for the latest version.
  • Demo developer tools: view the current SDK version
  • Check #define MixdeskSDKVersion in MixdeskManager.h
  • pod search Mixdesk may return an older version because of the local CocoaPods cache

Step 1: Import the SDK

CocoaPods is recommended for these reasons:

  • SDK updates are easier.
  • Manual updates require removing the old library, downloading the new one, and reconfiguring the project. Leftover files can cause conflicts.
  • Swift projects support CocoaPods.

1.1 Import with CocoaPods

Add this to your Podfile:

pod 'Mixdesk', '~> 1.0.0'

Install the Mixdesk pod:

$ pod install

1.2 Import manually

1.2.1 Objective-C projects

In the downloaded MixdeskSDK-files folder, find MixdeskSDK.framework , MixdeskChatViewController , MixdeskSDKViewInterface , MixdeskNotification and copy these four folders into your project directory. Right-click in the project navigator and select Add Files to Your Project. Alternatively, drag them into the Xcode project navigator.

1.2.2 Swift projects

  • Import the SDK files as described above.
  • Add the required imports, including #import "MixdeskChatViewManager.h", to your bridging header. See: Add a bridging header.

1.2.3 Add dependencies

The SDK depends on system frameworks. Select your project, then TARGETS -> Build Phases -> Link Binary With Libraries and expand Link Binary With Libraries. Select + to add the following dependencies:

  • libsqlite3.tbd
  • libicucore.tbd
  • AVFoundation.framework
  • CoreTelephony.framework
  • SystemConfiguration.framework
  • MobileCoreServices.framework
  • QuickLook.framework

Step 2: Integrate the SDK

After importing the SDK, complete these five steps for a basic integration.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
#pragma mark  Integration step 1: Initialize,  Parameters:appkey  ,Initialize the AppKey as early as possible.
    [MXManager initWithAppkey:@"" completion:^(NSString *clientId, NSError *error) {
        if (!error) {
            // Enable SDK bulk messaging here, Call only after SDK initialization succeeds
            // [[MXNotificationManager sharedManager] openMXGroupNotificationServer];
            NSLog(@"Mixdesk SDK: Initialization succeeded");
        } else {
            NSLog(@"error:%@",error);
        }
    }];
  /*Your code*/
    return YES;
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
    #pragma mark  Integration step 2: Open the Mixdesk service in the foreground
    [MXManager openMixdeskService];
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
    #pragma mark  Integration step 3: Close the Mixdesk service in the background
    [MXManager closeMixdeskService];
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    #pragma mark  Integration step 4: Upload the deviceToken
    [MXManager registerDeviceToken:deviceToken];
}

#pragma mark  Integration step 5: Open the chat screen(button click handler)
- (void)pushToMixdeskVC:(UIButton *)button {
#pragma mark In general, For UI customization, see MXChatViewStyle.h and its methods.,For behavior customization, see MXChatViewManager.h and its methods.

#pragma mark  Basic integration: Use the default Mixdesk,   UI without customization.
    MXChatViewManager *chatViewManager = [[MXChatViewManager alloc] init];
    [chatViewManager setoutgoingDefaultAvatarImage:[UIImage imageNamed:@"mixdesk-icon"]];
    [chatViewManager pushMXChatViewControllerInViewController:self];
#pragma mark  Use the following method to customize the back button
//    MXChatViewManager *chatViewManager = [[MXChatViewManager alloc] init];
//    MXChatViewStyle *aStyle = [chatViewManager chatViewStyle];
//    [aStyle setNavBarTintColor:[UIColor redColor]];
//    [aStyle setNavBackButtonImage:[UIImage imageNamed:@"mixdesk-icon"]];
//    [chatViewManager pushMXChatViewControllerInViewController:self];
#pragma mark To use round avatars instead of square ones, ,set round avatars.
//    MXChatViewManager *chatViewManager = [[MXChatViewManager alloc] init];
//    MXChatViewStyle *aStyle = [chatViewManager chatViewStyle];
//    [aStyle setEnableRoundAvatar:YES];
//    [aStyle setEnableOutgoingAvatar:NO]; //Hide the user avatar
//    [aStyle setEnableIncomingAvatar:NO]; //Hide the team-member avatar
//    [chatViewManager pushMXChatViewControllerInViewController:self];
#pragma mark Customize the right navigation-bar button,Only do this when necessary; ,it is not recommended,because it removes Mixdesk functionality,This button displays human transfer when AI support is enabled in the workspace,Select to transfer to a human. 2During human support, it also allows ratings
//    MXChatViewManager *chatViewManager = [[MXChatViewManager alloc] init];
//    MXChatViewStyle *aStyle = [chatViewManager chatViewStyle];
//    UIButton *bt = [UIButton buttonWithType:UIButtonTypeCustom];
//    [bt setImage:[UIImage imageNamed:@"mixdesk-icon"] forState:UIControlStateNormal];
//    [aStyle setNavBarRightButton:bt];
//    [chatViewManager pushMXChatViewControllerInViewController:self];
#pragma mark Custom customer information
//    MXChatViewManager *chatViewManager = [[MXChatViewManager alloc] init];
////    [chatViewManager setClientInfo:@{@"name":@"123Test",@"gender":@"man11",@"age":@"100"} override:YES];
//    [chatViewManager setClientInfo:@{@"name":@"123Test",@"gender":@"man11",@"age":@"100"}];
//    [chatViewManager pushMXChatViewControllerInViewController:self];

#pragma mark Pre-send a message
//    MXChatViewManager *chatViewManager = [[MXChatViewManager alloc] init];
//    [chatViewManager setPreSendMessages: @[@"I have a question about order 1705045496811"]];
//    [chatViewManager pushMXChatViewControllerInViewController:self];

#pragma mark To connect your own user system, ,use custom customer information for user profile details
#pragma mark Ensure customId is unique,so each customId maps to exactly one Mixdesk user ID
//    MXChatViewManager *chatViewManager = [[MXChatViewManager alloc] init];
//    NSString *customId = @"Get your own user ID or another unique identifier";
//    if (customId){
//        [chatViewManager setLoginCustomizedId:customId];
//    }else{
//   #pragma mark The following line is incorrect, It would cause ID = "notadda" to be bound to several Mixdesk users,and expose one customer’s conversation to others
//        //[chatViewManager setLoginCustomizedId:@"notadda"];
//    }
//    [chatViewManager pushMXChatViewControllerInViewController:self];
}

Follow the integration pattern above and ensure identifiers are mapped correctly.

Step 3: Configure push notifications

When the app enters the background, Mixdesk sends messages to your backend. Your backend then pushes them to the app through a provider such as JPush. See SDK workflow .

To configure the server URL, sign in as a Mixdesk administrator at mixdesk and go to Settings > SDK.

iOS app configuration with push notification settings

Push-message data structure

When a message needs to be pushed, Mixdesk sends it to your configured server using method POST and data format JSON .

Request format:

request.header.authorization contains the signature.

request.body contains the message data with this structure:

KeyDescription
idMessage ID
messageIdCurrent conversation ID
contentMessage content
messageTimeSend time
fromNameSender name
deviceTokenRecipient deviceToken as a string
clientIdRecipient contact ID
customizedIdDeveloper-defined custom ID
contentTypeContent type: text/photo/audio
deviceOSDevice operating system
customizedDataCustom attributes uploaded by the developer
typeMessage type: mesage = regular message; ending = conversation-ended message

Verify the signature to validate the push data. Mixdesk provides signature-calculation examples in five languages: Java, Python, Ruby, JavaScript, PHP. See Mixdesk SDK 1.0 push-payload signature algorithm.

Basic integration is complete.

Step 4: SDK workflow

The diagram below shows the SDK workflow.

Mixdesk SDK initialization and message handling workflow diagram

Note

  • If you customize the open-source chat UI, fork the GitHub repository so you can merge upstream updates later.

Step 5: API reference

Initialize the SDK

All operations require successful SDK initialization and a usable clientId returned by Mixdesk.

Register your app in Mixdesk to obtain an AppKey. In the AppDelegate.m system callback didFinishLaunchingWithOptions, call the initialization API:

[MXManager initWithAppkey:@"AppKey for your registered app" completion:^(NSString *clientId, NSError *error) {
}];

If you do not know the AppKey, sign in as an administrator at mixdesk and open Settings > SDK, as shown below.

App settings with the SDK AppKey location highlighted

Add custom information

Example result:

Custom contact information displayed in the conversation sidebar

Upload user attributes to help team members support customers. Example:

//Create custom information
NSDictionary* clientCustomizedAttrs = @{
@"name"        : @"Kobe Bryant"
};

/**
 *  Set custom contact information
 *
 *  @param clientInfo Custom contact information
    @param override Force update. Unless set to YES, the values take effect only on the first call.
 */
[chatViewManager setClientInfo:clientCustomizedAttrs override:YES];
or
[MXManager setClientInfo:clientCustomizedAttrs completion:^(BOOL success) {
}];

Set the following predefined fields through the API above:

KeyDescription
nameReal name
telPhone
emailEmail
commentNotes

Note

  • After enabling custom response events, handle them through notification listeners. Otherwise, selecting a bulk message will do nothing.

Note

  • Set this option before bringing the user online.
Custom contact field definitions in Mixdesk

Show the chat view

Open the Mixdesk UI when the user needs support:

MXChatViewManager *chatViewManager = [[MXChatViewManager alloc] init];
[chatViewManager pushMXChatViewControllerInViewController:self];

MXServiceToViewInterface is the adapter between the open-source chat UI and the SDK. It separates Mixdesk-specific business logic so the UI can be reused in other projects. Implement the methods in MXServiceToViewInterface to connect your own business logic.

Synchronize server messages

With synchronization enabled, pull-to-refresh retrieves conversation history from the server.

With synchronization disabled, it retrieves history from the local database.

A contact may use multiple devices, so local history can contain fewer messages than server history.

MXChatViewManager *chatViewManager = [[MXChatViewManager alloc] init];
//Enable message synchronization
[chatViewManager enableSyncServerMessage:true];
[chatViewManager pushMXChatViewControllerInViewController:self];

Set the contact ID for sign-in

Set a Mixdesk contact ID to bring that contact online.

MXChatViewManager *chatViewManager = [[MXChatViewManager alloc] init];
[chatViewManager setLoginMXClientId:clientId];
[chatViewManager pushMXChatViewControllerInViewController:self];

Note: If the server cannot find the ID, it returns a contact does not exist error.

Use the following API to obtain clientId:[MXManager getCurrentClientId].

Device language does not switch to Chinese

Add Localizations to your app’s info.plist so the SDK can detect the language. To support English, Simplified Chinese, and Traditional Chinese, include this configuration:

<key>CFBundleLocalizations</key>
<array>
    <string>zh_CN</string>
    <string>zh_TW</string>
    <string>en</string>
</array>

For more chat UI options, see MXChatViewManager.h .

SDK API details

This section covers key APIs. In MixdeskSDK.framework > MXManager.h, all APIs include detailed comments.

Use Mixdesk APIs to build a custom chat interface. Before calling them, remember to initialize the SDK.

API description

Initialize the SDK

Initialize in AppDelegate.m system callback didFinishLaunchingWithOptions as early as possible. On the first initialization, the SDK requests a contact from the server. Other APIs require successful initialization.

//Add this in AppDelegate.minside didFinishLaunchingWithOptions
[MXManager initWithAppkey:@"AppKey for your registered app" completion:^(NSString *clientId, NSError *error) {
}];

Register the deviceToken

Mixdesk needs deviceToken to send offline messages to your backend. Your backend can use the token to deliver a notification through APNs.

In AppDelegate.m, use the system callback didRegisterForRemoteNotificationsWithDeviceToken to upload deviceToken:

[MXManager registerDeviceToken:deviceToken];

Disable Mixdesk push notifications

For details, see Push notifications.

Bring the current contact online

After initialization, a contact ID is available. Call this API to bring it online:

[MXManager setCurrentClientOnlineWithCompletion:^(MXClientOnlineResult result, MXAgent *agent, NSArray<MXMessage *> *messages) {
//Check result to determine whether the contact is online
} receiveMessageDelegate:self];

Bring a contact online using its Mixdesk contact ID

Use the Get Current Contact ID API and store the ID in your backend to link it with your user system.
Pass the saved ID to bring that contact online and make it the current contact.

[MXManager setClientOnlineWithClientId:clientId completion:^(MXClientOnlineResult result, MXAgent *agent, NSArray<MXMessage *> *messages) {
//Check result to determine whether the contact is online
} receiveMessageDelegate:self];

Bring a contact online using a custom ID

Alternatively, pass your own user ID. Mixdesk binds it to a contact, which subsequent calls with the same ID bring online.

The contact associated with that custom ID becomes the current contact.

Important:Do not use an auto-incrementing custom ID. Predictable IDs can enable impersonation; store the Mixdesk contact ID instead if necessary.

[MXManager setClientOnlineWithCustomizedId:customizedId completion:^(MXClientOnlineResult result, MXAgent *agent, NSArray<MXMessage *> *messages) {
//Check result to determine whether the contact is online
} receiveMessageDelegate:self];

Listen for contact-online notifications

After a contact comes online, use this notification to upload custom information or perform other actions. The notification is named MX_CLIENT_ONLINE_SUCCESS_NOTIFICATION and defined in MXDefinition.h .

Get Current Contact ID

Use this API to obtain and store the contact ID in your backend, linking it to your user account.

NSString *clientId = [MXManager getCurrentClientId];

Create a new contact

Call this API to initialize a new contact.

The new contact has no history or user information.

Store the ID and link it to your app user if needed.

[MXManager createClient:^(BOOL success, NSString *clientId) {
//Store this clientId
}];

Set the contact offline

NSString *clientId = [MXManager setClientOffline];

While the contact remains online, the configured delegate receives real-time messages and new-message notifications. Use them to display an unread badge.

When the contact is offline, messages are sent to your backend.

Recommendation: Leave the contact online after exiting the chat screen if you need to receive new-message notifications.

Listen for incoming messages

Register a notification listener to alert the contact about new messages. The notification name is MX_RECEIVED_NEW_MESSAGES_NOTIFICATION and defined in MXDefinition.h .

Read its userInfo to obtain an array of Mixdesk message MXMessage objects, for example:[notification.userInfo objectForKey:@"messages"]

Note: If you leave the contact online after exiting the chat screen, you continue to receive new-message notifications.

### . Listen for new-message notifications where appropriate
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveNewMXMessages:) name:MX_RECEIVED_NEW_MESSAGES_NOTIFICATION object:nil];

### Listen for incoming Mixdesk messages
- (void)didReceiveNewMXMessages:(NSNotification *)notification {
//Message array in the notification
NSArray *messages = [notification.userInfo objectForKey:@"messages"];
NSLog(@"Received a team-member message notification");
}

Get the assigned team member

Use this API to retrieve the team member currently supporting the contact:

MXAgent *agent = [MXManager getCurrentAgent];

Add custom information

For custom contact information, see Add custom information.

Get more messages from the server

Retrieve server-side history with this API:

[MXManager getServerHistoryMessagesWithUTCMsgDate:firstMessageDate messagesNumber:messageNumber success:^(NSArray<MXMessage *> *messagesArray) {
//Display the retrieved messages
} failure:^(NSError *error) {
//Handle errors
}];

Note: Server history includes messages for the contact across all platforms, including Web, Android, and iOS. Call this from the chat screen’s pull-to-refresh handler.

Get local conversation history

Because the Get more messages from the server API uses network data, you can instead retrieve history from the local iOS SDK database.

[MXManager getDatabaseHistoryMessagesWithMsgDate:firstMessageDate messagesNumber:messageNumber result:^(NSArray<MXMessage *> *messagesArray) {
//Display the retrieved messages
}];

Note: Local history may contain fewer messages because it is not synchronized with the server.

Receive real-time messages

The three contact-online APIs above include a parameter for the message delegate. Configure this delegate to receive messages.

After setting the delegate, implement MXManagerDelegate > didReceiveMXMessage: to receive messages in the callback.

Send messages

Call this API to send text messages:

[MXManager sendTextMessageWithContent:content completion:^(MXMessage *sendedMessage) {
//Handle successful message sending
}];

Call this API to send image messages:

[MXManager sendImageMessageWithImage:image completion:^(MXMessage *sendedMessage) {
//Handle successful message sending
}];

Call this API to send audio messages:

[MXManager sendAudioMessage:audioData completion:^(MXMessage *sendedMessage, NSError *error) {
//Handle successful message sending
}];

Call this API to send video messages:

[MXManager sendVideoMessage:filePath completion:^(MXMessage *sendedMessage, NSError *error) {
//Handle successful message sending
}];

Note. The callback returns a message object. Inspect its status to determine whether sending succeeded.

Get unread messages

This API merges unread messages from local storage and the server. Use it to display the unread count. Entering the chat screen clears unread messages.
[MXManager getUnreadMessagesWithCompletion:completion]

Get unread messages for a custom ID

Retrieve all unread messages associated with a custom ID.
[MXManager getUnreadMessagesWithCustomizedId:customizedId completion:completion]

Record and play audio

Recording and playback each support three modes:

  • Pause other audio
  • Play alongside other audio
  • Lower the volume of other audio

Choose a mode by configuring these two properties in MXChatViewManager.h :

@property (nonatomic, assign) MXPlayMode playMode;

@property (nonatomic, assign) MXRecordMode recordMode;

If the host app plays audio, such as background music in a game, set @property (nonatomic, assign) BOOL keepAudioSessionActive; to YES so the AudioSession is not closed after recording or playback.

In games, use the play-and-record audio category; otherwise, audio may fail to play after recording.

Pre-send a message

In MXChatViewManager.h, set @property (nonatomic, strong) NSArray *preSendMessages; to automatically send text or an image when the customer opens the chat window.

Observe chat-screen appearance and dismissal

  • MX_NOTIFICATION_CHAT_BEGINSent when the chat screen appears
  • MX_NOTIFICATION_CHAT_ENDSent when the chat screen disappears

User queue

Listen for:
When a team member accepts the user, an MX_NOTIFICATION_QUEUEING_END notification is sent.

Step 6: Embed Mixdesk in another SDK

If your project is itself an SDK, complete normal integration and the following additional steps.

Import Mixdesk, add dependencies, initialize it, and use its APIs as with an app integration.

If you use the provided chat UI, also expose its resource bundle:

Select your project, then TARGETS -> Build Phases -> Copy Files and expand Copy Files. Select + to add the Mixdesk resource bundle MXChatViewAsset.bundle.

When publishing your SDK, package MXChatViewAsset.bundle with it.

Step 7: Terminology

Your push-message server

Mixdesk sends SDK offline messages as webhooks to the URL you provide.

The server receiving these messages is Your push-message server.

Mixdesk contact ID

After a contact comes online or a conversation is assigned, the SDK has a unique ID.

Save this ID to bring the same contact online on another device and synchronize their information and history.

Developer-defined custom ID

An ID from your own system, such as user_id.

After a successful online request, your ID is bound to a Mixdesk contact ID. Use it on another device to synchronize previous data.

Note: If your ID is predictable, such as an auto-incrementing number, store the Mixdesk contact ID and use it for online requests instead.

Step 8: Troubleshooting

Update the SDK

1. CocoaPods integration

Update the Mixdesk version in your Podfile, change to the project directory in a terminal, and run pod update mixdesk to update the SDK.

2. Manual integration

1. Use Show in Finder to remove the four Mixdesk folders from the project.

MixdeskSDK.framework , MXChatViewController MXChatViewInterface and MXMessageForm

2. Clean the project in Xcode.

3. Download the latest demo from GitHub and locate
MixdeskSDK.framework , MXChatViewController MXChatViewInterface and MXMessageForm. Copy the folders into the previous SDK location in your project using Show in Finder.

4. Use Add Files to to add the four copied folders back to the project.

Green bar and unusable composer on iOS 11

Update the SDK to a version with iOS 11 support.
Before a major iOS update, ask technical support whether an SDK update is required.

SDK initialization fails

1. Missing NSExceptionDomains

Without NSExceptionDomains, the SDK returns MXErrorCodePlistConfigurationError and logs:Mixdesk SDK Error: Add NSExceptionDomains to your app’s info.plist. See https://github.com/Mixdesk/MixdeskSDK-iOS#info.plist%E8%AE%BE%E7%BD%AEIf this occurs, configure NSExceptionDomains

Note. If the error remains, check that you did not add the setting to the test target’s info.plist instead.

2. Network problems

If configuration is correct, check the device’s network connection.

Navigation bar is missing

The open-source UI uses the system UINavgationController. Possible causes include:

  • When presenting with Push mode, the supplied viewController may not be based on UINavigationController.
  • When presenting with Push mode, the UINavgationBar may be hidden or transparent.
  • The app may use Category to modify UINavgationBar in a way that prevents display.

For the first two cases, you can also use present presentation mode instead of changing the navigation setup.

Xcode Warning: was built for newer iOS version (7.0) than being linked (6.0)

This warning can occur if the app’s minimum supported version is below iOS 7.0.

ld: warning: object file (/Mixdesk-SDK-Demo/MXChatViewController/Vendors/MLAudioRecorder/amr_en_de/lib/libopencore-amrnb.a(wrapper.o)) was built for newer iOS version (7.0) than being linked (6.0)

The SDK’s open-source library opencore-amr was rebuilt for Bitcode support. This does not prevent iOS 6 use. If you do not need Bitcode, replace opencore-amr with an older version:Download

The static library is large

The static library contains armv7, arm64, i386, and x86_64 architectures plus Bitcode. The source guide estimates an increase of about 100 KB in the compiled host app.

Gap between the keyboard and composer

Check whether you use the third-party library IQKeyboardManager, which can conflict with the composer layout logic.

Solution (thanks to RandyTechnology for identifying the cause and solution):

  • In MXChatViewController.viewWillAppear, add [[IQKeyboardManager sharedManager] setEnable:NO]; to disable IQKeyboardManager on this screen.
  • In MXChatViewController.viewWillDisappear, add [[IQKeyboardManager sharedManager] setEnable:YES]; to re-enable IQKeyboardManager before leaving.

Incorrect inputBar height with TabBarController

TabBarController layouts vary and may use custom tab bars, so adjust your app or SDK code as needed. On iOS 7 and later, changing the tab bar’s hidden and translucent property often resolves the issue.

Listen for messages outside the chat screen

See Listen for incoming-message notifications.

Third-party library conflicts

If your app uses a library also included in the chat UI, duplicate class names may cause conflicts. Remove the duplicate code from Chat UI > Vendors.

Note: Some bundled libraries contain Mixdesk customizations. Removing them can remove those effects. See GitHub: Mixdesk open-source chat UI.

Incorrect app name in contact information

If the App field in contact visit information shows the bundle name or “SDK cannot get app name”, check that CFBundleDisplayName is set in the app’s info.plist.

Undefined symbols during compilation

Check that App Target > Build Settings > Search Paths > Framework Search Paths or Library Search Paths includes the Mixdesk project.

Xcode 14 changes

  • Bitcode removal
  • iOS SDK v3.8.5–v3.9.0 supports arm64 only on physical devices

Vendors: Third-party libraries

The SDK uses the following open-source libraries. Remove duplicate copies if your project uses the same ones.

Third-party libraryTag versionDescription
VoiceConvertN/AConverts AMR and WAV audio. The original source is not identified in the source documentation.
MLAudioRecordermasterTranscodes while recording, plays remote audio with local caching, and supports real-time audio.Note: Because the project’s lame.framework does not support bitCode, the MP3-related files were removed.
GrowingTextView1.1A text view that adjusts height with its content, used for the message composer.
TTTAttributedLabelA label with multiple display effects, used for chat-bubble text.
CustomIOSAlertViewCustomA custom AlertView used for conversation ratings.Note: Mixdesk modified this library to add button separators, detect an existing AlertView, and adjust frames when the keyboard appears. See the modified version at CustomIOSAlertView;
AGEmojiKeyboard0.2.0A customized emoji keyboard. See the project source for its layout.

Related articles

Still need help?

Contact support@mixdesk.com for help with your setup.