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
CalculatorWidget.swift
CalculatorWidget.swift
Raw Download
Find: Go to:
//
//  CalculatorWidget.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 WidgetKit
import SwiftUI

struct CalculatorWidgetEntry: TimelineEntry {
    let date: Date
    let displayValue: String
    let operation: String?
}

struct CalculatorWidgetProvider: TimelineProvider {
    
    func placeholder(in context: Context) -> CalculatorWidgetEntry {
        CalculatorWidgetEntry(date: Date(), displayValue: "0", operation: nil)
    }
    
    func getSnapshot(in context: Context, completion: @escaping (CalculatorWidgetEntry) -> Void) {
        let entry = CalculatorWidgetEntry(date: Date(), displayValue: "123.45", operation: "5 + 118.45")
        completion(entry)
    }
    
    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
        let currentDate = Date()
        let entry = CalculatorWidgetEntry(date: currentDate, displayValue: UserDefaults.shared.string(forKey: "WidgetDisplayValue") ?? "0", operation: UserDefaults.shared.string(forKey: "WidgetOperation"))
        
        let nextUpdate = Calendar.current.date(byAdding: .minute, value: 15, to: currentDate)!
        let timeline = Timeline(entries: [entry], policy: .after(nextUpdate))
        
        completion(timeline)
    }
}

struct CalculatorWidgetEntryView: View {
    var entry: CalculatorWidgetProvider.Entry
    
    var body: some View {
        VStack(spacing: 0) {
            // Display
            VStack {
                if let operation = entry.operation {
                    Text(operation)
                        .font(.caption)
                        .foregroundColor(.secondary)
                        .lineLimit(1)
                }
                
                Text(entry.displayValue)
                    .font(.system(size: 24, weight: .medium, design: .monospaced))
                    .foregroundColor(.primary)
                    .lineLimit(1)
            }
            .frame(height: 50)
            .frame(maxWidth: .infinity)
            .background(Color(.systemGray6))
            .cornerRadius(8)
            .padding(.horizontal, 8)
            .padding(.top, 8)
            
            // Quick Calculator Buttons
            VStack(spacing: 4) {
                HStack(spacing: 4) {
                    CalculatorButton(title: "7", action: "7")
                    CalculatorButton(title: "8", action: "8")
                    CalculatorButton(title: "9", action: "9")
                    CalculatorButton(title: "÷", action: "/", isOperation: true)
                }
                
                HStack(spacing: 4) {
                    CalculatorButton(title: "4", action: "4")
                    CalculatorButton(title: "5", action: "5")
                    CalculatorButton(title: "6", action: "6")
                    CalculatorButton(title: "×", action: "*", isOperation: true)
                }
                
                HStack(spacing: 4) {
                    CalculatorButton(title: "1", action: "1")
                    CalculatorButton(title: "2", action: "2")
                    CalculatorButton(title: "3", action: "3")
                    CalculatorButton(title: "-", action: "-", isOperation: true)
                }
                
                HStack(spacing: 4) {
                    CalculatorButton(title: "0", action: "0")
                    CalculatorButton(title: ".", action: ".")
                    CalculatorButton(title: "=", action: "=", isOperation: true)
                    CalculatorButton(title: "+", action: "+", isOperation: true)
                }
            }
            .padding(.horizontal, 8)
            .padding(.bottom, 8)
        }
        .background(Color(.systemBackground))
    }
}

struct CalculatorButton: View {
    let title: String
    let action: String
    let isOperation: Bool
    
    var body: some View {
        Text(title)
            .font(.system(size: 16, weight: .medium))
            .foregroundColor(isOperation ? .white : .primary)
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .background(isOperation ? Color.blue : Color(.systemGray5))
            .cornerRadius(8)
            .widgetURL(URL(string: "calculator://button/\(action)"))
    }
}

struct CalculatorWidget: Widget {
    let kind: String = "CalculatorWidget"
    
    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: CalculatorWidgetProvider()) { entry in
            CalculatorWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("Quick Calculator")
        .description("Perform quick calculations right from your home screen")
        .supportedFamilies([.systemMedium, .systemLarge])
    }
}

