help@rskworld.in +91 93305 39277
RSK World
  • Home
  • Development
    • Web Development
    • Mobile Apps
    • Software
    • Games
    • Project
  • Technologies
    • Data Science
    • AI Development
    • Cloud Development
    • Blockchain
    • Cyber Security
    • Dev Tools
    • Testing Tools
  • About
  • Contact

Theme Settings

Color Scheme
Display Options
Font Size
100%
Back to Project
RSK World
swift-ios-calculator
RSK World
swift-ios-calculator
Swift iOS Calculator v1.0 - AI Math Solver + 3D Graphing + Apple Watch Integration + iOS Widgets + Siri Shortcuts + Currency Converter + Scientific Calculator + Matrix Operations + Platform Integration + Modern iOS Development
swift-ios-calculator
  • Assets.xcassets
  • Base.lproj
  • swift-ios-calculator.xcodeproj
  • AIMathSolverViewController.swift26.6 KB
  • AppDelegate.swift1.7 KB
  • CalculatorHistoryViewController.swift6.5 KB
  • CalculatorLogic.swift4.4 KB
  • CalculatorSettingsViewController.swift5.6 KB
  • CalculatorTheme.swift8.3 KB
  • CalculatorUtils.swift6.9 KB
  • CalculatorViewController.swift3.4 KB
  • CalculatorWidget.swift14.3 KB
  • CalculatorWidgetInfo.plist846 B
  • ChemistryCalculatorViewController.swift26.9 KB
  • CurrencyConverterViewController.swift13.3 KB
  • CustomFormulaBuilderViewController.swift22.1 KB
  • EngineeringCalculatorViewController.swift25.7 KB
  • EquationSolverViewController.swift22.8 KB
  • FinancialCalculatorViewController.swift27.5 KB
  • GeometryCalculatorViewController.swift29.7 KB
  • Graphing3DViewController.swift20.8 KB
  • GraphingCalculatorViewController.swift14.7 KB
  • Info.plist3.2 KB
  • LICENSE1.1 KB
  • MainTabBarController.swift22.3 KB
  • MatrixCalculatorViewController.swift26.6 KB
  • PRIVACY_POLICY.md1.6 KB
  • PhysicsCalculatorService.swift8.2 KB
  • ProgrammerCalculatorViewController.swift11 KB
  • README.md8.7 KB
  • RELEASE_NOTES.md6.5 KB
  • SceneDelegate.swift2.8 KB
  • ScientificCalculatorViewController.swift6.2 KB
  • SiriShortcutsManager.swift23.5 KB
  • Swift iOS Calculator.entitlements1.1 KB
  • UnitConverterViewController.swift14 KB
  • WatchCalculatorViewController.swift15.3 KB
  • index.html47.5 KB
CurrencyConverterViewController.swiftCalculatorLogic.swift
CurrencyConverterViewController.swift
Raw Download
Find: Go to:
//
//  CurrencyConverterViewController.swift
//  Swift iOS Calculator
//
//  Created by RSK World on 23/01/2026.
//  Copyright © 2026 RSK World. All rights reserved.
//
//  Developer: Molla Samser (Founder, RSK World)
//  Designer & Tester: Rima Khatun
//  Contact: info@rskworld.com, +91 93305 39277
//  Website: https://rskworld.in
//  Address: Nutanhat, Mongolkote, Purba Burdwan, West Bengal, India - 713147
//

import UIKit

class CurrencyConverterViewController: UIViewController {
    
    // MARK: - Outlets
    @IBOutlet weak var fromCurrencyTextField: UITextField!
    @IBOutlet weak var toCurrencyTextField: UITextField!
    @IBOutlet weak var fromCurrencyPickerView: UIPickerView!
    @IBOutlet weak var toCurrencyPickerView: UIPickerView!
    @IBOutlet weak var exchangeRateLabel: UILabel!
    @IBOutlet weak var lastUpdatedLabel: UILabel!
    @IBOutlet weak var convertButton: UIButton!
    @IBOutlet weak var swapButton: UIButton!
    @IBOutlet weak var refreshButton: UIButton!
    @IBOutlet weak var favoriteCurrenciesButton: UIButton!
    
