β Star this repo if you find SwiftOBD2 useful! Your support helps the project grow and reach more developers.
SwiftOBD2 is a Swift package designed to simplify communication with vehicles using an ELM327 OBD2 adapter. It provides a straightforward and powerful interface for interacting with your vehicle's onboard diagnostics system, allowing you to retrieve real-time data and perform diagnostics. Sample App.
Demo coming soon! We're preparing a comprehensive demo video showcasing real-time vehicle data retrieval, DTC scanning, and more.
- Real-time RPM, Speed, and Engine Load monitoring
- Diagnostic Trouble Code (DTC) scanning and clearing
- Live sensor data visualization
- Bluetooth connection management
Screenshots and demo GIF will be added in the next release
Get up and running in 2 minutes:
// 1. Add to your project via Swift Package Manager
// File > Add Packages... > https://github.com/kkonteh97/SwiftOBD2
// 2. Import and connect
import SwiftOBD2
let obdService = OBDService(connectionType: .bluetooth)
let obd2Info = try await obdService.startConnection()
// 3. Get real-time data
obdService.startContinuousUpdates([.mode1(.rpm), .mode1(.speed)])
.sink { measurements in
print("RPM: \(measurements[.mode1(.rpm)]?.value ?? 0)")
print("Speed: \(measurements[.mode1(.speed)]?.value ?? 0)")
}Expected Output:
RPM: 2150.0
Speed: 65.0
- iOS 14.0+ / macOS 11.0+
- Xcode 13.0+
- Swift 5.0+
-
Connection Management:
- Establishes connections to the OBD2 adapter via Bluetooth or Wi-Fi.
- Handles the initialization of the adapter and the vehicle connection process.
- Manages connection states (disconnected, connectedToAdapter, connectedToVehicle).
-
Command Interface:
- Send and receive OBD2 commands for powerful interaction with your vehicle.
-
Data Retrieval:
- Supports requests for real-time vehicle data (RPM, speed, etc.) using standard OBD2 PIDs (Parameter IDs).
- Provides functions to continuously poll and retrieve updated measurements.
- Can get a list of supported PIDs from the vehicle.
-
Diagnostics:
- Retrieves and clears diagnostic trouble codes (DTCs).
- Gets the overall status of the vehicle's onboard systems.
-
Sensor Monitoring:
- Retrieve and view data from various vehicle sensors in real time.
-
Adaptability and Configuration
- Can switch between Bluetooth and Wi-Fi communication seamlessly.
- Allows for testing and development with a demo mode.
- Connect to an OBD2 adapter via Bluetooth Low Energy (BLE)
- Retrieve error codes (DTCs) stored in the vehicle's OBD2 system
- Retrieve various OBD2 Parameter IDs (PIDs) for monitoring vehicle parameters
- Retrieve real-time vehicle data (RPM, speed, etc.) using standard OBD2 PIDs
- Get supported PIDs from the vehicle
- Clear error codes (DTCs) stored in the vehicle's OBD2 system
- Run tests on the OBD2 system
- Retrieve vehicle status since DTCs cleared
- Connect to an OBD2 adapter via WIFI
- Add support for custom PIDs
-
Create a New Swift Project:
- Open Xcode and start a new iOS project (You can use a simple "App" template).
-
Add the SwiftOBD2 Package:
- In Xcode, navigate to File > Add Packages...
- Enter this repository's URL: https://github.com/kkonteh97/SwiftOBD2/
- Select the desired dependency rule (version, branch, or commit).
-
Permissions and Capabilities:
- If your app will use Bluetooth, you need to request the appropriate permissions and capabilities:
- Add NSBluetoothAlwaysUsageDescription to your Info.plist file with a brief description of why your app needs to use Bluetooth.
- Navigate to the Signing & Capabilities tab in your project settings and add the Background Modes capability. Enable the Uses Bluetooth LE Accessories option.
- If your app will use Bluetooth, you need to request the appropriate permissions and capabilities:
- SwiftUI & Combine: Your code leverages the SwiftUI framework for building the user interface and Combine for reactive handling of updates from the OBDService.
- OBDService: This is the core class within the SwiftOBD2 package. It handles communication with the OBD-II adapter and processes data from the vehicle.
- OBDServiceDelegate: This protocol is crucial for receiving updates about the connection state and other events from the OBDService.
- OBDCommand: These represent specific requests you can make to the vehicle's ECU (Engine Control Unit) for data.
- Import and Setup
- Begin by importing the necessary modules:
import SwiftUI
import SwiftOBD2
import Combine-
ViewModel
- Create a ViewModel class that conforms to the ObservableObject protocol. This allows your SwiftUI views to observe changes in the ViewModel.
- Inside the ViewModel:
- Define a @Published property measurements to store the collected data.
- Initialize an OBDService instance, setting the desired connection type (e.g., Bluetooth, Wi-Fi).
-
Connection Handling
- Implement the connectionStateChanged method from the OBDServiceDelegate protocol. Update the UI based on connection state changes (disconnected, connected, etc.) or handle any necessary logic.
-
Starting the Connection
- Create a startConnection function (ideally using async/await) to initiate the connection process with the OBD-II adapter. The OBDService's startConnection method will return useful OBDInfo about the vehicle. Like the Supported PIDs, Protocol, etc.
-
Stopping the Connection
- Create a stopConnection function to cleanly disconnect the service.
-
Retrieving Information
- Use the OBDService's methods to retrieve data from the vehicle, such as getting the vehicle's status, scanning for trouble codes, or requesting specific PIDs.
- getTroubleCodes: Retrieve diagnostic trouble codes (DTCs) from the vehicle's OBD-II system.
- getStatus: Retrieves Status since DTCs cleared.
- Use the OBDService's methods to retrieve data from the vehicle, such as getting the vehicle's status, scanning for trouble codes, or requesting specific PIDs.
-
Continuous Updates
- Use the startContinuousUpdates method to continuously poll and retrieve updated measurements from the vehicle. This method returns a Combine publisher that you can subscribe to for updates.
- Can also add PIDs to the continuous updates using the addPID method.
class ViewModel: ObservableObject {
@Published var measurements: [OBDCommand: MeasurementResult] = [:]
@Published var connectionState: ConnectionState = .disconnected
var cancellables = Set<AnyCancellable>()
var requestingPIDs: [OBDCommand] = [.mode1(.rpm)] {
didSet {
addPID(command: requestingPIDs[-1])
}
}
init() {
obdService.$connectionState
.assign(to: &$connectionState)
}
let obdService = OBDService(connectionType: .bluetooth)
func startContinousUpdates() {
obdService.startContinuousUpdates([.mode1(.rpm)]) // You can add more PIDs
.sink { completion in
print(completion)
} receiveValue: { measurements in
self.measurements = measurements
}
.store(in: &cancellables)
}
func addPID(command: OBDCommand) {
obdService.addPID(command)
}
func stopContinuousUpdates() {
cancellables.removeAll()
}
func startConnection() async throws {
let obd2info = try await obdService.startConnection(preferedProtocol: .protocol6)
print(obd2info)
}
func stopConnection() {
obdService.stopConnection()
}
func switchConnectionType() {
obdService.switchConnectionType(.wifi)
}
func getStatus() async {
let status = try? await obdService.getStatus()
print(status ?? "nil")
}
func getTroubleCodes() async {
let troubleCodes = try? await obdService.scanForTroubleCodes()
print(troubleCodes ?? "nil")
}
}
struct ContentView: View {
@ObservedObject var viewModel = ViewModel()
var body: some View {
VStack(spacing: 20) {
Text("Connection State: \(viewModel.connectionState.rawValue)")
ForEach(viewModel.requestingPIDs, id: \.self) { pid in
Text("\(pid.properties.description): \(viewModel.measurements[pid]?.value ?? 0) \(viewModel.measurements[pid]?.unit.symbol ?? "")")
}
Button("Connect") {
Task {
do {
try await viewModel.startConnection()
viewModel.startContinousUpdates()
} catch {
print(error)
}
}
}
.buttonStyle(.bordered)
Button("Stop") {
viewModel.stopContinuousUpdates()
}
.buttonStyle(.bordered)
Button("Add PID") {
viewModel.requestingPIDs.append(.mode1(.speed))
}
}
.padding()
}
}A comprehensive list of supported OBD2 commands will be available in the full documentation (coming soon).
Q: Bluetooth connection fails
- Ensure Bluetooth permissions are granted in iOS Settings
- Verify your ELM327 adapter is in pairing mode
- Try restarting Bluetooth on your device
Q: No data received from vehicle
- Check that your vehicle is OBD2 compatible (1996+ in US)
- Ensure the ELM327 adapter is properly connected to the OBD2 port
- Verify the vehicle is running (some data requires engine on)
Q: App crashes on connection
- Update to the latest version of SwiftOBD2
- Check that you've added required Bluetooth permissions to Info.plist
β Tested ELM327 Adapters:
- BAFX Products Bluetooth OBD2
- OBDLink MX+ Bluetooth
- VEEPEAK Mini WiFi OBD2
- Some cheap ELM327 clones may have connectivity issues
- WiFi adapters require network configuration
- π Open an issue for bug reports
- π‘ Start a discussion for questions
- π± Check out the sample app for implementation examples
- Ensure you have a compatible ELM327 OBD2 adapter.
- Permissions: If using Bluetooth, your app may need to request Bluetooth permissions from the user.
- Error Handling: Implement robust error handling mechanisms to gracefully handle potential communication issues.
- Background Updates (Optional): If your app needs background OBD2 data updates, explore iOS background fetch capabilities and fine-tune your library and app to work effectively in the background.
This project welcomes your contributions! Feel free to open issues for bug reports or feature requests. To contribute code:
- Fork the repository.
- Create your feature branch.
- Commit your changes with descriptive messages.
- Submit a pull request for review.
The Swift OBD package is distributed under the MIT license. See the LICENSE file for more details.
Love SwiftOBD2? Here's how you can help:
- β Star this repository - It really makes a difference!
- π Report bugs - Help us improve by reporting issues
- π‘ Suggest features - Share your ideas for new functionality
- π Contribute code - Submit PRs for fixes and enhancements
- π’ Spread the word - Share with other iOS/Swift developers
Current Stars: 106+ and growing! π
- SwiftOBD2App - Sample iOS app demonstrating SwiftOBD2
- Want your project listed here? Open a PR!
