// // BibleAPI.swift // Bible-Week // // Cliente da API da Bíblia (NBV - Nova Bíblia Viva). // import Foundation // MARK: - Modelos /// Um livro da Bíblia (ex.: Gênesis, João). struct Book: Decodable, Identifiable, Hashable { let code: String let name: String let testament: String let bookOrder: Int let chapterCount: Int var id: String { code } enum CodingKeys: String, CodingKey { case code, name, testament case bookOrder = "book_order" case chapterCount = "chapter_count" } } /// Resposta de `GET /v1/books`. struct BooksResponse: Decodable { let books: [Book] } /// Um versículo com seu número e texto. struct Verse: Decodable, Identifiable, Hashable { let verse: Int let text: String var id: Int { verse } } /// Resposta de um capítulo completo. struct Chapter: Decodable, Hashable { let translation: String let book: String let bookName: String let chapter: Int let verses: [Verse] } // MARK: - Serviço /// Cliente mínimo, somente leitura, para a API da Bíblia. enum BibleAPI { static let baseURL = URL(string: "https://bible.falehandix.com.br")! // A chave vive em Secrets.swift (gitignored) — ver Secrets.swift.example. static let apiKey = Secrets.bibleAPIKey /// Faz um GET na API e decodifica a resposta JSON. static func get(_ path: String, query: [URLQueryItem] = []) async throws -> T { var components = URLComponents( url: baseURL.appendingPathComponent(path), resolvingAgainstBaseURL: false )! if !query.isEmpty { components.queryItems = query } var request = URLRequest(url: components.url!) request.setValue(apiKey, forHTTPHeaderField: "X-API-Key") let (data, response) = try await URLSession.shared.data(for: request) guard let http = response as? HTTPURLResponse, 200..<300 ~= http.statusCode else { throw URLError(.badServerResponse) } return try JSONDecoder().decode(T.self, from: data) } /// Busca todos os 66 livros em ordem canônica. static func books() async throws -> [Book] { let response: BooksResponse = try await get("/v1/books") return response.books } /// Busca o texto completo de um capítulo. static func chapter(book code: String, chapter: Int) async throws -> Chapter { try await get("/v1/books/\(code)/chapters/\(chapter)") } }