// MARK: - Widget Extension Entry Point
@main
struct CalculatorWidgetBundle: WidgetBundle {
    var body: some Widget {
        CalculatorWidget()
        CurrencyWidget()
        UnitConverterWidget()
    }
}

// MARK: - Currency Widget
struct CurrencyWidgetEntry: TimelineEntry {
    let date: Date
    let fromCurrency: String
    let toCurrency: String
    let exchangeRate: Double
    let lastUpdated: Date
}

struct CurrencyWidgetProvider: TimelineProvider {
    
    func placeholder(in context: Context) -> CurrencyWidgetEntry {
        CurrencyWidgetEntry(date: Date(), fromCurrency: "USD", toCurrency: "EUR", exchangeRate: 0.92, lastUpdated: Date())
    }
    
    func getSnapshot(in context: Context, completion: @escaping (CurrencyWidgetEntry) -> Void) {
        let entry = CurrencyWidgetEntry(date: Date(), fromCurrency: "USD", toCurrency: "EUR", exchangeRate: 0.92, lastUpdated: Date())
        completion(entry)
    }
    
    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
        let currentDate = Date()
        
        // Get saved preferences or use defaults
        let fromCurrency = UserDefaults.shared.string(forKey: "WidgetFromCurrency") ?? "USD"
        let toCurrency = UserDefaults.shared.string(forKey: "WidgetToCurrency") ?? "EUR"
        
        // Simulate API call - in real app, fetch from actual API
        let exchangeRates: [String: Double] = [
            "USD": 1.0,
            "EUR": 0.92,
            "GBP": 0.79,
            "JPY": 149.50,
            "AUD": 1.53,
            "CAD": 1.36
        ]
        
        let rate = exchangeRates[toCurrency] ?? 1.0
        let entry = CurrencyWidgetEntry(date: currentDate, fromCurrency: fromCurrency, toCurrency: toCurrency, exchangeRate: rate, lastUpdated: currentDate)
        
        let nextUpdate = Calendar.current.date(byAdding: .hour, value: 1, to: currentDate)!
        let timeline = Timeline(entries: [entry], policy: .after(nextUpdate))
        
        completion(timeline)
    }
}

struct CurrencyWidgetEntryView: View {
    var entry: CurrencyWidgetProvider.Entry
    
    var body: some View {
        VStack(spacing: 12) {
            HStack {
                VStack(alignment: .leading) {
                    Text("Currency Converter")
                        .font(.headline)
                        .foregroundColor(.primary)
                    
                    Text("Updated \(entry.lastUpdated, style: .time)")
                        .font(.caption)
                        .foregroundColor(.secondary)
                }
                
                Spacer()
                
                Image(systemName: "dollarsign.circle.fill")
                    .font(.title2)
                    .foregroundColor(.green)
            }
            
            VStack(spacing: 8) {
                HStack {
                    Text(entry.fromCurrency)
                        .font(.title2)
                        .fontWeight(.bold)
                    
                    Spacer()
                    
                    Text("1")
                        .font(.title2)
                        .foregroundColor(.secondary)
                }
                
                HStack {
                    Text(entry.toCurrency)
                        .font(.title2)
                        .fontWeight(.bold)
                    
                    Spacer()
                    
                    Text(String(format: "%.4f", entry.exchangeRate))
                        .font(.title2)
                        .foregroundColor(.blue)
                }
            }
            .padding()
            .background(Color(.systemGray6))
            .cornerRadius(12)
            
            Button("Open Converter") {
                // Deep link to currency converter
            }
            .buttonStyle(.borderedProminent)
            .widgetURL(URL(string: "calculator://currency"))
        }
        .padding()
    }
}

struct CurrencyWidget: Widget {
    let kind: String = "CurrencyWidget"
    
    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: CurrencyWidgetProvider()) { entry in
            CurrencyWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("Currency Exchange")
        .description("Quick currency conversion widget")
        .supportedFamilies([.systemMedium])
    }
}

