Keplers Mail Service

iOS Swift

iOS Swift integration examples for Keplers Mail Service

Send emails using iOS Swift with Keplers Mail Service REST API.

Installation

No additional dependencies required for basic usage.

Basic Setup

// Add your API key to Info.plist or use environment variables
let apiKey = "kms_your_api_key.live_..."

REST API Integration

Basic Client

import Foundation

class KeplersEmailClient {
    private let apiKey: String
    private let baseURL: String
    private let session: URLSession
    
    init(apiKey: String, baseURL: String = "https://api.keplars.com") {
        self.apiKey = apiKey
        self.baseURL = baseURL
        self.session = URLSession.shared
    }
    
    func sendEmail(
        to: String,
        subject: String,
        body: String,
        isHTML: Bool = false,
        completion: @escaping (Result<[String: Any], Error>) -> Void
    ) {
        makeRequest(endpoint: "/api/v1/send-email/queue", to: to, subject: subject, body: body, isHTML: isHTML, completion: completion)
    }
    
    func sendInstantEmail(
        to: String,
        subject: String,
        body: String,
        isHTML: Bool = false,
        completion: @escaping (Result<[String: Any], Error>) -> Void
    ) {
        makeRequest(endpoint: "/api/v1/send-email/instant", to: to, subject: subject, body: body, isHTML: isHTML, completion: completion)
    }
    
    private func makeRequest(
        endpoint: String,
        to: String,
        subject: String,
        body: String,
        isHTML: Bool,
        completion: @escaping (Result<[String: Any], Error>) -> Void
    ) {
        guard let url = URL(string: "\(baseURL)\(endpoint)") else {
            completion(.failure(KeplersError.invalidURL))
            return
        }
        
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        
        let payload: [String: Any] = [
            "to": [to],
            "subject": subject,
            "body": body,
            "is_html": isHTML
        ]
        
        do {
            request.httpBody = try JSONSerialization.data(withJSONObject: payload)
        } catch {
            completion(.failure(error))
            return
        }
        
        session.dataTask(with: request) { data, response, error in
            if let error = error {
                completion(.failure(error))
                return
            }
            
            guard let httpResponse = response as? HTTPURLResponse,
                  let data = data else {
                completion(.failure(KeplersError.invalidResponse))
                return
            }
            
            if httpResponse.statusCode == 200 {
                do {
                    if let jsonResponse = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
                        completion(.success(jsonResponse))
                    } else {
                        completion(.failure(KeplersError.invalidJSON))
                    }
                } catch {
                    completion(.failure(error))
                }
            } else {
                completion(.failure(KeplersError.httpError(httpResponse.statusCode)))
            }
        }.resume()
    }
}

enum KeplersError: Error {
    case invalidURL
    case invalidResponse
    case invalidJSON
    case noData
    case httpError(Int)
}

Usage Examples

class EmailService {
    private let client: KeplersEmailClient
    
    init() {
        guard let apiKey = Bundle.main.object(forInfoDictionaryKey: "KEPLERS_API_KEY") as? String else {
            fatalError("KEPLERS_API_KEY not found in Info.plist")
        }
        self.client = KeplersEmailClient(apiKey: apiKey)
    }
    
    func sendWelcomeEmail(to userEmail: String, name userName: String, completion: @escaping (Bool) -> Void) {
        let htmlBody = """
            <h1>Welcome \(userName)!</h1>
            <p>Thank you for joining our platform.</p>
        """
        
        client.sendEmail(to: userEmail, subject: "Welcome \(userName)!", body: htmlBody, isHTML: true) { result in
            DispatchQueue.main.async {
                switch result {
                case .success(let response):
                    print("Email sent: \(response)")
                    completion(true)
                case .failure(let error):
                    print("Failed to send email: \(error)")
                    completion(false)
                }
            }
        }
    }
    
    func sendVerificationEmail(to userEmail: String, code: String, completion: @escaping (Bool) -> Void) {
        let body = "Your verification code: \(code)"
        
        client.sendInstantEmail(to: userEmail, subject: "Verify Your Email", body: body, isHTML: false) { result in
            DispatchQueue.main.async {
                switch result {
                case .success(let response):
                    print("Verification email sent: \(response)")
                    completion(true)
                case .failure(let error):
                    print("Failed to send verification email: \(error)")
                    completion(false)
                }
            }
        }
    }
}

