Obtaining App ID and App Key

Your account is associated with a secret ID and key, which is used to integrate with Freshchat.


To get app id and app key,

  1. Go to Settings.

  2. Click Mobile SDK.



Integrating Freshchat with iOS App

Freshchat SDK contains a slice for arm64 architecture and supports only iOS 8.0 and above. Follow the below steps to integrate Freshchat with your iOS app.


Step 1: Add Freshchat to your project
Add Freshchat to your project in a single step by updating your podfile to include Freshchat.

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'

target 'Your project target' do
        use_frameworks!
        pod 'FreshchatSDK'
end


Step 2: Initialise and configure Freshchat for your App


1. Import "FreshchatSDK.h" in your AppDelegate.m file

Note:  
Header file has been updated from Freshchat.h to FreshchatSDK.h for naming consistency (from version v1.3.0).

2. Initialize Freshchat by pasting the following snippet in your -[AppDelegate application:didFinishLaunchingWithOptions:] method.

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

/* Initialize Freshchat*/

FreshchatConfig *config = [[FreshchatConfig alloc]initWithAppID:@"<App ID>"  andAppKey:@"<App Key>"];

[[Freshchat sharedInstance] initWithConfig:config];

/* Enable remote notifications */

if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")){
UIUserNotificationSettings *settings =
[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];

}
else{

[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];

}

[self.window makeKeyAndVisible]; // or similar code to set a visible view

/*  Set your view before the following snippet executes */

/* Handle remote notifications */
if ([[Freshchat sharedInstance]isFreshchatNotification:launchOptions]) {
[[Freshchat sharedInstance]handleRemoteNotification:launchOptions
andAppstate:application.applicationState];
}

/* Any other code to be executed on app launch */

/* Reset badge app count if so desired */
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];

return YES;
}


3. Set config options, as needed.
You can turn-on/turn-off features like voice messaging at initialisation. Use the snippet before calling the initWithConfig: method to configure Freshchat features as desired.

config.gallerySelectionEnabled = YES; // set NO to disable picture selection for messaging via gallery
config.cameraCaptureEnabled = YES; // set NO to disable picture selection for messaging via camera
config.teamMemberInfoVisible = YES; // set to NO to turn off showing team member avatar. To customize the avatar shown, use the theme file
config.showNotificationBanner = YES; // set to NO if you don't want to show the in-app notification banner upon receiving a new message while the app is open 


Note:
Check Step 5 to make sure it is compatible with iOS 10.

4. In your AppDelegate file, include the following snippet  in [AppDelegate applicationDidBecomActive:]]

- (void)applicationDidBecomeActive:(UIApplication *)application{
/* Reset badge app count if so desired */
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
}


5. To enable Freshchat to send push notifications to the application, add this implementation of application:didRegisterForRemoteNotificationsWithDeviceToken: in your AppDelegate file that captures the device token and sends it to Freshchat servers.

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
[[Freshchat sharedInstance] setPushRegistrationToken:devToken];
}


Step 3: Handling Push notifications 


Note:      
-[Freshchat isFreshchatNotification:] returns a BOOL. If remote notification was not sent by Freshchat, it returns NO and you can insert code to handle other notifications based on this check.

In your AppDelegate.m, insert the following method.

- (void) application:(UIApplication *)app didReceiveRemoteNotification:(NSDictionary *)info{
    if ([[Freshchat sharedInstance]isFreshchatNotification:info]) {
        [[Freshchat sharedInstance]handleRemoteNotification:info andAppstate:app.applicationState];
    }
}


If you are using UserNotifications.framework for handling notifications, make sure you are handling Freshchat notifications in willPresent &  didReceive methods as follows:

/* For devices running on ios 10 and above */
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
       willPresentNotification:(UNNotification *)notification
         withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
    if ([[Freshchat sharedInstance]isFreshchatNotification:notification.request.content.userInfo]) {
        [[Freshchat sharedInstance]handleRemoteNotification:notification.request.content.userInfo andAppstate:[[UIApplication sharedApplication] applicationState]];
    } else {
        completionHandler( UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge );
    }
}


/* For devices running on ios 10 and above */
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void (^)(void))completionHandler {
    if ([[Freshchat sharedInstance]isFreshchatNotification:response.notification.request.content.userInfo]) {
        [[Freshchat sharedInstance]handleRemoteNotification:response.notification.request.content.userInfo andAppstate:[[UIApplication sharedApplication] applicationState]];
    } else {
        completionHandler();
    }
}


