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 as below.

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

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


Step 2: Update bridging header file

Import Freshchat in your bridging header file.

#import "FreshchatSDK.h"


Note: 

Header file is updated from Freshchat.h to FreshchatSDK.h for naming consistency from version v1.3.0.


Step 3: Initialize and configure Freshchat for your App

1. Initialize Freshchat by pasting the following snippet in your didFinishLaunchingWithOptions: method.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        let freschatConfig:FreshchatConfig = FreshchatConfig.init(appID: "AppId", andAppKey: "AppKey")
        Freshchat.sharedInstance().initWith(freschatConfig)
        return true
}


2. In your AppDelegate file, include the snippet below in applicationDidBecomActive.

func applicationDidBecomeActive(_ application: UIApplication) {
        var freahchatUnreadCount = Int()
        Freshchat.sharedInstance().unreadCount { (unreadCount) in
            freahchatUnreadCount = unreadCount
        }
        UIApplication.shared.applicationIconBadgeNumber = freahchatUnreadCount;
}


3. Set config options as needed

You can turn-on/turn-off features like picture messaging at initialization. Use the below snippet before calling the initWithConfig: method to configure Freshchat features as desired. 

freschatConfig.gallerySelectionEnabled = true; // set NO to disable picture selection for messaging via gallery
        freschatConfig.cameraCaptureEnabled = true; // set NO to disable picture selection for messaging via camera
        freschatConfig.teamMemberInfoVisible = true; // set to NO to turn off showing an team member avatar. To customize the avatar shown, use the theme file
        freschatConfig.showNotificationBanner = true; // 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


4. To enable Freshchat to send push notifications to the application, add the following implementation of didRegisterForRemoteNotificationsWithDeviceToken in your AppDelegate file to capture the device token and send it to Freshchat servers.

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Freshchat.sharedInstance().setPushRegistrationToken(deviceToken)
}


5. Handing Push notifications

Note:

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.swift, insert the following method:

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
        if Freshchat.sharedInstance().isFreshchatNotification(userInfo) {
            Freshchat.sharedInstance().handleRemoteNotification(userInfo, andAppstate: application.applicationState)
        }
}


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

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter,
        willPresent: UNNotification,
        withCompletionHandler: @escaping (UNNotificationPresentationOptions)->()) {
if Freshchat.sharedInstance().isFreshchatNotification(willPresent.request.content.userInfo) {
   Freshchat.sharedInstance().handleRemoteNotification(willPresent.request.content.userInfo, andAppstate: UIApplication.shared.applicationState)  //Handled for freshchat notifications
} else {
    withCompletionHandler([.alert, .sound, .badge]) //For other notifications    
     }
}


@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter,
                          didReceive: UNNotificationResponse,
                          withCompletionHandler: @escaping ()->()) {
if Freshchat.sharedInstance().isFreshchatNotification(didReceive.notification.request.content.userInfo) {
  Freshchat.sharedInstance().handleRemoteNotification(didReceive.notification.request.content.userInfo, andAppstate: UIApplication.shared.applicationState) //Handled for freshchat notifications
} else {
       withCompletionHandler() //For other notifications
    }
}


Step 4: Entry points in the UI


Conversation

To bring up Freshchat’s Conversations list or a single conversation overlay at any point, use showConversations() method.


For example, if you are bringing up feedback overlay on a button press, the target method in a ViewController class could look like,

func presentConversation(sender: Any) {
        Freshchat.sharedInstance().showConversations(self)
}


Filter Conversations

Different sets of channels can be displayed to different segments of users by using tags to filter channels. This can be configured and passed on to the ConversationsOptions() method.

let options = ConversationOptions.init()
let tags: [String] = ["all","paidUser"]  //Your filter tags
options.filter(byTags: tags, withTitle: "Filter_View_Title")
Freshchat.sharedInstance().showConversations(self, with: options)


FAQs

