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
  • Blog
  • 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
AIMathSolverViewController.swift
AIMathSolverViewController.swift
Raw Download
Find: Go to:
//
//  AIMathSolverViewController.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
import NaturalLanguage

class AIMathSolverViewController: UIViewController {
    
    // MARK: - Outlets
    @IBOutlet weak var problemTextView: UITextView!
    @IBOutlet weak var solveButton: UIButton!
    @IBOutlet weak var solutionTextView: UITextView!
    @IBOutlet weak var stepsTableView: UITableView!
    @IBOutlet weak var categorySegmentedControl: UISegmentedControl!
    @IBOutlet weak var difficultySegmentedControl: UISegmentedControl!
    @IBOutlet weak var activityIndicator: UIActivityIndicatorView!
    @IBOutlet weak var progressLabel: UILabel!
    
    // MARK: - Properties
    private var solutionSteps: [SolutionStep] = []
    private var currentProblem: String = ""
    private var aiService = AIMathService()
    
    struct SolutionStep {
        let stepNumber: Int
        let description: String
        let formula: String?
        let result: String?
        let explanation: String
    }
    
    enum ProblemCategory: String, CaseIterable {
        case algebra = "Algebra"
        case calculus = "Calculus"
        case trigonometry = "Trigonometry"
        case geometry = "Geometry"
        case statistics = "Statistics"
        case physics = "Physics"
        
        var icon: String {
            switch self {
            case .algebra: return "x.squareroot"
            case .calculus: return "integral"
            case .trigonometry: return "triangle"
            case .geometry: return "circle"
            case .statistics: return "chart.bar"
            case .physics: return "atom"
            }
        }
    }
    
    enum Difficulty: String, CaseIterable {
        case easy = "Easy"
        case medium = "Medium"
        case hard = "Hard"
        case expert = "Expert"
    }
    
