SDK Swift ainda não disponível. Não existe um pacote Swift Package Manager oficial para o SuperDB ainda.
Enquanto isso, a integração via URLSession funciona perfeitamente — o SuperDB usa APIs REST padrão HTTP/JSON. Quer ajudar a criar o SDK? GitHub Discussions →
Abordagem: URLSession + Keychain
No iOS nativo, o fluxo é:
- Fazer login via
URLSessionchamando a API REST do SuperDB - Armazenar o JWT no Keychain do iOS — o equivalente seguro ao SecureStore do Expo
- Incluir o JWT no header
Authorization: Bearerem todas as requisições subsequentes
Se preferir usar Alamofire, a lógica é idêntica — apenas a camada de HTTP muda.
Serviço de autenticação
SuperDBAuth.swift
import Foundation
import Security
struct AuthResponse: Codable {
let accessToken: String
let refreshToken: String
let user: UserInfo?
enum CodingKeys: String, CodingKey {
case accessToken = "access_token"
case refreshToken = "refresh_token"
case user
}
}
struct UserInfo: Codable {
let id: String
let email: String?
}
class SuperDBAuth {
static let shared = SuperDBAuth()
private let baseURL = "https://auth.superdb.com.br"
private let anonKey = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
private let tokenKey = "superdb_access_token"
private var defaultHeaders: [String: String] {
["Content-Type": "application/json", "apikey": anonKey]
}
// MARK: - Keychain helpers
func saveToken(_ token: String) {
let data = Data(token.utf8)
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: tokenKey,
kSecValueData as String: data
]
SecItemDelete(query as CFDictionary)
SecItemAdd(query as CFDictionary, nil)
}
func getToken() -> String? {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: tokenKey,
kSecReturnData as String: true,
kSecMatchLimit as String: kSecMatchLimitOne
]
var result: AnyObject?
SecItemCopyMatching(query as CFDictionary, &result)
guard let data = result as? Data else { return nil }
return String(data: data, encoding: .utf8)
}
func deleteToken() {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: tokenKey
]
SecItemDelete(query as CFDictionary)
}
// MARK: - Auth
func signIn(email: String, password: String) async throws -> AuthResponse {
var request = URLRequest(url: URL(string: "\(baseURL)/auth/v1/token?grant_type=password")!)
request.httpMethod = "POST"
defaultHeaders.forEach { request.setValue($1, forHTTPHeaderField: $0) }
request.httpBody = try JSONEncoder().encode(["email": email, "password": password])
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200 else {
throw URLError(.badServerResponse)
}
let authResponse = try JSONDecoder().decode(AuthResponse.self, from: data)
saveToken(authResponse.accessToken)
return authResponse
}
func signUp(email: String, password: String) async throws -> AuthResponse {
var request = URLRequest(url: URL(string: "\(baseURL)/auth/v1/signup")!)
request.httpMethod = "POST"
defaultHeaders.forEach { request.setValue($1, forHTTPHeaderField: $0) }
request.httpBody = try JSONEncoder().encode(["email": email, "password": password])
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
(200...201).contains(httpResponse.statusCode) else {
throw URLError(.badServerResponse)
}
return try JSONDecoder().decode(AuthResponse.self, from: data)
}
func signOut() async {
deleteToken()
}
}
Queries no banco de dados
SuperDBDatabase.swift
class SuperDBDatabase {
// Dados: api.superdb.com.br (NÃO auth.superdb.com.br)
// Path: raiz da tabela, sem prefixo /rest/v1/
private let dataURL = "https://api.superdb.com.br"
private let anonKey = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
func fetch<T: Decodable>(
from table: String,
type: T.Type,
query: String = ""
) async throws -> [T] {
guard let token = SuperDBAuth.shared.getToken() else {
throw URLError(.userAuthenticationRequired)
}
// Correto: api.superdb.com.br/ (sem /rest/v1/)
let urlString = "\(dataURL)/\(table)\(query)"
var request = URLRequest(url: URL(string: urlString)!)
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
request.setValue(anonKey, forHTTPHeaderField: "apikey")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let (data, _) = try await URLSession.shared.data(for: request)
return try JSONDecoder().decode([T].self, from: data)
}
}
// Uso:
struct Post: Codable {
let id: Int
let title: String
let body: String?
}
// Em um ViewModel ou View:
let db = SuperDBDatabase()
let posts = try await db.fetch(
from: "posts",
type: Post.self,
query: "?order=created_at.desc&limit=20"
)
Alternativa com Alamofire
Se preferir usar Alamofire (Swift Package Manager: https://github.com/Alamofire/Alamofire):
Com Alamofire
import Alamofire
let token = SuperDBAuth.shared.getToken() ?? ""
// Dados: api.superdb.com.br/ (sem /rest/v1/)
AF.request(
"https://api.superdb.com.br/posts",
headers: [
"Authorization": "Bearer \(token)",
"apikey": anonKey
]
)
.responseDecodable(of: [Post].self) { response in
switch response.result {
case .success(let posts):
print("Posts: \(posts)")
case .failure(let error):
print("Erro: \(error)")
}
}
Quando o SDK Swift estiver disponível
- Vote e acompanhe o SDK Swift nas Discussions
- Referência completa da API REST
- Como funcionam os JWT tokens
- Expo (React Native) — SDK JS disponível hoje
Essa página ajudou?