To bring up the Freshchat’s FAQ overlay at any point, use showFAQs() method.


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

func presentFAQ(sender: Any) {
        Freshchat.sharedInstance().showFAQs(self)
}


Customizing FAQ Options

There are options to customize the FAQ Flow exposed via the FaqOptions class. This can be configured and passed on to the FAQOptions() method.


Filtering FAQs based on article tags can be done as follows,

let options = FAQOptions.init()
let tags: [String] = ["article_tag"]
options.filter(byTags: tags, withTitle:"Filter_screen_title", andType :ARTICLE)
Freshchat.sharedInstance().showFAQs(self, with: options)


Filtering FAQs based on Category tags can be done as follows,

let options = FAQOptions.init()
let tags: [String] = ["category_tag"]
options.filter(byTags: tags, withTitle:"Filter_screen_title", andType :CATEGORY)
Freshchat.sharedInstance().showFAQs(self, with: options)


More with FAQ Options

You can display FAQs in a grid or list format, add ContactUs on app bar, add ContactUs at the bottom using FAQOptions. ContactUs view can also be filtered via tags.

let options = FAQOptions.init()
options.showFaqCategoriesAsGrid = true; // Set false to show faq in list view
options.showContactUsOnAppBar = true; // Set false to hide contact us from app bar
options.showContactUsOnFaqScreens = true; // Set false to hide contact us bottom banner view
options.filterContactUs(byTags: ["feedback1"], withTitle: "Filtered_contactus_title")


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 camera or photo library.


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 follows:

let tag = "premium"
let message = "Your message here"
let freshchatMessage = FreshchatMessage.init(message: message, andTag: tag)
Freshchat.sharedInstance().send(freshchatMessage)


Note

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


Restore User and Chat Messages

For retaining the 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 identifyUser 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 conversations across sessions on the same device or across different devices and platforms. 


Note

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


To set external id

Freshchat.sharedInstance().identifyUser(withExternalID: "externalId", restoreID: nil)


To lookup and restore user by external id and restore id

Freshchat.sharedInstance().identifyUser(withExternalID: "externalId", restoreID: "restoreId")


To retrieve the restore id:

FreshchatUser.sharedInstance().restoreID


To listen to restore id generated event:

// Register for local notification
NotificationCenter.default.addObserver(self,selector: #selector(userRestoreIdReceived),name: NSNotification.Name(rawValue: FRESHCHAT_USER_RESTORE_ID_GENERATED),object: nil)

func userRestoreIdReceived() 
{
   print("Your restore id is - "+FreshchatUser.sharedInstance().restoreID)
   print("Your query external id is - "+FreshchatUser.sharedInstance().externalID)
}


//Unregister local notification
NotificationCenter.default.removeObserver(FRESHCHAT_USER_RESTORE_ID_GENERATED)


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().resetUser(completion: { () in
            //Completion code
})


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.


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 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 and add your app bundleId and then select development or production environment depending on whether you are using it for dev or production push services.


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


Note

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


Do More With Freshchat

// Create a user object
        let 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 & Segmentation - 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")
        
        /*
         Managing Badge number for unread messages - Manual
         */
        
        Freshchat.sharedInstance().unreadCount { (count:Int) -> Void in
            print("Unread count (Async) :\(count)")
        }


Customization

UI Customization Options

Modify the default theme file FCTheme.plist to customize the interface or you could link your own custom theme file to the SDK by using the following snippet:

freschatConfig.themeName = "<Theme Name>"


String Customizations 

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. You can rename the file.     


The structure of the bundle folder would be as follows: 

    YouCustomBundle.bundle      

            -en.Iproj            

                - FCLocalizable.strings      

            -fr.Iproj           

                 - FCLocalizable.strings      

            -de.Iproj            

                - FCLocalizable.strings

Changing Strings 

  1. In order to change a specific string used in the SDK UI, 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 above 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" flag 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 try use to try out our SDK APIs, which can be accessed from this link
.