Módulo 02 — Lógica de Programação, Algoritmos & 40 Linguagens • Bloco 7: Desenvolvimento Mobile Nativo


🎯 Nível 1: Fundamentos

Problema 17.1 — Inferência de Tipos, Optionals Seguros e guard let em Swift

Contexto: Swift foi desenhada pela Apple com segurança estrita contra ponteiros nulos (null safety) usando Optionals.

Requisitos de Execução:

  1. Criar um script Swift validacao_usuario.swift.
  2. Declarar uma função func autenticarUsuario(token: String?) -> String.
  3. Usar guard let token = token, !token.isEmpty else { return "Acesso Negado" } para desembrulhar o optional com segurança.

Resultado Esperado

Autenticação 1: Sessão Ativa (Token: sec_abc123)
Autenticação 2: Acesso Negado: Token Ausente ou Inválido

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_17_1_SeuNome.swift
  2. Envie na tarefa: Atividade Cap 17 - Linguagem Swift
🔑 Gabarito de Código & Solução Comentada
import Foundation

func autenticarUsuario(token: String?) -> String {
    guard let tokenValido = token, !tokenValido.isEmpty else {
        return "Acesso Negado: Token Ausente ou Inválido"
    }
    return "Sessão Ativa (Token: \(tokenValido))"
}

let tokenValido: String? = "sec_abc123"
let tokenInvalido: String? = nil

print("Autenticação 1: \(autenticarUsuario(token: tokenValido))")
print("Autenticação 2: \(autenticarUsuario(token: tokenInvalido))")

🔍 Nível 2: Prática

Problema 17.2 — struct Imutável, Closures de Alta Ordem e Enums com Valores Associados

Contexto: Em Swift, structs são tipos de valor (value types) altamente otimizados e preferidos para modelagem de domínio.

Requisitos de Execução:

  1. Definir o enum enum StatusPedido { case pendente; case aprovado(codigo: String); case cancelado(motivo: String) }.
  2. Criar uma struct Pedido com id: Int, valor: Double e status: StatusPedido.
  3. Filtrar uma lista de pedidos usando closures de alta ordem (pedidos.filter { ... }.map { $0.valor }).

Resultado Esperado

Total de Pedidos Aprovados: R$ 3.850,00
Pedidos Processados:
- Pedido #1: Aprovado [AUT-9921]
- Pedido #2: Cancelado por Falha no pagamento
- Pedido #3: Aprovado [AUT-9922]

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_17_2_SeuNome.swift
  2. Envie na tarefa: Atividade Cap 17 - Linguagem Swift
🔑 Gabarito de Código & Solução Comentada
import Foundation

enum StatusPedido {
    case pendente
    case aprovado(codigo: String)
    case cancelado(motivo: String)
}

struct Pedido {
    let id: Int
    let valor: Double
    let status: StatusPedido
}

let pedidos: [Pedido] = [
    Pedido(id: 1, valor: 2500.0, status: .aprovado(codigo: "AUT-9921")),
    Pedido(id: 2, valor: 450.0, status: .cancelado(motivo: "Falha no pagamento")),
    Pedido(id: 3, valor: 1350.0, status: .aprovado(codigo: "AUT-9922"))
]

let totalAprovado = pedidos
    .filter {
        if case .aprovado = $0.status { return true }
        return false
    }
    .reduce(0.0) { $0 + $1.valor }

print("Total de Pedidos Aprovados: R$ \(String(format: "%.2f", totalAprovado))")
print("Pedidos Processados:")
for p in pedidos {
    switch p.status {
    case .pendente:
        print("- Pedido #\(p.id): Pendente")
    case .aprovado(let cod):
        print("- Pedido #\(p.id): Aprovado [\(cod)]")
    case .cancelado(let mot):
        print("- Pedido #\(p.id): Cancelado por \(mot)")
    }
}

⚡ Nível 3: Integração

