SDKs que apresentam UI precisam gerenciar navegacao sem depender do navigation stack do app host. O pattern Coordinator encapsula o fluxo inteiro, enquanto programmatic Auto Layout garante controle total sem storyboards.

Por que Coordinator em SDKs?

Um SDK de verificacao de identidade tem um fluxo multi-step (permissao de camera, captura de documento, selfie, upload, resultado). O Coordinator pattern encapsula toda essa navegacao, isolando o SDK do app host.

Vantagens do Coordinator

  • Isolamento: SDK controla seu proprio navigation stack
  • Reutilizacao: ViewControllers nao sabem sobre navegacao
  • Testabilidade: fluxo pode ser testado sem UI
  • Flexibilidade: steps podem ser adicionados/removidos via config
  • Cleanup: coordinator garante dismiss correto de tudo

Sem Coordinator (problemas)

  • ViewControllers acoplados entre si
  • SDK depende do UINavigationController do app
  • Dificil pular ou reordenar steps
  • Memory leaks por referencia circular entre VCs
  • Testes requerem instanciar toda a hierarquia de UI

Programmatic Auto Layout

Em SDKs, preferimos Auto Layout programatico sobre storyboards/XIBs. Isso elimina conflitos de merge, permite versionamento limpo e da controle total sobre constraints.

AspectoProgrammaticStoryboard/XIB
VersionamentoDiff legivel em PRXML opaco, conflitos frequentes
Distribuicao SDKApenas codigo SwiftPrecisa incluir resource bundles
Dynamic TypeFacil de adaptar constraintsSuporta mas menos flexivel
PerformanceSem desserializacao de XIBCarrega e parseia XML
ReutilizacaoFuncoes e extensoes de layoutDificil parametrizar
// Auto Layout helpers para codigo limpo extension UIView { func pin( to parent: UIView, insets: UIEdgeInsets = .zero ) { translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ topAnchor.constraint( equalTo: parent.topAnchor, constant: insets.top ), leadingAnchor.constraint( equalTo: parent.leadingAnchor, constant: insets.left ), trailingAnchor.constraint( equalTo: parent.trailingAnchor, constant: -insets.right ), bottomAnchor.constraint( equalTo: parent.bottomAnchor, constant: -insets.bottom ), ]) } func centerIn(_ parent: UIView) { translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ centerXAnchor.constraint(equalTo: parent.centerXAnchor), centerYAnchor.constraint(equalTo: parent.centerYAnchor), ]) } func size(width: CGFloat? = nil, height: CGFloat? = nil) { translatesAutoresizingMaskIntoConstraints = false if let w = width { widthAnchor.constraint(equalToConstant: w).isActive = true } if let h = height { heightAnchor.constraint(equalToConstant: h).isActive = true } } }