SwiftUI Integration

import SwiftUI

struct EmailView: View {
    @State private var email = ""
    @State private var name = ""
    @State private var isLoading = false
    @State private var showAlert = false
    @State private var alertMessage = ""
    
    private let emailService = EmailService()
    
    var body: some View {
        VStack(spacing: 20) {
            TextField("Email", text: $email)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .keyboardType(.emailAddress)
                .autocapitalization(.none)
            
            TextField("Name", text: $name)
                .textFieldStyle(RoundedBorderTextFieldStyle())
            
            Button("Send Welcome Email") {
                sendEmail()
            }
            .disabled(isLoading || email.isEmpty || name.isEmpty)
            
            if isLoading {
                ProgressView()
            }
        }
        .padding()
        .alert("Email Status", isPresented: $showAlert) {
            Button("OK") { }
        } message: {
            Text(alertMessage)
        }
    }
    
    private func sendEmail() {
        isLoading = true
        
        emailService.sendWelcomeEmail(to: email, name: name) { success in
            isLoading = false
            alertMessage = success ? "Email sent successfully!" : "Failed to send email"
            showAlert = true
        }
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            EmailView()
                .navigationTitle("Keplers Email")
        }
    }
}

UIKit Integration

import UIKit

class EmailViewController: UIViewController {
    @IBOutlet weak var emailTextField: UITextField!
    @IBOutlet weak var nameTextField: UITextField!
    @IBOutlet weak var sendButton: UIButton!
    @IBOutlet weak var activityIndicator: UIActivityIndicatorView!
    
    private let emailService = EmailService()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
    }
    
    private func setupUI() {
        title = "Send Email"
        emailTextField.keyboardType = .emailAddress
        emailTextField.autocapitalizationType = .none
    }
    
    @IBAction func sendEmailTapped(_ sender: UIButton) {
        guard let email = emailTextField.text, !email.isEmpty,
              let name = nameTextField.text, !name.isEmpty else {
            showAlert(message: "Please fill in all fields")
            return
        }
        
        setLoading(true)
        
        emailService.sendWelcomeEmail(to: email, name: name) { [weak self] success in
            self?.setLoading(false)
            let message = success ? "Email sent successfully!" : "Failed to send email"
            self?.showAlert(message: message)
        }
    }
    
    private func setLoading(_ loading: Bool) {
        sendButton.isEnabled = !loading
        if loading {
            activityIndicator.startAnimating()
        } else {
            activityIndicator.stopAnimating()
        }
    }
    
    private func showAlert(message: String) {
        let alert = UIAlertController(title: "Email Status", message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        present(alert, animated: true)
    }
}

Async/Await Support

extension KeplersEmailClient {
    @available(iOS 13.0, *)
    func sendEmail(
        to: String,
        subject: String,
        body: String,
        isHTML: Bool = false
    ) async throws -> [String: Any] {
        return try await withCheckedThrowingContinuation { continuation in
            sendEmail(to: to, subject: subject, body: body, isHTML: isHTML) { result in
                continuation.resume(with: result)
            }
        }
    }
    
    @available(iOS 13.0, *)
    func sendInstantEmail(
        to: String,
        subject: String,
        body: String,
        isHTML: Bool = false
    ) async throws -> [String: Any] {
        return try await withCheckedThrowingContinuation { continuation in
            sendInstantEmail(to: to, subject: subject, body: body, isHTML: isHTML) { result in
                continuation.resume(with: result)
            }
        }
    }
}

// Usage with async/await
class ModernEmailService {
    private let client = KeplersEmailClient(apiKey: "your_api_key")
    
    @available(iOS 13.0, *)
    func sendWelcomeEmail(to email: String, name: String) async throws {
        let htmlBody = "<h1>Welcome \(name)!</h1><p>Thank you for joining our platform.</p>"
        let response = try await client.sendEmail(to: email, subject: "Welcome \(name)!", body: htmlBody, isHTML: true)
        print("Email sent: \(response)")
    }
}

iOS Swift provides native integration with Keplers Mail Service using URLSession for HTTP requests.

On this page