    // MARK: - Properties
    private let currencies = [
        ("USD", "United States Dollar", "$"),
        ("EUR", "Euro", "€"),
        ("GBP", "British Pound", "£"),
        ("JPY", "Japanese Yen", "¥"),
        ("AUD", "Australian Dollar", "A$"),
        ("CAD", "Canadian Dollar", "C$"),
        ("CHF", "Swiss Franc", "Fr"),
        ("CNY", "Chinese Yuan", "¥"),
        ("INR", "Indian Rupee", "₹"),
        ("KRW", "South Korean Won", "₩"),
        ("BRL", "Brazilian Real", "R$"),
        ("RUB", "Russian Ruble", "₽"),
        ("MXN", "Mexican Peso", "$"),
        ("SGD", "Singapore Dollar", "S$"),
        ("HKD", "Hong Kong Dollar", "HK$"),
        ("SEK", "Swedish Krona", "kr"),
        ("NOK", "Norwegian Krone", "kr"),
        ("NZD", "New Zealand Dollar", "NZ$"),
        ("ZAR", "South African Rand", "R"),
        ("TRY", "Turkish Lira", "₺")
    ]
    
    private var selectedFromCurrency = 0
    private var selectedToCurrency = 1
    private var exchangeRates: [String: Double] = [:]
    private var lastUpdated: Date = Date()
    