Step 4: Entry points in the UI
Import "FreshchatSDK/Freshchat.h" into the class from which you want to invoke the Freshchat SDK’s Conversation interface or FAQ interface.

FAQs   
To display Freshchat’s FAQ overlay at any point, use -[[Freshchat sharedInstance] showFAQs:] method.    


For example, to display the feedback overlay on a button press, the target method in a ViewController class could look like,

- (IBAction)showFeedbackOverlay:(id)sender {
[[Freshchat sharedInstance] showFAQs:self];
}


Customising FAQ Options
Customisations to the FAQ Flow can be achieved by specifying the relevant options in the FaqOptions instance passed to the showFAQs() API.   

- (IBAction)showFeedbackOverlay:(id)sender {
    FAQOptions *options = [FAQOptions new];
    options.showFaqCategoriesAsGrid = YES; // Set NO to show faq in list view
    options.showContactUsOnAppBar = YES; // Set NO to hide contact us from app bar
    options.showContactUsOnFaqScreens = YES; // Set NO to hide contact us bottom banner view
    [[Freshchat sharedInstance]showFAQs:self withOptions:options];
}


Filtering FAQs
You can filter and show only FAQs tagged with a specific term. The tags can be setup from the dashboard.  

For example, to display FAQs related to payment failure, the particular FAQs can be tagged as "payment" and "billing". They can then be filtered and displayed to the users.


Sample Code:

FAQOptions *options = [FAQOptions new];
[options filterByTags:@[ @"payment", @"billing" ] withTitle:@"Filtered_View_title" andType: ARTICLE];
[[Freshchat sharedInstance]showFAQs:self withOptions:options];


You can also filter categories by tags. This will show a filtered view of categories ( under which articles would be listed). This is useful to show different sets of categories to different customers ( e.g. Paid Customers Vs Free Customers ).

FAQOptions *options = [FAQOptions new];
[options filterByTags:@[ @"payment", @"billing" ] withTitle:@"Filtered_View_title" andType: CATEGORY];
[[Freshchat sharedInstance]showFAQs:self withOptions:options];


Note:

When you filter an article by tags, the category(under which the article falls) tags are also applicable.


Conversations 
To bring up the Freshchat’s Conversations List or single conversation overlay at any point, you need to use -[[Freshchat sharedInstance] showConversations:] method.

For example, to bring up the feedback overlay on a button press, the target method in a ViewController class could look like,

- (IBAction)showFeedbackOverlay:(id)sender {
    [[Freshchat sharedInstance] showConversations:self];
} 


Filtering Channels  
Different sets of channels can be displayed to different segments of users by filtering Channels by tags.

ConversationOptions *options = [ConversationOptions new];
[options filterByTags:@[ @"all", @"paiduser" ] withTitle:@"Support"];
[[Freshchat sharedInstance] showConversations:self withOptions: options];


The contactUsTags  can also be used to show a different set of channels when the user comes from the self help section.

Send Message on Behalf of User
The app can send a message on behalf of the user using the sendMessage: API. This API would silently send a message and not launch the Freshchat SDK UI.

For example, to send a message on a channel tagged "premium", the API can be invoked as below:

NSString *tag = @"premium";
NSString *message = @"Your message here";
FreshchatMessage *userMessage = [[FreshchatMessage alloc] initWithMessage:message andTag:tag];
[[Freshchat sharedInstance] sendMessage:userMessage];


Note:
If there are no matching channels, message will be sent to the default channel. In case of multiple matches it will be added to oldest the channel.

Restore User and Chat Messages
For retaining chat messages across devices/sessions/platforms, the mobile app needs to pass the same external id and restore id combination for the user. This will allow users to seamlessly pick up the conversation from any of the supported platforms - Android, iOS and Web.

  • External Id - This should (ideally) be an unique identifier for the user from your system like a user id or email id etc and is set using the identifyUserWithExternalID: API

Note

This cannot be changed once set for the user

  • Restore Id - This is generated by Freshchat for the current user, given an external id was set and can be retrieved anytime using the [FreshchatUser sharedInstance].restoreID API.
    Note:
    Restore Id should be stored at your backend and you can implement logic to retrieve them to restore conversations back.


The app stores the combination of external id and restore id in the Freshchat SDK to continue the conversation across sessions on the same device or across different devices and platforms.

Note:
Notifications are supported in only one mobile device at any point in time. At present it is the last restored device or device with last updated push token.

To set external id:

[[Freshchat sharedInstance] identifyUserWithExternalID:@”externalId” restoreID:nil];


