Tutorial Embed SDK Livechat Barantum di IOS

Panduan menambahkan fitur Livechat pada aplikasi SwiftUI dan UIKit

Diperbarui pada 08 September 2026

Panduan ini menjelaskan cara menambahkan Livechat Barantum sebagai fitur layanan pelanggan di aplikasi iOS: memasang SDK, membuat konfigurasi, menampilkan layar chat dari tombol Buka Chat, serta menangani event percakapan.

SDK iOS memuat halaman chat melalui WKWebView. URL halaman widget adalah https://livechat.barantum.com/widget/. File widget.js dan posisi bubble kiri/kanan digunakan pada website; pada iOS, aplikasi menentukan layar atau panel tempat chat ditampilkan.



1. Siapkan SDK dan inbox

  • Gunakan Mac dengan Xcode 15 atau lebih baru. SDK mendukung iOS 13+; kode SwiftUI dalam tutorial ini menggunakan API iOS 15+, sehingga target aplikasi yang mengikuti kode tersebut perlu iOS 15 atau lebih baru.
  • Terima file ZIP SDK iOS dari tim Barantum, lalu ekstrak seluruh isinya. Temukan folder paket SDK yang berisi Package.swift dan Sources/BarantumWidget; pertahankan struktur folder hasil ekstraksi. Gunakan versi SDK yang menyediakan BarantumConversationStatus dan conversationStatusDidChange.
  • Ambil Inbox Identifier dari integrasi Live Chat Barantum. Jika belum memiliki inbox, ikuti tab “Integrasi Livechat” pada dokumen ini terlebih dahulu.
  • Pastikan perangkat atau Simulator terhubung ke internet. Untuk verifikasi identitas user login, siapkan Identifier Hash dari backend Anda.


Pada project aplikasi Anda, buka File → Add Package Dependencies → Add Local. Pilih folder paket SDK hasil ekstraksi yang langsung berisi Package.swift, lalu tambahkan produk BarantumWidget ke target aplikasi. Nama folder mengikuti paket ZIP yang Anda terima; jika terdapat folder pembungkus, buka hingga menemukan Package.swift.

import BarantumWidget

Simpan folder SDK hasil ekstraksi di lokasi tetap, misalnya di dalam folder project aplikasi, lalu pastikan produk BarantumWidget terhubung ke target pada Frameworks, Libraries, and Embedded Content. Jangan menghapus folder tersebut setelah menambahkannya karena Xcode menggunakan paket lokal itu saat build. Jika lokasinya berubah, perbarui referensi paket melalui Xcode.


2. Siapkan struktur integrasi pada aplikasi

Buka project aplikasi iOS Anda di Xcode. Livechat dapat dibuka dari halaman layanan pelanggan, pusat bantuan, atau halaman lain yang sesuai dengan alur aplikasi. Pengaturan koneksi disimpan dalam kode dan tidak perlu ditampilkan kepada pengguna.

  1. Tambahkan produk BarantumWidget ke target aplikasi seperti pada langkah 1.
  2. Pilih alur SwiftUI pada langkah 4 atau UIKit pada langkah 5 sesuai antarmuka aplikasi Anda. Kedua alur menggunakan konfigurasi pada langkah 3.
  3. Buat LivechatConfiguration.swift untuk URL layanan, Inbox Identifier, identitas pengunjung, dan tampilan chat.
  4. Untuk SwiftUI, buat ChatScreen.swift menggunakan kode lengkap pada langkah 4. Tambahkan tombol Buka Chat pada halaman aplikasi yang akan menjadi pintu masuk layanan pelanggan.
  5. Chat tampil satu layar penuh. Indikator Menghubungkan… hilang setelah callback ready diterima. Tekan Tutup untuk kembali ke halaman aplikasi sebelumnya.

Gunakan Inbox Identifier milik integrasi Anda. Nilai INBOX_IDENTIFIER_ANDA pada kode harus diganti sebelum menjalankan aplikasi. Untuk pengguna yang login, ambil identitas dan Identifier Hash dari backend sebagaimana dijelaskan pada langkah 7.