    // MARK: - Lifecycle
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        setupTableView()
        setupSegmentedControls()
    }
    
    // MARK: - Setup
    private func setupUI() {
        title = "AI Math Solver"
        view.backgroundColor = CalculatorTheme.shared.backgroundColor
        
        // Setup problem input
        problemTextView.backgroundColor = CalculatorTheme.shared.displayBackgroundColor
        problemTextView.textColor = CalculatorTheme.shared.textColor
        problemTextView.layer.cornerRadius = 12
        problemTextView.layer.borderWidth = 2
        problemTextView.layer.borderColor = CalculatorTheme.shared.buttonBackgroundColor.cgColor
        problemTextView.font = UIFont.systemFont(ofSize: 16)
        problemTextView.placeholder = "Enter your math problem here...\n\nExamples:\n• Solve x² + 5x + 6 = 0\n• Find derivative of sin(x²)\n• Calculate ∫(2x + 3)dx\n• Solve triangle with angles 30°, 60°, 90°"
        
        // Setup solution display
        solutionTextView.backgroundColor = CalculatorTheme.shared.displayBackgroundColor
        solutionTextView.textColor = CalculatorTheme.shared.textColor
        solutionTextView.layer.cornerRadius = 12
        solutionTextView.layer.borderWidth = 2
        solutionTextView.layer.borderColor = CalculatorTheme.shared.accentColor.cgColor
        solutionTextView.font = UIFont.systemFont(ofSize: 16, weight: .medium)
        solutionTextView.isEditable = false
        
        // Setup buttons
        solveButton.backgroundColor = CalculatorTheme.shared.accentColor
        solveButton.setTitleColor(.white, for: .normal)
        solveButton.layer.cornerRadius = 25
        solveButton.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .semibold)
        
        // Setup activity indicator
        activityIndicator.color = CalculatorTheme.shared.accentColor
        activityIndicator.hidesWhenStopped = true
        
        // Setup progress label
        progressLabel.textColor = CalculatorTheme.shared.textColor
        progressLabel.textAlignment = .center
        progressLabel.font = UIFont.systemFont(ofSize: 14)
        progressLabel.isHidden = true
    }
    
    private func setupTableView() {
        stepsTableView.delegate = self
        stepsTableView.dataSource = self
        stepsTableView.backgroundColor = CalculatorTheme.shared.backgroundColor
        stepsTableView.layer.cornerRadius = 12
        stepsTableView.separatorStyle = .none
        
        // Register custom cell
        stepsTableView.register(UINib(nibName: "SolutionStepCell", bundle: nil), forCellReuseIdentifier: "SolutionStepCell")
    }
    
    private func setupSegmentedControls() {
        // Category control
        categorySegmentedControl.removeAllSegments()
        for (index, category) in ProblemCategory.allCases.enumerated() {
            categorySegmentedControl.insertSegment(withTitle: category.rawValue, at: index, animated: false)
        }
        categorySegmentedControl.selectedSegmentIndex = 0
        categorySegmentedControl.backgroundColor = CalculatorTheme.shared.buttonBackgroundColor
        categorySegmentedControl.selectedSegmentTintColor = CalculatorTheme.shared.accentColor
        categorySegmentedControl.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: CalculatorTheme.shared.textColor], for: .normal)
        categorySegmentedControl.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white], for: .selected)
        
        // Difficulty control
        difficultySegmentedControl.removeAllSegments()
        for (index, difficulty) in Difficulty.allCases.enumerated() {
            difficultySegmentedControl.insertSegment(withTitle: difficulty.rawValue, at: index, animated: false)
        }
        difficultySegmentedControl.selectedSegmentIndex = 1
        difficultySegmentedControl.backgroundColor = CalculatorTheme.shared.buttonBackgroundColor
        difficultySegmentedControl.selectedSegmentTintColor = CalculatorTheme.shared.accentColor
        difficultySegmentedControl.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: CalculatorTheme.shared.textColor], for: .normal)
        difficultySegmentedControl.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white], for: .selected)
    }
    
    // MARK: - Actions
    @IBAction func solveButtonPressed(_ sender: UIButton) {
        guard let problem = problemTextView.text, !problem.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else {
            showAlert(title: "Error", message: "Please enter a math problem to solve")
            return
        }
        
        currentProblem = problem
        solveProblem(problem)
    }
    
    @IBAction func categoryChanged(_ sender: UISegmentedControl) {
        updatePlaceholderForCategory()
    }
    
    @IBAction func difficultyChanged(_ sender: UISegmentedControl) {
        // Adjust AI response complexity based on difficulty
    }
    
    @IBAction func cameraButtonPressed(_ sender: UIButton) {
        // Open camera to scan math problem
        presentCameraScanner()
    }
    
    @IBAction func voiceButtonPressed(_ sender: UIButton) {
        // Voice input for math problems
        presentVoiceInput()
    }
    
    @IBAction func historyButtonPressed(_ sender: UIButton) {
        // Show solved problems history
        presentProblemHistory()
    }
    
    // MARK: - Methods
    private func solveProblem(_ problem: String) {
        showLoading(true)
        
        let category = ProblemCategory.allCases[categorySegmentedControl.selectedSegmentIndex]
        let difficulty = Difficulty.allCases[difficultySegmentedControl.selectedSegmentIndex]
        
        aiService.solveProblem(problem, category: category, difficulty: difficulty) { [weak self] result in
            DispatchQueue.main.async {
                self?.showLoading(false)
                
                switch result {
                case .success((let solution, let steps)):
                    self?.displaySolution(solution, steps: steps)
                case .failure(let error):
                    self?.showError(error)
                }
            }
        }
    }
    
    private func displaySolution(_ solution: String, steps: [SolutionStep]) {
        solutionTextView.text = solution
        solutionSteps = steps
        stepsTableView.reloadData()
        
        // Animate solution appearance
        solutionTextView.alpha = 0
        stepsTableView.alpha = 0
        
        UIView.animate(withDuration: 0.5) {
            self.solutionTextView.alpha = 1
            self.stepsTableView.alpha = 1
        }
        
        // Save to history
        saveToHistory(problem: currentProblem, solution: solution)
    }
    
    private func showLoading(_ show: Bool) {
        if show {
            activityIndicator.startAnimating()
            progressLabel.isHidden = false
            progressLabel.text = "Analyzing problem..."
            solveButton.isEnabled = false
        } else {
            activityIndicator.stopAnimating()
            progressLabel.isHidden = true
            solveButton.isEnabled = true
        }
    }
    
    private func updatePlaceholderForCategory() {
        let category = ProblemCategory.allCases[categorySegmentedControl.selectedSegmentIndex]
        
        switch category {
        case .algebra:
            problemTextView.placeholder = "Enter algebra problem...\n\nExamples:\n• Solve x² + 5x + 6 = 0\n• Factor 2x² - 8x + 6\n• Find x in 3x + 7 = 22"
        case .calculus:
            problemTextView.placeholder = "Enter calculus problem...\n\nExamples:\n• Find derivative of sin(x²)\n• Calculate ∫(2x + 3)dx\n• Find limit of (x²-1)/(x-1) as x→1"
        case .trigonometry:
            problemTextView.placeholder = "Enter trigonometry problem...\n\nExamples:\n• Solve sin(x) = 0.5\n• Find cos(45°)\n• Prove identity: sin²(x) + cos²(x) = 1"
        case .geometry:
            problemTextView.placeholder = "Enter geometry problem...\n\nExamples:\n• Find area of circle with radius 5\n• Calculate volume of sphere with radius 3\n• Find hypotenuse of right triangle with legs 3,4"
        case .statistics:
            problemTextView.placeholder = "Enter statistics problem...\n\nExamples:\n• Find mean of 2,4,6,8,10\n• Calculate standard deviation\n• Find probability of drawing red card"
        case .physics:
            problemTextView.placeholder = "Enter physics problem...\n\nExamples:\n• Calculate force: F = ma\n• Find kinetic energy: KE = ½mv²\n• Solve for time: d = vt + ½at²"
        }
    }
    
    private func presentCameraScanner() {
        let scanner = MathProblemScannerViewController()
        scanner.delegate = self
        let navController = UINavigationController(rootViewController: scanner)
        present(navController, animated: true)
    }
    
    private func presentVoiceInput() {
        let voiceInput = VoiceInputViewController()
        voiceInput.delegate = self
        let navController = UINavigationController(rootViewController: voiceInput)
        present(navController, animated: true)
    }
    
    private func presentProblemHistory() {
        let history = ProblemHistoryViewController()
        let navController = UINavigationController(rootViewController: history)
        present(navController, animated: true)
    }
    
    private func saveToHistory(problem: String, solution: String) {
        let historyItem = ProblemHistoryItem(
            problem: problem,
            solution: solution,
            category: ProblemCategory.allCases[categorySegmentedControl.selectedSegmentIndex].rawValue,
            difficulty: Difficulty.allCases[difficultySegmentedControl.selectedSegmentIndex].rawValue,
            date: Date()
        )
        
        ProblemHistoryManager.shared.addHistoryItem(historyItem)
    }
    
    private func showError(_ error: Error) {
        showAlert(title: "Error", message: "Failed to solve problem: \(error.localizedDescription)")
    }
    
    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: - UITableViewDataSource & UITableViewDelegate