// MARK: - Unit Converter Widget
struct UnitConverterWidgetEntry: TimelineEntry {
    let date: Date
    let category: String
    let fromValue: Double
    let fromUnit: String
    let toValue: Double
    let toUnit: String
}

struct UnitConverterWidgetProvider: TimelineProvider {
    
    func placeholder(in context: Context) -> UnitConverterWidgetEntry {
        UnitConverterWidgetEntry(date: Date(), category: "Length", fromValue: 1.0, fromUnit: "Meter", toValue: 3.281, toUnit: "Foot")
    }
    
    func getSnapshot(in context: Context, completion: @escaping (UnitConverterWidgetEntry) -> Void) {
        let entry = UnitConverterWidgetEntry(date: Date(), category: "Length", fromValue: 1.0, fromUnit: "Meter", toValue: 3.281, toUnit: "Foot")
        completion(entry)
    }
    
    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
        let currentDate = Date()
        
        // Get saved preferences or use defaults
        let category = UserDefaults.shared.string(forKey: "WidgetUnitCategory") ?? "Length"
        let fromValue = UserDefaults.shared.double(forKey: "WidgetFromValue") ?? 1.0
        
        // Perform conversion
        let (toValue, fromUnit, toUnit) = performUnitConversion(category: category, value: fromValue)
        
        let entry = UnitConverterWidgetEntry(date: currentDate, category: category, fromValue: fromValue, fromUnit: fromUnit, toValue: toValue, toUnit: toUnit)
        
        let nextUpdate = Calendar.current.date(byAdding: .minute, value: 30, to: currentDate)!
        let timeline = Timeline(entries: [entry], policy: .after(nextUpdate))
        
        completion(timeline)
    }
    
    private func performUnitConversion(category: String, value: Double) -> (Double, String, String) {
        switch category {
        case "Length":
            return (value * 3.28084, "Meter", "Foot")
        case "Weight":
            return (value * 2.20462, "Kilogram", "Pound")
        case "Temperature":
            return (value * 9/5 + 32, "Celsius", "Fahrenheit")
        default:
            return (value, "Unit", "Unit")
        }
    }
}

struct UnitConverterWidgetEntryView: View {
    var entry: UnitConverterWidgetProvider.Entry
    
    var body: some View {
        VStack(spacing: 12) {
            HStack {
                VStack(alignment: .leading) {
                    Text("\(entry.category) Converter")
                        .font(.headline)
                        .foregroundColor(.primary)
                    
                    Text("Quick conversion")
                        .font(.caption)
                        .foregroundColor(.secondary)
                }
                
                Spacer()
                
                Image(systemName: "ruler.fill")
                    .font(.title2)
                    .foregroundColor(.orange)
            }
            
            VStack(spacing: 8) {
                HStack {
                    Text(entry.fromUnit)
                        .font(.subheadline)
                        .foregroundColor(.secondary)
                    
                    Spacer()
                    
                    Text(String(format: "%.2f", entry.fromValue))
                        .font(.title3)
                        .fontWeight(.medium)
                }
                
                Divider()
                
                HStack {
                    Text(entry.toUnit)
                        .font(.subheadline)
                        .foregroundColor(.secondary)
                    
                    Spacer()
                    
                    Text(String(format: "%.2f", entry.toValue))
                        .font(.title3)
                        .fontWeight(.medium)
                        .foregroundColor(.blue)
                }
            }
            .padding()
            .background(Color(.systemGray6))
            .cornerRadius(12)
            
            Button("Open Converter") {
                // Deep link to unit converter
            }
            .buttonStyle(.bordered)
            .widgetURL(URL(string: "calculator://units"))
        }
        .padding()
    }
}

struct UnitConverterWidget: Widget {
    let kind: String = "UnitConverterWidget"
    
    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: UnitConverterWidgetProvider()) { entry in
            UnitConverterWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("Unit Converter")
        .description("Quick unit conversion widget")
        .supportedFamilies([.systemMedium])
    }
}

// MARK: - UserDefaults Extension
extension UserDefaults {
    static let shared = UserDefaults(suiteName: "group.com.rskworld.calculator") ?? UserDefaults.standard
}
405 lines•14.3 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