Setelah file dan pemanggilan layar selesai ditambahkan, pilih scheme aplikasi serta Simulator atau perangkat tujuan, lalu tekan Run. Untuk perangkat fisik, tentukan Team pada Signing & Capabilities dan gunakan Bundle Identifier aplikasi Anda.


3. Atur koneksi dan tampilan

Pusatkan konfigurasi di LivechatConfiguration.swift agar dapat digunakan oleh layar SwiftUI maupun UIKit. Buat konfigurasi sebelum membuka chat dan isi identitas dari pengguna yang sedang aktif. Jika nilai ditulis langsung di kode, build dan jalankan ulang aplikasi setelah mengubahnya.


Konfigurasi minimal di aplikasi Anda

Buat helper LivechatConfiguration.swift berikut. Ganti INBOX_IDENTIFIER_ANDA dengan identifier dari integrasi Anda sebelum menjalankan Live Chat.

import BarantumWidget


enum LivechatConfiguration {

    static func make() -> BarantumWidgetConfig {

        let config = BarantumWidgetConfig(

            livechatBaseURL: "https://livechat.barantum.com",

            inboxIdentifier: "INBOX_IDENTIFIER_ANDA"

        )

        config.locale = "id"

        config.title = "Layanan Pelanggan"

        config.subtitle = "Kami siap membantu Anda"

        config.color = "#2563eb"

        return config

    }

}

Konfigurasi Live Chat tidak memerlukan publishableKey. widgetURL memiliki default halaman /widget/. Jika diubah, gunakan URL halaman widget HTTPS, bukan URL widget.js. Pastikan Inbox Identifier terisi dan URL koneksi valid sebelum memanggil load(config).


Opsi pengunjung dan tampilan

// Tambahkan sebelum return config pada helper di atas.

config.visitorName = "Budi"

config.visitorEmail = "budi@example.com"

config.visitorPhone = "+628123456789"

config.visitorExternalId = "user-123"

config.preChat = true

// Opsional: gunakan URL gambar logo HTTPS milik Anda.

// config.logoURL = "https://domain-anda.example/logo.png"

  • locale menerima id atau en. color memakai format CSS; title, subtitle, dan logoURL mengatur header widget.
  • Properti tampilan opsional yang tidak diisi mengikuti nilai panel atau default SDK. Nilai yang Anda isi menjadi konfigurasi eksplisit.
  • preChat = true mengaktifkan form pra-chat. Form dapat dilewati jika visitorExternalId, nama, atau email sudah tersedia.
  • Pada SDK saat ini, preChat = false tidak dikirim sebagai false ke halaman. Karena itu, konfigurasi tersebut masih dapat mengikuti pengaturan pra-chat dari panel.
  • Konfigurasi native saat ini belum mengekspos appId, visitor.attributes, pathPrefix, atau pengaturan pra-chat per kolom. Hindari menambahkan properti tersebut ke potongan Swift ini.


4. Tampilkan chat di aplikasi SwiftUI

Buat file ChatScreen.swift pada target aplikasi, lalu masukkan kode berikut. Komponen ini membungkus BarantumWidgetView dengan UIViewRepresentable, menangani event melalui Coordinator, serta menyediakan indikator koneksi dan tombol Tutup.

import SwiftUI

import BarantumWidget


struct ChatScreen: View {

    let config: BarantumWidgetConfig

    var onUnreadChanged: (Int) -> Void = { _ in }

    var onConversationStatusChanged: (BarantumConversationStatus) -> Void = { _ in }

    @Environment(\.dismiss) private var dismiss

    @State private var isConnecting = true

    @State private var errorMessage = ""

    @State private var showingError = false