Problema 17.3 — Protocolos, Extensões (extension) e Protocol-Oriented Programming (POP)

Contexto: Swift favorece a Programação Orientada a Protocolos em detrimento de hierarquias complexas de classes.

Requisitos de Execução:

  1. Definir o protocolo protocol Notificavel { var destino: String { get }; func enviarMensagem(_ texto: String) }.
  2. Criar uma extensão com implementação padrão extension Notificavel.
  3. Implementar structs NotificacaoEmail e NotificacaoPush.

Resultado Esperado

[EMAIL para dev@empresa.com]: Build de produção concluído com sucesso!
[PUSH para Token-iOS-9981]: Seu pedido saiu para entrega!

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_17_3_SeuNome.swift
  2. Envie na tarefa: Atividade Cap 17 - Linguagem Swift
🔑 Gabarito de Código & Solução Comentada
import Foundation

protocol Notificavel {
    var destino: String { get }
    func enviarMensagem(_ texto: String)
}

extension Notificavel {
    func enviarMensagemPadrao() {
        enviarMensagem("Mensagem do Sistema")
    }
}

struct NotificacaoEmail: Notificavel {
    let destino: String
    func enviarMensagem(_ texto: String) {
        print("[EMAIL para \(destino)]: \(texto)")
    }
}

struct NotificacaoPush: Notificavel {
    let destino: String
    func enviarMensagem(_ texto: String) {
        print("[PUSH para \(destino)]: \(texto)")
    }
}

let email = NotificacaoEmail(destino: "dev@empresa.com")
let push = NotificacaoPush(destino: "Token-iOS-9981")

email.enviarMensagem("Build de produção concluído com sucesso!")
push.enviarMensagem("Seu pedido saiu para entrega!")

🏆 Nível 4: Desafio Corporativo

Problema 17.4 — Consumo de API Assíncrona com async/await e Codable em Swift

Contexto: Concorrência moderna estruturada (async/await) e desserialização automática com Codable para aplicativos iOS corporativos.

Requisitos de Execução:

  1. Definir a struct Usuario: Codable, Identifiable { let id: Int; let name: String; let email: String }.
  2. Criar uma função assíncrona func buscarUsuariosRemotos() async throws -> [Usuario].
  3. Simular o parsing de JSON e exibir o relatório consolidado.

Resultado Esperado

=== CLIENTE HTTP ASSÍNCRONO (SWIFT ASYNC/AWAIT) ===
Buscando dados na API remota...
[SUCESSO] 2 usuários desserializados com Codable:
- ID #1: Ricardo Lima (ricardo@tech.com)
- ID #2: Beatriz Souza (beatriz@tech.com)

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_17_4_SeuNome.swift
  2. Envie na tarefa: Atividade Cap 17 - Linguagem Swift
🔑 Gabarito de Código & Solução Comentada
import Foundation

struct Usuario: Codable, Identifiable {
    let id: Int
    let name: String
    let email: String
}

func buscarUsuariosRemotos() async throws -> [Usuario] {
    let jsonMock = """
    [
        {"id": 1, "name": "Ricardo Lima", "email": "ricardo@tech.com"},
        {"id": 2, "name": "Beatriz Souza", "email": "beatriz@tech.com"}
    ]
    """.data(using: .utf8)!

    let decoder = JSONDecoder()
    let usuarios = try decoder.decode([Usuario].self, from: jsonMock)
    return usuarios
}

Task {
    print("=== CLIENTE HTTP ASSÍNCRONO (SWIFT ASYNC/AWAIT) ===")
    print("Buscando dados na API remota...")
    do {
        let lista = try await buscarUsuariosRemotos()
        print("[SUCESSO] \(lista.count) usuários desserializados com Codable:")
        for u in lista {
            print("- ID #\(u.id): \(u.name) (\(u.email))")
        }
    } catch {
        print("[ERRO]: \(error.localizedDescription)")
    }
}