To lookup and restore user by external id and restore id:

[[Freshchat sharedInstance] identifyUserWithExternalID:@”externalId” restoreID:@”restoreId”];


To retrieve the restore id:

[FreshchatUser sharedInstance].restoreID;


To listen to restore id generated event:

// Register for local notification
[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(userRestoreIdReceived:)
                                                 name:FRESHCHAT_USER_RESTORE_ID_GENERATED
                                               object:nil];

- (void) userRestoreIdReceived:(NSNotification *) notification{
    NSLog(@"Your restore id is - %@",[FreshchatUser sharedInstance].restoreID);
    NSLog(@"Your query external id is - %@",[FreshchatUser sharedInstance].externalID);
}


//Unregister
[[NSNotificationCenter defaultCenter] removeObserver:self name:FRESHCHAT_USER_RESTORE_ID_GENERATED object:nil];


Reset User Data
Reset user data at logout or when deemed appropriate based on user action in the app by invoking the resetUser API.

[[Freshchat sharedInstance] resetUserWithCompletion:^{
        //Completion block code here
}];


Right-to-Left Language Support
Freshchat SDK supports RTL languages (Arabic). Set value ‘NSTextAlignmentNatural’ for UserMessageTextStyle/TeamMemberMessageTextStyle  textAlignment to support conversation messages for RTL languages.


Run-time locale change 

If your app supports runtime locale change please add local notification name FRESHCHAT_USER_LOCALE_CHANGED  event into your locale change  method.

[[NSNotificationCenter defaultCenter] postNotificationName:FRESHCHAT_USER_LOCALE_CHANGED object:self];



Step 5: iOS 10 Compatibility
Starting with iOS 10, Apple requires developers to declare access to privacy-sensitive controls ahead of time.

To comply with this new privacy requirement, developers must add the required keys to the Info.plist,
"NSPhotoLibraryUsageDescription" and "NSCameraUsageDescription"

Moreover, we will also log a warning message on the XCode console if you have missed adding the required keys.  

Warning!
Failing this iOS 10 will exit the app by crashing when user tries to access the controls of microphone, camera or photo library.
For more clarification, click here.  

iOS 10 Simulator issue  
Freshchat SDK depends on keychain services. Xcode 8.0 (8A218a) /  iOS 10 simulators have an issue with keychain services, which does not allow the SDK to retrieve data from the store when there are no "entitlements" set up. We expect this issue will be fixed in the later version of Xcode. In the meantime, we suggest the following workaround to continue testing on the iOS 10 simulators.

In the project’s capabilities page, please turn on push notifications capability (and select the "fix issue" if any issue appears). This is a work around to ensure there is a valid entitlement file for the project (which the simulator requires to work correctly), and once testing is done you can discard these changes. Hopefully the issue will be resolved in the next Xcode update.

Step 6: Uploading your App’s SSL Push Certificate

  1. Go to the Mac OS finder application, and search for "Keychain Access". Open it.  
  2. Find your App’s push certificate in the Certificates section. It will start with the string "Apple Development iOS Push Services" ("Apple Production iOS push services" in case of production certificate).
  3. Expand the row, and you will find the private key.
  4. Select both the private key and certificate and export it as .p12 file and necessarily set a password
  5. Upload the saved .p12 file in the field below selecting development environment or production environment depending on whether you are using it for dev or production push services


Upload your development/production certificate at this link: https://web.freshchat.com/settings/apisdk

Note:
Use a separate Freshchat account exclusively for Production or Development purposes. Do not use the same account for different environments - Apple fails push message batches when it gets device tokens that are invalid for that environment. Create a new account if you need an additional environment.

Do More with Freshchat

/* 
* Following three methods are to identify a user.
* These user properties will be viewable on the Freshchat web dashboard.
* The externalID (identifier) set will also be used to identify the specific user for any APIs 
* targeting a user or list of users in pro-active messaging or marketing
*/

// Create a user object
FreshchatUser *user = [FreshchatUser sharedInstance];

// To set an identifiable first name for the user
user.firstName = @"John";

// To set an identifiable last name for the user
user.lastName = @"Doe";

//To set user's email id
user.email = @"john.doe.1982@mail.com";

//To set user's phone number
user.phoneCountryCode=@"91";
user.phoneNumber = @"9790987495";

// FINALLY, REMEMBER TO SEND THE USER INFORMATION SET TO FRESHCHAT SERVERS

[[Freshchat sharedInstance] setUser:user];