extension AIMathSolverViewController: UITableViewDataSource, UITableViewDelegate {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return solutionSteps.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "SolutionStepCell", for: indexPath) as! SolutionStepCell
        let step = solutionSteps[indexPath.row]
        cell.configure(with: step)
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
    
    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return 100
    }
}

// MARK: - Math Problem Scanner Delegate
extension AIMathSolverViewController: MathProblemScannerDelegate {
    func didScanProblem(_ problem: String) {
        problemTextView.text = problem
        solveProblem(problem)
    }
}

// MARK: - Voice Input Delegate
extension AIMathSolverViewController: VoiceInputDelegate {
    func didReceiveVoiceInput(_ text: String) {
        problemTextView.text = text
        solveProblem(text)
    }
}

// MARK: - AI Math Service
class AIMathService {
    
    func solveProblem(_ problem: String, category: AIMathSolverViewController.ProblemCategory, difficulty: AIMathSolverViewController.Difficulty, completion: @escaping (Result<(String, [AIMathSolverViewController.SolutionStep]), Error>) -> Void) {
        
        // Simulate AI processing
        DispatchQueue.global().asyncAfter(deadline: .now() + 2.0) {
            do {
                let (solution, steps) = try self.generateSolution(for: problem, category: category, difficulty: difficulty)
                DispatchQueue.main.async {
                    completion(.success((solution, steps)))
                }
            } catch {
                DispatchQueue.main.async {
                    completion(.failure(error))
                }
            }
        }
    }
    
