Pular para o conteúdo principal
DocumentaçãoiOS
Versão 0.2.0iOS 15.1 ou posterior

Integrar o SDK iOS DobroDesk

Adicione o Swift Package assinado, crie o cliente nativo e apresente o widget partilhado a partir de um view controller.

Nesta página

A sua app iOS apresenta o widget nativo DobroDesk com estado durável por conta e preferências de movimento do sistema.

Adicionar o Swift Package publicado

No Xcode, adicione o repositório https://github.com/comstud-io/dobrodesk-mobile-sdk.git na release 0.2.0 e adicione DobroDeskSDK e DobroDeskUI ao target da app. O pacote binário suporta iOS 15.1 e posteriores. A release contém apenas artefactos. O código fonte da implementação nativa não está incluído.

Swift Package
https://github.com/comstud-io/dobrodesk-mobile-sdk.git

Inicializar e apresentar o cliente nativo

A app deve fornecer um JWT de identidade do cliente de curta duração através de credentialProvider. A autenticação nativa exige um utilizador assinado: use um backend do host e nunca coloque o signing secret ou um support API token na app.

Com a concorrência estrita do Swift 6, declare o loader do host como uma closure @Sendable () async throws -> String e passe essa closure a credentialProvider.

Apresentação Swift
import Foundation
import UIKit
import DobroDeskSDK
import DobroDeskUI

let loadDobroDeskToken: @Sendable () async throws -> String = {
  // Replace this placeholder with a request to your host backend.
  "short-lived-token-from-host-backend"
}

let client = try DobroDeskClient(
  configuration: DobroDeskConfiguration(
    apiOrigin: URL(string: "https://dobrodesk.com")!,
    integrationId: "wgt_0123456789abcdef0123456789abcdef",
    accountScope: currentCustomer.id,
    locale: "en",
    credentialProvider: loadDobroDeskToken,
    pollInterval: 1
  )
)

try await DobroDeskWidgetBridgePresenter.shared.present(
  client: client,
  options: ["locale": "en"],
  from: viewController
)

Usar um acionador personalizado ou uma superfície integrada

Para uma superfície integrada, use um UIView próprio com constraints para safeArea top, leading e trailing e uma ligação inferior à keyboardLayoutGuide. Defina uma altura inicial de 560 pontos com priority .defaultHigh e monte apenas depois de a view estar ligada à window. Crie um presenter próprio em cada montagem para que um close falhado ou antigo não feche outra superfície.

O botão personalizado deve ser acessível pelo teclado e expor aria-controls e aria-expanded. O wrapper do host deve capturar os erros de embed com do/catch e encaminhá-los para o seu próprio callback onError tipado para apresentar a recuperação. Ao montar novamente, reutilize o mesmo cliente, a mesma sessão e o mesmo rascunho.

As APIs inline fazem parte dos artefactos publicados do Mobile SDK 0.2.0. Use a superfície inline quando o host controla o posicionamento e a apresentação modal quando o host precisa de gerir o ecrã inteiro.

Integração integrada
import UIKit
import DobroDeskSDK
import DobroDeskUI

@MainActor
final class SupportPanelHost {
  private let client: DobroDeskClient
  private weak var parent: UIViewController?
  private let onError: (Error) -> Void
  private let supportContainer = UIView()
  private var presenter: DobroDeskWidgetBridgePresenter?
  private var mountTask: Task<Void, Never>?
  private var mountGeneration = 0
  private var isMounted = false

  init(
    client: DobroDeskClient,
    parent: UIViewController,
    onError: @escaping (Error) -> Void
  ) {
    self.client = client
    self.parent = parent
    self.onError = onError
    supportContainer.translatesAutoresizingMaskIntoConstraints = false
    parent.view.addSubview(supportContainer)
    let safeArea = parent.view.safeAreaLayoutGuide
    let keyboardGuide = parent.view.keyboardLayoutGuide
    let height = supportContainer.heightAnchor.constraint(equalToConstant: 560)
    height.priority = .defaultHigh
    NSLayoutConstraint.activate([
      supportContainer.topAnchor.constraint(equalTo: safeArea.topAnchor),
      supportContainer.leadingAnchor.constraint(equalTo: safeArea.leadingAnchor),
      supportContainer.trailingAnchor.constraint(equalTo: safeArea.trailingAnchor),
      supportContainer.bottomAnchor.constraint(equalTo: keyboardGuide.topAnchor),
      height,
    ])
  }