/* Custom properties  - You can add any number of custom properties. An example is given below.
These properties give context for your conversation with the user and also serve as segmentation criteria for your marketing messages */

//You can set custom user properties for a particular user
[[Freshchat sharedInstance] setUserPropertyforKey:@"customerType" withValue:@"Premium"];
//You can set user demographic information
[[Freshchat sharedInstance] setUserPropertyforKey:@"city" withValue:@"San Bruno"];
//You can segment based on where the user is in their journey of using your app
[[Freshchat sharedInstance] setUserPropertyforKey:@"loggedIn" withValue:@"true"];
//You can capture a state of the user that includes what the user has done in your app
[[Freshchat sharedInstance] setUserPropertyforKey:@"transactionCount" withValue:@"3"];

/* If you want to indicate to the user that he has unread messages in his inbox, you can retrieve the unread count to display. */
//returns an int indicating the of number of unread messages for the user
[[Freshchat sharedInstance]unreadCountWithCompletion:^(NSInteger count) {
        NSLog(@"your unread count : %d", (int)count);
}]; 

/* Managing Badge number for unread messages - Manual
If you want to listen to a local notification and take care of updating the badge number yourself, listen for a notification with name "FRESHCHAT_UNREAD_MESSAGE_COUNT_CHANGED " as below
*/

[[NSNotificationCenter defaultCenter]addObserverForName:FRESHCHAT_UNREAD_MESSAGE_COUNT_CHANGED object:nil queue:nil usingBlock:^(NSNotification *note) {
       [[Freshchat sharedInstance]unreadCountWithCompletion:^(NSInteger count) {
            NSLog(@"your unread count : %d", (int)count);
       }]; 
}];



Note : 

From SDK v1.5.0, unread count event name changed from FRESHCHAT_UNREAD_MESSAGE_COUNT to FRESHCHAT_UNREAD_MESSAGE_COUNT_CHANGED. 


Customisation


UI Customization options
Modify our default theme file FCTheme.plist to customise the interface or you could link your own custom theme file to the SDK by using the following snippet.

 [config setThemeName:@"<Theme name>"];


String Customisations  
All strings used in the Freshchat SDK UI can be customized and localized in multiple languages.  


You can do the following to customize your SDK:


Creating a Bundle  
Locate the FCLocalization.bundle in the FreshchatSDK pod or  Download the FCLocalization.bundle from here. You can rename the file to a custom name.      

The structure of the bundle folder would be as follows:  

Sample bundle structure containing strings for English, French and German.

YouCustomBundle.bundle
      -en.Iproj
            - FCLocalizable.strings
      -fr.Iproj
            - FCLocalizable.strings
      -de.Iproj
            - FCLocalizable.strings</span></span>


Changing Strings  

  1. In order to change a specific string used in the SDK UI, just update the appropriate key in FCLocalizable.strings. The keynames in the file are categorized by UI and the keys used are self explanatory.  
  2. Do the same for all the languages you wish to support.
  3. SDK comes with only English at the moment, but you will be able to use translations for any language you want.   


Linking to Project

  1. Once you have changed all the required strings in the languages that you are supporting, link it under “Build Phases”  > “Copy Bundle Resources”
  2. When you are initializing the SDK,  specify that bundle name as part of freshchat config.
    config.stringsBundle = @"MyCustomBundle";  

Note:

  1. Bundle name is case-sensitive
  2. extension .bundle is not required  


Testing
Once you have made the changes, please run the app to verify the changes on the SDK UI.    

If you are using SDK by drag & drop, please set "-all_load", "-objC" flags in Project Settings, General -> Build Settings -> Other Linker flags.


Checklist for Launch

  1. Ensure you have the latest SDK.
  2. Ensure you are initializing the SDK at the starting of application: didFinishLaunchingWithOptions: function.
  3. Check if push notification is working properly when the app is in foreground, background and in killed state with production certificate.
  4. See our Theming and Customization document here to make sure you are matching the experience with the rest of your app.
  5. Configure your default channel name and welcome message right even if you aren't using other channels.
  6. Capture the unique user identifier, email, phone number, or any other unique customer identifiers with the SDK to ensure smooth use of APIs, as well as for best use of our "Smart Plugs" feature on the dashboard.
  7. Ensure the push notifications are working for new installs as well as upgrades from your previous versions.  


We have hosted a sample project which you could use to try out our SDK APIs. It can be accessed at the following link:

https://github.com/freshdesk/freshchat-ios/tree/master/Sample