    private func generateSolution(for problem: String, category: AIMathSolverViewController.ProblemCategory, difficulty: AIMathSolverViewController.Difficulty) throws -> (String, [AIMathSolverViewController.SolutionStep]) {
        
        // Simulate AI-based solution generation
        // In a real app, this would call an actual AI service
        
        switch category {
        case .algebra:
            return generateAlgebraSolution(problem, difficulty: difficulty)
        case .calculus:
            return generateCalculusSolution(problem, difficulty: difficulty)
        case .trigonometry:
            return generateTrigonometrySolution(problem, difficulty: difficulty)
        case .geometry:
            return generateGeometrySolution(problem, difficulty: difficulty)
        case .statistics:
            return generateStatisticsSolution(problem, difficulty: difficulty)
        case .physics:
            return generatePhysicsSolution(problem, difficulty: difficulty)
        }
    }
    
    private func generateAlgebraSolution(_ problem: String, difficulty: AIMathSolverViewController.Difficulty) -> (String, [AIMathSolverViewController.SolutionStep]) {
        var steps: [AIMathSolverViewController.SolutionStep] = []
        
        if problem.contains("x²") && problem.contains("=") {
            // Quadratic equation
            steps.append(AIMathSolverViewController.SolutionStep(
                stepNumber: 1,
                description: "Identify the quadratic equation in standard form",
                formula: "ax² + bx + c = 0",
                result: "x² + 5x + 6 = 0",
                explanation: "The equation is already in standard form where a=1, b=5, c=6"
            ))
            
            steps.append(AIMathSolverViewController.SolutionStep(
                stepNumber: 2,
                description: "Apply the quadratic formula",
                formula: "x = (-b ± √(b² - 4ac)) / 2a",
                result: "x = (-5 ± √(25 - 24)) / 2",
                explanation: "Substitute the values of a, b, and c into the quadratic formula"
            ))
            
            steps.append(AIMathSolverViewController.SolutionStep(
                stepNumber: 3,
                description: "Calculate the discriminant",
                formula: "Δ = b² - 4ac",
                result: "Δ = 25 - 24 = 1",
                explanation: "The discriminant is positive, so there are two real solutions"
            ))
            
            steps.append(AIMathSolverViewController.SolutionStep(
                stepNumber: 4,
                description: "Find the solutions",
                formula: "x = (-5 ± √1) / 2",
                result: "x₁ = -2, x₂ = -3",
                explanation: "The quadratic equation has two solutions: x = -2 and x = -3"
            ))
            
            let solution = "The equation x² + 5x + 6 = 0 has two solutions:\n\nx₁ = -2\nx₂ = -3\n\nVerification:\n• For x = -2: (-2)² + 5(-2) + 6 = 4 - 10 + 6 = 0 ✓\n• For x = -3: (-3)² + 5(-3) + 6 = 9 - 15 + 6 = 0 ✓"
            
            return (solution, steps)
        }
        
        // Default algebra solution
        steps.append(AIMathSolverViewController.SolutionStep(
            stepNumber: 1,
            description: "Analyze the algebraic expression",
            formula: problem,
            result: "Simplified form",
            explanation: "Apply algebraic rules to simplify the expression"
        ))
        
        return ("Solution completed", steps)
    }
    