    var body: some View {

        NavigationView {

            VStack(spacing: 0) {

                if isConnecting {

                    HStack(spacing: 10) {

                        ProgressView()

                        Text("Menghubungkan…")

                            .font(.subheadline).foregroundColor(.secondary)

                    }

                    .frame(maxWidth: .infinity)

                    .padding(12)

                }


                WidgetView(config: config,

                           onReady: { isConnecting = false },

                           onClose: { dismiss() },

                           onUnread: onUnreadChanged,

                           onStatus: onConversationStatusChanged,

                           onError: {

                               isConnecting = false

                               errorMessage = $0

                               showingError = true

                           })

            }

            .navigationTitle("Live Chat")

            .navigationBarTitleDisplayMode(.inline)

            .toolbar {

                ToolbarItem(placement: .navigationBarTrailing) {

                    Button("Tutup") { dismiss() }

                }

            }

            .alert("Live Chat", isPresented: $showingError) {

                Button("OK", role: .cancel) {}

            } message: { Text(errorMessage) }

        }

        .navigationViewStyle(.stack)

    }

}


private struct WidgetView: UIViewRepresentable {

    let config: BarantumWidgetConfig

    let onReady: () -> Void

    let onClose: () -> Void

    let onUnread: (Int) -> Void

    let onStatus: (BarantumConversationStatus) -> Void

    let onError: (String) -> Void


    func makeCoordinator() -> Coordinator { Coordinator(self) }


    func makeUIView(context: Context) -> BarantumWidgetView {

        let widget = BarantumWidgetView(frame: .zero)

        widget.delegate = context.coordinator

        widget.load(config)

        return widget

    }


    func updateUIView(_ widget: BarantumWidgetView, context: Context) {

        // Perubahan badge/status tidak memuat ulang sesi chat.

        context.coordinator.callbacks = self

    }


    static func dismantleUIView(_ widget: BarantumWidgetView, coordinator: Coordinator) {

        widget.delegate = nil

    }


    final class Coordinator: NSObject, BarantumWidgetDelegate {

        var callbacks: WidgetView

        init(_ callbacks: WidgetView) { self.callbacks = callbacks }


        func barantumWidgetDidBecomeReady(_ widget: BarantumWidgetView) { callbacks.onReady() }

        func barantumWidgetDidRequestClose(_ widget: BarantumWidgetView) { callbacks.onClose() }

        func barantumWidget(_ widget: BarantumWidgetView, unreadDidChange count: Int) { callbacks.onUnread(count) }

        func barantumWidget(_ widget: BarantumWidgetView, conversationStatusDidChange status: BarantumConversationStatus) {

            callbacks.onStatus(status)

        }

        func barantumWidget(_ widget: BarantumWidgetView, didFailWithMessage message: String) { callbacks.onError(message) }

    }

}


Setelah ChatScreen.swift dibuat, tambahkan tombol berikut pada ContentView.swift atau halaman aplikasi Anda. Gunakan LivechatConfiguration dari langkah 3; tombol akan menampilkan chat satu layar penuh.

import SwiftUI

import BarantumWidget


struct ContentView: View {

    @State private var showChat = false

    @State private var config = LivechatConfiguration.make()


    var body: some View {

        Button("Buka Chat") {

            // Buat konfigurasi terbaru sebelum membuka layar chat.

            config = LivechatConfiguration.make()

            showChat = true

        }

        .fullScreenCover(isPresented: $showChat) {

            ChatScreen(config: config)

        }

    }

}

ChatScreen membuat BarantumWidgetView, memasang delegate ke Coordinator, kemudian memanggil load(config) satu kali di makeUIView. updateUIView hanya memperbarui callback. Pertahankan pola ini agar perubahan badge atau status SwiftUI tidak memuat ulang percakapan. Saat layar dilepas, dismantleUIView mengosongkan delegate.

ChatScreen menampilkan indikator Menghubungkan… sampai sesi siap, percakapan, dan tombol Tutup. Status percakapan dan angka unread tidak ditampilkan sebagai panel teknis. Untuk kebutuhan badge atau status pada aplikasi Anda, isi closure opsional onUnreadChanged dan onConversationStatusChanged saat membuat ChatScreen; keduanya meneruskan nilai callback SDK dan secara default tidak melakukan tindakan. Error yang diteruskan melalui delegate ditampilkan sebagai alert.