    // MARK: - Lifecycle
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        setupPickerViews()
        loadExchangeRates()
    }
    
    // MARK: - Setup
    private func setupUI() {
        title = "Currency Converter"
        view.backgroundColor = CalculatorTheme.shared.backgroundColor
        
        // Setup text fields
        setupTextField(fromCurrencyTextField, placeholder: "Enter amount")
        setupTextField(toCurrencyTextField, placeholder: "Converted amount")
        
        // Setup labels
        exchangeRateLabel.backgroundColor = CalculatorTheme.shared.displayBackgroundColor
        exchangeRateLabel.textColor = CalculatorTheme.shared.textColor
        exchangeRateLabel.layer.cornerRadius = 8
        exchangeRateLabel.layer.masksToBounds = true
        exchangeRateLabel.textAlignment = .center
        exchangeRateLabel.font = UIFont.systemFont(ofSize: 16, weight: .medium)
        
        lastUpdatedLabel.textColor = CalculatorTheme.shared.textColor
        lastUpdatedLabel.textAlignment = .center
        lastUpdatedLabel.font = UIFont.systemFont(ofSize: 12)
        
        // Setup buttons
        setupButton(convertButton, title: "Convert", color: .systemGreen)
        setupButton(swapButton, title: "⇄", color: .systemBlue)
        setupButton(refreshButton, title: "↻", color: .systemOrange)
        setupButton(favoriteCurrenciesButton, title: "★", color: .systemYellow)
    }
    
    private func setupTextField(_ textField: UITextField, placeholder: String) {
        textField.backgroundColor = CalculatorTheme.shared.displayBackgroundColor
        textField.textColor = CalculatorTheme.shared.textColor
        textField.placeholder = placeholder
        textField.textAlignment = .center
        textField.font = UIFont.systemFont(ofSize: 24, weight: .medium)
        textField.layer.cornerRadius = 12
        textField.layer.borderWidth = 2
        textField.layer.borderColor = CalculatorTheme.shared.buttonBackgroundColor.cgColor
        textField.keyboardType = .decimalPad
    }
    
    private func setupButton(_ button: UIButton, title: String, color: UIColor) {
        button.setTitle(title, for: .normal)
        button.backgroundColor = color
        button.setTitleColor(.white, for: .normal)
        button.layer.cornerRadius = 25
        button.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .medium)
    }
    
    private func setupPickerViews() {
        fromCurrencyPickerView.delegate = self
        fromCurrencyPickerView.dataSource = self
        toCurrencyPickerView.delegate = self
        toCurrencyPickerView.dataSource = self
        
        fromCurrencyPickerView.selectRow(selectedFromCurrency, inComponent: 0, animated: false)
        toCurrencyPickerView.selectRow(selectedToCurrency, inComponent: 0, animated: false)
    }
    
    // MARK: - Actions
    @IBAction func convertButtonPressed(_ sender: UIButton) {
        performConversion()
    }
    
    @IBAction func swapButtonPressed(_ sender: UIButton) {
        let tempCurrency = selectedFromCurrency
        selectedFromCurrency = selectedToCurrency
        selectedToCurrency = tempCurrency
        
        fromCurrencyPickerView.selectRow(selectedFromCurrency, inComponent: 0, animated: true)
        toCurrencyPickerView.selectRow(selectedToCurrency, inComponent: 0, animated: true)
        
        performConversion()
    }
    
    @IBAction func refreshButtonPressed(_ sender: UIButton) {
        loadExchangeRates()
    }
    
    @IBAction func favoriteCurrenciesButtonPressed(_ sender: UIButton) {
        showFavoriteCurrencies()
    }
    
    @IBAction func fromCurrencyChanged(_ sender: UITextField) {
        performConversion()
    }
    
    // MARK: - Methods
    private func loadExchangeRates() {
        // Simulate API call with mock data
        // In a real app, you would fetch from a real API like exchangerate-api.com
        exchangeRates = [
            "USD": 1.0,
            "EUR": 0.92,
            "GBP": 0.79,
            "JPY": 149.50,
            "AUD": 1.53,
            "CAD": 1.36,
            "CHF": 0.88,
            "CNY": 7.24,
            "INR": 83.12,
            "KRW": 1318.50,
            "BRL": 4.97,
            "RUB": 89.75,
            "MXN": 17.15,
            "SGD": 1.35,
            "HKD": 7.82,
            "SEK": 10.75,
            "NOK": 10.85,
            "NZD": 1.67,
            "ZAR": 18.95,
            "TRY": 29.75
        ]
        
        lastUpdated = Date()
        updateLastUpdatedLabel()
        performConversion()
        
        // Show success message
        showAlert(title: "Success", message: "Exchange rates updated successfully!")
    }
    
    private func performConversion() {
        guard let inputText = fromCurrencyTextField.text, let inputValue = Double(inputText) else {
            toCurrencyTextField.text = ""
            exchangeRateLabel.text = "Enter an amount"
            return
        }
        
        let fromCurrencyCode = currencies[selectedFromCurrency].0
        let toCurrencyCode = currencies[selectedToCurrency].0
        
        guard let fromRate = exchangeRates[fromCurrencyCode],
              let toRate = exchangeRates[toCurrencyCode] else {
            toCurrencyTextField.text = "Rate unavailable"
            exchangeRateLabel.text = "Exchange rate unavailable"
            return
        }
        
        // Convert: input * (toRate / fromRate)
        let convertedAmount = inputValue * (toRate / fromRate)
        let rate = toRate / fromRate
        
        toCurrencyTextField.text = String(format: "%.2f", convertedAmount)
        exchangeRateLabel.text = String(format: "1 %@ = %.4f %@", fromCurrencyCode, rate, toCurrencyCode)
    }
    
    private func updateLastUpdatedLabel() {
        let formatter = DateFormatter()
        formatter.timeStyle = .short
        formatter.dateStyle = .short
        lastUpdatedLabel.text = "Last updated: \(formatter.string(from: lastUpdated))"
    }
    
    private func showFavoriteCurrencies() {
        let alert = UIAlertController(title: "Favorite Currencies", message: "Select your favorite currency pairs for quick access", preferredStyle: .actionSheet)
        
        // Add common currency pairs
        alert.addAction(UIAlertAction(title: "USD/EUR", style: .default) { _ in
            self.setCurrencyPair(from: "USD", to: "EUR")
        })
        
        alert.addAction(UIAlertAction(title: "USD/GBP", style: .default) { _ in
            self.setCurrencyPair(from: "USD", to: "GBP")
        })
        
        alert.addAction(UIAlertAction(title: "USD/JPY", style: .default) { _ in
            self.setCurrencyPair(from: "USD", to: "JPY")
        })
        
        alert.addAction(UIAlertAction(title: "EUR/GBP", style: .default) { _ in
            self.setCurrencyPair(from: "EUR", to: "GBP")
        })
        
        alert.addAction(UIAlertAction(title: "GBP/EUR", style: .default) { _ in
            self.setCurrencyPair(from: "GBP", to: "EUR")
        })
        
        alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
        
        if let popover = alert.popoverPresentationController {
            popover.sourceView = favoriteCurrenciesButton
            popover.sourceRect = favoriteCurrenciesButton.bounds
        }
        
        present(alert, animated: true)
    }
    
    private func setCurrencyPair(from: String, to: String) {
        if let fromIndex = currencies.firstIndex(where: { $0.0 == from }) {
            selectedFromCurrency = fromIndex
            fromCurrencyPickerView.selectRow(fromIndex, inComponent: 0, animated: true)
        }
        
        if let toIndex = currencies.firstIndex(where: { $0.0 == to }) {
            selectedToCurrency = toIndex
            toCurrencyPickerView.selectRow(toIndex, inComponent: 0, animated: true)
        }
        
        performConversion()
    }
    
    private func showAlert(title: String, message: String) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        present(alert, animated: true)
    }
}