    private func generateCalculusSolution(_ problem: String, difficulty: AIMathSolverViewController.Difficulty) -> (String, [AIMathSolverViewController.SolutionStep]) {
        var steps: [AIMathSolverViewController.SolutionStep] = []
        
        if problem.contains("derivative") && problem.contains("sin") {
            steps.append(AIMathSolverViewController.SolutionStep(
                stepNumber: 1,
                description: "Identify the function to differentiate",
                formula: "f(x) = sin(x²)",
                result: "f(x) = sin(x²)",
                explanation: "We need to find the derivative of sin(x²)"
            ))
            
            steps.append(AIMathSolverViewController.SolutionStep(
                stepNumber: 2,
                description: "Apply the chain rule",
                formula: "d/dx[f(g(x))] = f'(g(x)) · g'(x)",
                result: "f'(x) = cos(x²) · 2x",
                explanation: "Using chain rule: derivative of sin(u) is cos(u)·u'"
            ))
            
            steps.append(AIMathSolverViewController.SolutionStep(
                stepNumber: 3,
                description: "Simplify the result",
                formula: "f'(x) = 2x · cos(x²)",
                result: "f'(x) = 2x cos(x²)",
                explanation: "The derivative is 2x cos(x²)"
            ))
            
            let solution = "The derivative of sin(x²) is 2x cos(x²)\n\nSteps:\n1. Apply chain rule: d/dx[sin(u)] = cos(u) · du/dx\n2. Let u = x², so du/dx = 2x\n3. Therefore: d/dx[sin(x²)] = cos(x²) · 2x = 2x cos(x²)"
            
            return (solution, steps)
        }
        
        return ("Calculus solution generated", steps)
    }
    
    private func generateTrigonometrySolution(_ problem: String, difficulty: AIMathSolverViewController.Difficulty) -> (String, [AIMathSolverViewController.SolutionStep]) {
        var steps: [AIMathSolverViewController.SolutionStep] = []
        
        steps.append(AIMathSolverViewController.SolutionStep(
            stepNumber: 1,
            description: "Identify the trigonometric relationship",
            formula: problem,
            result: "Trigonometric identity",
            explanation: "Apply trigonometric identities and formulas"
        ))
        
        return ("Trigonometry solution completed", steps)
    }
    
    private func generateGeometrySolution(_ problem: String, difficulty: AIMathSolverViewController.Difficulty) -> (String, [AIMathSolverViewController.SolutionStep]) {
        var steps: [AIMathSolverViewController.SolutionStep] = []
        
        steps.append(AIMathSolverViewController.SolutionStep(
            stepNumber: 1,
            description: "Identify geometric shapes and formulas",
            formula: problem,
            result: "Geometric calculation",
            explanation: "Apply geometric formulas and theorems"
        ))
        
        return ("Geometry solution completed", steps)
    }
    
    private func generateStatisticsSolution(_ problem: String, difficulty: AIMathSolverViewController.Difficulty) -> (String, [AIMathSolverViewController.SolutionStep]) {
        var steps: [AIMathSolverViewController.SolutionStep] = []
        
        steps.append(AIMathSolverViewController.SolutionStep(
            stepNumber: 1,
            description: "Identify statistical measures needed",
            formula: problem,
            result: "Statistical analysis",
            explanation: "Apply statistical formulas and methods"
        ))
        
        return ("Statistics solution completed", steps)
    }
    
    private func generatePhysicsSolution(_ problem: String, difficulty: AIMathSolverViewController.Difficulty) -> (String, [AIMathSolverViewController.SolutionStep]) {
        var steps: [AIMathSolverViewController.SolutionStep] = []
        
        steps.append(AIMathSolverViewController.SolutionStep(
            stepNumber: 1,
            description: "Identify physics principles and formulas",
            formula: problem,
            result: "Physics calculation",
            explanation: "Apply physics laws and equations"
        ))
        
        return ("Physics solution completed", steps)
    }
}