5. Alternatif integrasi dengan UIKit

Untuk aplikasi UIKit, buat LiveChatViewController.swift berikut. Contoh ini memakai helper konfigurasi yang sama, memasang widget ke safe area, dan dapat ditampilkan secara modal atau melalui navigation controller.

import UIKit

import BarantumWidget


final class LiveChatViewController: UIViewController {

    private let widget = BarantumWidgetView(frame: .zero)


    override func viewDidLoad() {

        super.viewDidLoad()

        view.backgroundColor = .systemBackground

        widget.delegate = self

        widget.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(widget)

        let safe = view.safeAreaLayoutGuide

        NSLayoutConstraint.activate([

            widget.topAnchor.constraint(equalTo: safe.topAnchor),

            widget.bottomAnchor.constraint(equalTo: safe.bottomAnchor),

            widget.leadingAnchor.constraint(equalTo: safe.leadingAnchor),

            widget.trailingAnchor.constraint(equalTo: safe.trailingAnchor)

        ])

        widget.load(LivechatConfiguration.make())

    }

}


extension LiveChatViewController: BarantumWidgetDelegate {

    func barantumWidgetDidBecomeReady(

        _ widget: BarantumWidgetView

    ) {

        title = "Live Chat"

    }


    func barantumWidgetDidRequestClose(

        _ widget: BarantumWidgetView

    ) {

        if let nav = navigationController,

           nav.viewControllers.first !== self {

            nav.popViewController(animated: true)

        } else {

            dismiss(animated: true)

        }

    }


    func barantumWidget(

        _ widget: BarantumWidgetView,

        unreadDidChange count: Int

    ) {

        // Perbarui badge aplikasi sesuai nilai callback.

        print("Unread:", count)

    }


    func barantumWidget(

        _ widget: BarantumWidgetView,

        conversationStatusDidChange status: BarantumConversationStatus

    ) {

        print("Status:", status.wireValue)

    }


    func barantumWidget(

        _ widget: BarantumWidgetView,

        didFailWithMessage message: String

    ) {

        let alert = UIAlertController(

            title: "Live Chat",

            message: message,

            preferredStyle: .alert

        )

        alert.addAction(UIAlertAction(title: "OK", style: .default))

        present(alert, animated: true)

    }

}

Dari UIViewController pemanggil, tampilkan layar chat saat pengguna menekan tombol bantuan:

let chat = LiveChatViewController()

chat.modalPresentationStyle = .fullScreen

present(chat, animated: true)

Delegate bersifat weak dan callback opsional. Simpan objek delegate selama widget digunakan; UIViewController atau Coordinator pada contoh memenuhi kebutuhan ini. iOS membersihkan script handler saat view dilepas. API Android registerFileChooser() dan release() tidak dipanggil pada SDK iOS.


6. Pahami event dan status percakapan

  • barantumWidgetDidBecomeReady: sesi chat berhasil tersambung, bukan sekadar halaman selesai dimuat.
  • barantumWidgetDidRequestClose: pengguna meminta menutup widget; aplikasi host menutup layar.
  • unreadDidChange: meneruskan nilai unread dari widget untuk tampilan badge.
  • conversationStatusDidChange: memberi status percakapan aktif melalui BarantumConversationStatus.
  • didFailWithMessage: memberi pesan error dari halaman widget. Untuk kegagalan memuat halaman awal, periksa juga koneksi dan log Xcode.

Status pending berarti pesan customer menunggu balasan agent; progress berarti agent sudah membalas dan percakapan belum selesai; done berarti percakapan ditutup agent. Callback status berjalan di main thread, mendukung Swift/Objective-C, dan mengabaikan status asing. Menutup layar aplikasi tidak sama dengan menutup ticket; penyelesaian ticket dilakukan agent.


7. Hubungkan identitas user login