// MARK: - UIPickerViewDelegate & UIPickerViewDataSource
extension CurrencyConverterViewController: UIPickerViewDelegate, UIPickerViewDataSource {
    
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return currencies.count
    }
    
    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        let label = UILabel()
        label.textAlignment = .center
        label.font = UIFont.systemFont(ofSize: 16, weight: .medium)
        
        let currency = currencies[row]
        label.text = "\(currency.2) \(currency.0) - \(currency.1)"
        
        return label
    }
    
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        if pickerView == fromCurrencyPickerView {
            selectedFromCurrency = row
        } else {
            selectedToCurrency = row
        }
        performConversion()
    }
}

// MARK: - Currency Data Model
struct Currency {
    let code: String
    let name: String
    let symbol: String
    
    init(code: String, name: String, symbol: String) {
        self.code = code
        self.name = name
        self.symbol = symbol
    }
}

// MARK: - Exchange Rate Service
class ExchangeRateService {
    
    static let shared = ExchangeRateService()
    
    private init() {}
    
    func fetchExchangeRates(base: String = "USD", completion: @escaping (Result<[String: Double], Error>) -> Void) {
        // In a real app, you would make an actual API call here
        // For demo purposes, we'll simulate with mock data
        
        DispatchQueue.global().asyncAfter(deadline: .now() + 1.0) {
            let mockRates: [String: Double] = [
                "USD": 1.0,
                "EUR": 0.92,
                "GBP": 0.79,
                "JPY": 149.50,
                "AUD": 1.53,
                "CAD": 1.36,
                "CHF": 0.88,
                "CNY": 7.24,
                "INR": 83.12,
                "KRW": 1318.50,
                "BRL": 4.97,
                "RUB": 89.75,
                "MXN": 17.15,
                "SGD": 1.35,
                "HKD": 7.82,
                "SEK": 10.75,
                "NOK": 10.85,
                "NZD": 1.67,
                "ZAR": 18.95,
                "TRY": 29.75
            ]
            
            DispatchQueue.main.async {
                completion(.success(mockRates))
            }
        }
    }
    
    func convert(amount: Double, from: String, to: String, rates: [String: Double]) -> Double? {
        guard let fromRate = rates[from],
              let toRate = rates[to] else {
            return nil
        }
        
        return amount * (toRate / fromRate)
    }
}
371 lines•13.3 KB
swift
CalculatorLogic.swift
Raw Download
Find: Go to:
//
//  CalculatorLogic.swift
//  Swift iOS Calculator
//
//  Created by RSK World on 23/01/2026.
//  Copyright © 2026 RSK World. All rights reserved.
//
//  Developer: Molla Samser (Founder, RSK World)
//  Designer & Tester: Rima Khatun
//  Contact: info@rskworld.com, +91 93305 39277
//  Website: https://rskworld.in
//  Address: Nutanhat, Mongolkote, Purba Burdwan, West Bengal, India - 713147
//

