Padrões de Projeto em Swift: nível avançado com exemplos para iOS/macOS
\n\nPadrões de projeto são soluções comprovadas para problemas típicos no desenvolvimento. Para desenvolvedores Swift que trabalham com aplicações iOS e macOS, dominar padrões avançados é criticamente importante para criar projetos escaláveis, testáveis e sustentáveis. Neste artigo, vamos analisar quatro padrões-chave: MVVM, Coordinator, Builder e Factory. Cada um deles resolve problemas arquiteturais específicos e é amplamente utilizado no desenvolvimento comercial.
\n\n1. Padrão MVVM (Model-View-ViewModel) em Swift
\n\nMVVM é um dos padrões arquiteturais mais populares para SwiftUI e UIKit. Ele garante uma separação clara entre a lógica de apresentação e a lógica de negócios, simplificando os testes e a reutilização de código.
\n\nComponentes do MVVM:
\n- \n
- Model — dados e lógica de negócios (requisições de rede, trabalho com BD). \n
- View — UI (SwiftUI View ou UIViewController). \n
- ViewModel — intermediário que prepara os dados para a View e processa as ações do usuário. \n
Exemplo de implementação em SwiftUI:
\n\nimport SwiftUI\nimport Combine\n\n// MARK: - Model\nstruct User: Codable {\n let id: Int\n let name: String\n let email: String\n}\n\n// MARK: - ViewModel\nclass UserViewModel: ObservableObject {\n @Published var users: [User] = []\n @Published var isLoading = false\n private var cancellables = Set<AnyCancellable>()\n \n func fetchUsers() {\n isLoading = true\n guard let url = URL(string: "https://jsonplaceholder.typicode.com/users") else { return }\n \n URLSession.shared.dataTaskPublisher(for: url)\n .map { $0.data }\n .decode(type: [User].self, decoder: JSONDecoder())\n .receive(on: DispatchQueue.main)\n .sink(receiveCompletion: { [weak self] completion in\n self?.isLoading = false\n if case .failure(let error) = completion {\n print("Error: \\(error)")\n }\n }, receiveValue: { [weak self] users in\n self?.users = users\n })\n .store(in: &cancellables)\n }\n}\n\n// MARK: - View\nstruct UserListView: View {\n @StateObject private var viewModel = UserViewModel()\n \n var body: some View {\n NavigationView {\n List(viewModel.users, id: \\.id) { user in\n VStack(alignment: .leading) {\n Text(user.name).font(.headline)\n Text(user.email).font(.subheadline).foregroundColor(.secondary)\n }\n }\n .navigationTitle("Users")\n .overlay {\n if viewModel.isLoading {\n ProgressView()\n }\n }\n }\n .onAppear {\n viewModel.fetchUsers()\n }\n }\n}\n\nVantagens do MVVM:
\n- \n
- Separação clara de responsabilidades. \n
- Teste fácil da ViewModel sem UI. \n
- Atualização reativa da UI via Combine ou @Published. \n
2. Padrão Coordinator (Coordenador) para navegação
\n\nO Coordinator resolve o problema dos ViewControllers "gordos", transferindo a lógica de navegação para objetos separados. Isso simplifica a reutilização de telas e torna a navegação flexível.
\n\nEstrutura:
\n- \n
- AppCoordinator — coordenador principal que gerencia os filhos. \n
- ChildCoordinator — responsável por um fluxo específico (ex.: autenticação ou tela principal). \n
Exemplo de implementação para UIKit:
\n\nimport UIKit\n\n// MARK: - Coordinator Protocol\nprotocol Coord