  func mountAfterAppearance() {
    guard mountTask == nil, !isMounted, let parent, supportContainer.window != nil else { return }
    mountGeneration += 1
    let generation = mountGeneration
    let mountPresenter = DobroDeskWidgetBridgePresenter()
    let client = self.client
    let supportContainer = self.supportContainer
    presenter = mountPresenter
    mountTask = Task { @MainActor [weak self] in
      defer {
        if let self, self.mountGeneration == generation {
          self.mountTask = nil
        }
      }
      do {
        try await mountPresenter.embed(
          client: client,
          options: ["locale": "en", "view": "home"],
          in: supportContainer,
          parent: parent
        )
        guard let self, self.mountGeneration == generation else {
          mountPresenter.close()
          return
        }
        isMounted = true
      } catch {
        guard let self, self.mountGeneration == generation else { return }
        mountPresenter.close()
        presenter = nil
        onError(error)
      }
    }
  }

  func setVisible(_ visible: Bool) {
    guard isMounted else { return }
    presenter?.setEmbeddedVisible(visible)
  }

  func close() {
    mountGeneration += 1
    mountTask?.cancel()
    mountTask = nil
    presenter?.close()
    presenter = nil
    isMounted = false
  }
}

Manter explícitos a apresentação e o ciclo da conta

Apresente a partir de um UIViewController em primeiro plano e chame close quando o ecrã do host for eliminado. Chame client.resetSession() quando o cliente descartar intencionalmente a conversa. O cliente iOS direto não tem logout: reinicie-o, elimine-o e crie um novo cliente antes de alterar accountScope.

O presenter nativo usa o mesmo contrato de aparência do widget web. Omita reduceMotion salvo quando o cliente tiver uma escolha explícita na app. A definição do sistema para reduzir movimento continua prioritária.

Tratar carregamento, visibilidade e acessibilidade

Use hooks de carregamento ou eventos tipados para o estado da tela hospedeira. A superfície mostra o carregamento das mensagens, a espera e as tentativas novamente para evitar um segundo indicador sobre o campo de entrada.

Oculte ou mostre a superfície durante uma navegação temporária mantendo o cliente. O widget respeita as preferências do sistema para reduzir movimento. Remover ou fechar a vista não descarta a sessão nem o rascunho.

  1. Ao montar novamente, reutilize o mesmo cliente e dimensões estáveis do contêiner.
  2. Use a função de visibilidade para ocultar temporariamente, sem redefinir a sessão.
  3. Finalize a sessão apenas ao sair ou trocar de conta de forma intencional.

Verificar o fluxo iOS

  1. Abra o widget a partir de um ecrã em primeiro plano e confirme que tocar duas vezes não cria um segundo controlador.
  2. Inicie uma conversa, feche e abra novamente o widget e confirme que o rascunho e o envio pendente continuam associados à mesma conta.
  3. Rode ou envie a app para segundo plano durante uma operação pendente e aguarde o estado explícito de reconexão ou repetição antes de tentar novamente.
  4. Reinicie e elimine o cliente iOS direto antes de trocar de conta. Depois crie o cliente seguinte e confirme que não consegue ver a conversa anterior.

Prévia dos SDKs nativos

Veja o mesmo fluxo de suporte com controles nativos do iOS e do Android.

Tela de conversa do SDK nativo do iOS da DobroDesk com uma mensagem do cliente, campo de entrada e navegação inferior
Prévia nativa do iOS com textos personalizados em português, mensagem do cliente localizada, entrada nativa e barra de abas.