import Foundation

struct CalculatorLogic {
    
    // MARK: - Properties
    private var firstNumber: Double?
    private var secondNumber: Double?
    private var operation: String?
    private var intermediateResult: Double?
    private var memoryValue: Double = 0.0
    private var history: [String] = []
    
    // MARK: - Public Methods
    mutating func setNumber(_ number: String) {
        if let doubleValue = Double(number) {
            if operation == nil {
                firstNumber = doubleValue
            } else {
                secondNumber = doubleValue
            }
        }
    }
    
    mutating func calculate(symbol: String) -> Double? {
        if symbol == "=" {
            return performCalculation()
        } else {
            operation = symbol
            if let first = firstNumber {
                intermediateResult = first
            }
            return intermediateResult
        }
    }
    
    mutating func clear() {
        firstNumber = nil
        secondNumber = nil
        operation = nil
        intermediateResult = nil
    }
    
    mutating func clearAll() {
        clear()
        memoryValue = 0.0
        history.removeAll()
    }
    
    // MARK: - Memory Functions
    mutating func memoryClear() {
        memoryValue = 0.0
    }
    
    mutating func memoryRecall() -> Double? {
        return memoryValue
    }
    
    mutating func memoryAdd(_ number: Double) {
        memoryValue += number
    }
    
    mutating func memorySubtract(_ number: Double) {
        memoryValue -= number
    }
    
    mutating func memoryStore(_ number: Double) {
        memoryValue = number
    }
    
    // MARK: - History Functions
    mutating func addToHistory(_ calculation: String) {
        history.append(calculation)
        if history.count > 100 {
            history.removeFirst()
        }
    }
    
    func getHistory() -> [String] {
        return history
    }
    
    mutating func clearHistory() {
        history.removeAll()
    }
    
    // MARK: - Private Methods
    private func performCalculation() -> Double? {
        guard let first = firstNumber,
              let second = secondNumber,
              let op = operation else {
            return firstNumber
        }
        
        let result: Double
        
        switch op {
        case "+":
            result = first + second
        case "-":
            result = first - second
        case "×":
            result = first * second
        case "÷":
            if second == 0 {
                return nil // Division by zero
            }
            result = first / second
        default:
            return nil
        }
        
        // Update first number for chained calculations
        firstNumber = result
        secondNumber = nil
        operation = nil
        
        return result
    }
    
    // MARK: - Scientific Functions
    mutating func performScientificOperation(_ operation: String) -> Double? {
        guard let number = firstNumber else { return nil }
        
        let result: Double
        
        switch operation {
        case "sin":
            result = sin(number * .pi / 180) // Convert to radians
        case "cos":
            result = cos(number * .pi / 180)
        case "tan":
            result = tan(number * .pi / 180)
        case "√":
            result = sqrt(number)
        case "x²":
            result = number * number
        case "x³":
            result = number * number * number
        case "log":
            result = log10(number)
        case "ln":
            result = log(number)
        case "1/x":
            if number == 0 {
                return nil
            }
            result = 1 / number
        case "π":
            result = .pi
        case "e":
            result = .e
        default:
            return nil
        }
        
        firstNumber = result
        return result
    }
}
174 lines•4.4 KB
swift

About RSK World

Founded by Molla Samser, with Designer & Tester Rima Khatun, RSK World is your one-stop destination for free programming resources, source code, and development tools.

Founder: Molla Samser
Designer & Tester: Rima Khatun

Development

  • Game Development
  • Web Development
  • Mobile Development
  • AI Development
  • Development Tools

Legal

  • Terms & Conditions
  • Privacy Policy
  • Disclaimer

Contact Info

Nutanhat, Mongolkote
Purba Burdwan, West Bengal
India, 713147

+91 93305 39277

hello@rskworld.in
support@rskworld.in

© 2026 RSK World. All rights reserved.

Content used for educational purposes only. View Disclaimer