// MARK: - Supporting Classes
class SolutionStepCell: UITableViewCell {
    
    @IBOutlet weak var stepNumberLabel: UILabel!
    @IBOutlet weak var descriptionLabel: UILabel!
    @IBOutlet weak var formulaLabel: UILabel!
    @IBOutlet weak var resultLabel: UILabel!
    @IBOutlet weak var explanationLabel: UILabel!
    
    func configure(with step: AIMathSolverViewController.SolutionStep) {
        stepNumberLabel.text = "Step \(step.stepNumber)"
        descriptionLabel.text = step.description
        formulaLabel.text = step.formula
        resultLabel.text = step.result
        explanationLabel.text = step.explanation
        
        // Apply theme
        backgroundColor = CalculatorTheme.shared.backgroundColor
        stepNumberLabel.textColor = CalculatorTheme.shared.accentColor
        descriptionLabel.textColor = CalculatorTheme.shared.textColor
        formulaLabel.textColor = CalculatorTheme.shared.textColor
        resultLabel.textColor = CalculatorTheme.shared.accentColor
        explanationLabel.textColor = CalculatorTheme.shared.textColor.withAlphaComponent(0.8)
    }
}

struct ProblemHistoryItem {
    let problem: String
    let solution: String
    let category: String
    let difficulty: String
    let date: Date
}

class ProblemHistoryManager {
    static let shared = ProblemHistoryManager()
    
    private var historyItems: [ProblemHistoryItem] = []
    
    func addHistoryItem(_ item: ProblemHistoryItem) {
        historyItems.append(item)
        
        // Keep only last 100 items
        if historyItems.count > 100 {
            historyItems.removeFirst(historyItems.count - 100)
        }
        
        // Save to UserDefaults
        saveToUserDefaults()
    }
    
    func getHistoryItems() -> [ProblemHistoryItem] {
        return historyItems
    }
    
    private func saveToUserDefaults() {
        let encoder = JSONEncoder()
        if let encoded = try? encoder.encode(historyItems) {
            UserDefaults.standard.set(encoded, forKey: "ProblemHistory")
        }
    }
    
    private func loadFromUserDefaults() {
        if let data = UserDefaults.standard.data(forKey: "ProblemHistory") {
            let decoder = JSONDecoder()
            if let decoded = try? decoder.decode([ProblemHistoryItem].self, from: data) {
                historyItems = decoded
            }
        }
    }
}

// MARK: - Placeholder Protocols
protocol MathProblemScannerDelegate: AnyObject {
    func didScanProblem(_ problem: String)
}

protocol VoiceInputDelegate: AnyObject {
    func didReceiveVoiceInput(_ text: String)
}

// Placeholder view controllers
class MathProblemScannerViewController: UIViewController {
    weak var delegate: MathProblemScannerDelegate?
}

class VoiceInputViewController: UIViewController {
    weak var delegate: VoiceInputDelegate?
}

class ProblemHistoryViewController: UIViewController {
    
}

// MARK: - UITextView Extension for Placeholder
extension UITextView {
    var placeholder: String? {
        get {
            return self.placeholderLabel?.text
        }
        set {
            if let placeholder = newValue {
                if placeholderLabel == nil {
                    placeholderLabel = UILabel()
                    placeholderLabel?.textColor = UIColor.placeholderText
                    placeholderLabel?.font = self.font
                    placeholderLabel?.textAlignment = .left
                    placeholderLabel?.numberOfLines = 0
                    addSubview(placeholderLabel!)
                }
                placeholderLabel?.text = placeholder
                placeholderLabel?.sizeToFit()
            } else {
                placeholderLabel?.removeFromSuperview()
                placeholderLabel = nil
            }
        }
    }
    
    private var placeholderLabel: UILabel?
    
    override var text: String! {
        didSet {
            placeholderLabel?.isHidden = !text.isEmpty
        }
    }
}
655 lines•26.6 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