Gunakan ID user yang stabil dari sistem Anda sebagai visitorExternalId. Backend menghasilkan HMAC-SHA256 atas string ID tersebut menggunakan secret inbox, kemudian mengembalikan hash hex lowercase ke aplikasi. Isi pasangan external ID dan hash yang sesuai sebelum load(config).

// userId dan identifierHash berasal dari backend login Anda.

config.visitorExternalId = userId

config.livechatIdentifierHash = identifierHash

Secret HMAC hanya disimpan di backend; jangan menanamkannya dalam source aplikasi. Jika pengguna atau inbox berubah, ambil hash baru yang cocok dengan visitorExternalId dan inbox aktif. Untuk pengguna anonim tanpa HMAC, jangan isi visitorExternalId dan livechatIdentifierHash apabila pengaturan inbox mengizinkannya.

Untuk logout atau pergantian akun, tutup layar chat lalu buat konfigurasi baru dari akun aktif sebelum membuka kembali. Mengganti konfigurasi tidak berarti menghapus seluruh riwayat sesi yang disimpan halaman widget. Uji perpindahan akun agar riwayat yang ditampilkan sesuai user.


8. Lampiran foto dan dokumen

Tombol lampiran pada widget memakai picker bawaan WKWebView. Tidak ada langkah registerFileChooser seperti Android. Pastikan widget tampil di layar sebelum pengguna membuka picker.

Tambahkan deskripsi izin berikut pada Info.plist target aplikasi untuk fitur yang digunakan. Sesuaikan kalimatnya dengan tujuan akses kamera, mikrofon, dan foto:

<key>NSCameraUsageDescription</key>

<string>Ambil foto untuk lampiran chat.</string>

<key>NSMicrophoneUsageDescription</key>

<string>Rekam suara pada video lampiran chat.</string>

<key>NSPhotoLibraryUsageDescription</key>

<string>Pilih foto untuk lampiran chat.</string>

Izin kamera digunakan ketika mengambil foto/video; izin mikrofon terkait perekaman suara video. Menyalin key Info.plist tidak otomatis memberikan izin pengguna. Uji foto, dokumen, pembatalan, pilih ulang, dan penolakan izin pada perangkat fisik. Widget membatasi ukuran file hingga 10 MB (10 × 1024 × 1024 byte); server juga harus menerima ukuran tersebut beserta tambahan body multipart. Photos dan Files menggunakan fungsi upload dan endpoint lampiran yang sama. Lihat penanganan HTTP 413 pada bagian Troubleshooting.


9. Verifikasi integrasi

  1. Jalankan aplikasi dan tekan tombol Buka Chat yang telah Anda tambahkan. Pastikan layar chat tampil penuh dan indikator Menghubungkan… hilang setelah callback ready.
  2. Kirim pesan percobaan dengan akun uji Anda; pastikan pesan masuk ke inbox yang benar.
  3. Balas dari dashboard agent. Pastikan balasan muncul di aplikasi dan, bila dipasang, closure onConversationStatusChanged menerima progress.
  4. Tutup percakapan dari sisi agent; pantau closure onConversationStatusChanged atau delegate untuk memastikan status done diterima.
  5. Coba Komplain Baru dan kirim pesan pertama. Tombol Komplain Baru menyiapkan draft; room baru dibuat ketika pesan/lampiran pertama dikirim.
  6. Uji lampiran foto dan dokumen dengan beberapa ukuran, rotasi layar, tombol Tutup untuk kembali ke halaman sebelumnya, buka ulang chat, serta pergantian akun.
  7. Jika aplikasi Anda menambahkan badge melalui onUnreadChanged, uji perilakunya ketika layar dibuka dan disembunyikan. SDK native belum mengirim sinyal visibilitas view seperti loader web; penanda baca awal mengandalkan interaksi pengguna.

Lakukan verifikasi pada inbox pengujian milik Anda dan ulangi pengujian lampiran di perangkat fisik. Keberhasilan build saja belum membuktikan pesan dan lampiran telah diterima. Periksa hasil percakapan di aplikasi serta dashboard agent.


