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.
Connection Management:
Data Retrieval:
Diagnostics:
Adaptability and Configuration
Create a New Swift Project:
Add the SwiftOBD2 Package:
Permissions and Capabilities:
import SwiftUI
import SwiftOBD2
import Combine
ViewModel
Connection Handling
Starting the Connection
Stopping the Connection
Retrieving Information
Continuous Updates
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).
This project welcomes your contributions! Feel free to open issues for bug reports or feature requests. To contribute code:
The Swift OBD package is distributed under the MIT license. See the LICENSE file for more details.