10. Troubleshooting

No such module BarantumWidget

Pastikan file ZIP SDK sudah diekstrak seluruhnya dan paket lokal ditambahkan dari folder yang langsung berisi Package.swift. Periksa bahwa produk BarantumWidget terhubung ke target aplikasi serta target membership file Swift sudah benar. Jika folder SDK dipindahkan atau dihapus, pulihkan foldernya lalu perbarui referensi paket di Xcode.


Widget kosong atau terus Menghubungkan

Periksa koneksi internet, log Xcode, URL HTTPS, dan ukuran view. Widget URL harus menunjuk halaman /widget/, bukan widget.js. Pastikan load(config) dipanggil setelah delegate terpasang dan widget mendapat layout yang terlihat.


Inbox salah atau identitas gagal diverifikasi

Periksa Inbox Identifier tanpa spasi tambahan. Untuk HMAC, input ID harus sama persis dengan visitorExternalId dan secret harus berasal dari inbox yang sesuai. Jangan menggunakan kembali hash yang dibuat untuk ID atau inbox lain.


Pra-chat tetap muncul atau justru dilewati

Nilai config.preChat = false dapat mengikuti konfigurasi panel karena SDK menghilangkan nilai false dari JSON. Sebaliknya, visitorExternalId, visitorName, atau visitorEmail yang terisi dapat membuat form pra-chat dilewati. Uji dengan identitas kosong bila ingin memeriksa pra-chat.


Upload failed saat memilih foto atau dokumen

Periksa respons HTTP request upload pada log jaringan. HTTP 413 (Request Entity Too Large) berarti ukuran request melampaui batas yang diterapkan server atau proxy. File dapat lolos batas widget 10 MB tetapi tetap ditolak apabila batas server lebih kecil. Pesan Upload failed saja belum cukup untuk menentukan penyebab kegagalan.

Foto dan dokumen dikirim melalui jalur multipart attachments[] yang sama, sehingga keduanya dapat terkena batas ukuran server. Selaraskan batas request pada proxy/server dan backend dengan batas file widget, serta sisakan ruang untuk multipart. Bila memakai Nginx, minta pengelola server memeriksa client_max_body_size pada konfigurasi yang melayani endpoint upload.

Widget saat ini menampilkan Upload failed untuk kegagalan upload dan tidak meneruskan detail kegagalan tersebut melalui delegate error native. Gunakan respons jaringan untuk diagnosis. Setelah batas server disesuaikan, uji Photos dan Files dengan file kecil, mendekati 10 MB, dan melebihi 10 MB; pastikan file yang diizinkan masuk ke percakapan dan file yang terlalu besar ditolak.


Callback status tidak tersedia atau widget memuat ulang

Gunakan SDK yang sudah memiliki BarantumConversationStatus dan delegate conversationStatusDidChange. Pada SwiftUI, jangan panggil load(config) dari updateUIView untuk setiap perubahan state. Ikuti pemisahan makeUIView/updateUIView pada ChatScreen.swift.


11. Susunan file integrasi

  • LivechatConfiguration.swift — membentuk BarantumWidgetConfig dengan koneksi, identitas, dan tampilan yang digunakan aplikasi.
  • ChatScreen.swift — layar SwiftUI, pembungkus UIViewRepresentable, serta Coordinator untuk event SDK.
  • ContentView.swift atau halaman aplikasi Anda — menempatkan tombol Buka Chat dan menampilkan ChatScreen melalui fullScreenCover.
  • LiveChatViewController.swift — alternatif layar chat untuk aplikasi yang menggunakan UIKit.
  • Info.plist target aplikasi — deskripsi izin sesuai fitur lampiran yang digunakan.

Apakah konten di atas membantu?

Bantu kami meningkatkan kualitas dari guidebook kami dengan mengisi form

Isi Form Saran

© 2026 Barantum. All rights reserved.