How to Integrate OpenMedKit Swift Library in iOS Apps: MLX and CoreML Setup

Add OpenMedKit via Swift Package Manager, initialize it with either the MLX backend for Apple Silicon devices or the CoreML backend for bundled models, then call extractPII(_:) to perform on-device clinical entity extraction.

OpenMedKit is a Swift package from the maziyarpanahi/openmed repository that brings HIPAA-compliant clinical NLP—specifically named entity recognition (NER) and PII de-identification—directly to iOS, iPadOS, and macOS applications. To integrate OpenMedKit Swift library in iOS apps, you import the package, configure a backend, and invoke the high-level API on user text.

Installation via Swift Package Manager

You can add the dependency using Xcode's GUI or by editing your Package.swift directly.

Via Xcode

  1. Choose File > Add Packages…
  2. Enter the repository URL: https://github.com/maziyarpanahi/openmed
  3. Select the OpenMedKit product and add it to your app target

Via Package.swift

// swift-tools-version:5.9
import PackageDescription

let package = Package(
    name: "YourApp",
    dependencies: [
        .package(url: "https://github.com/maziyarpanahi/openmed.git", from: "1.5.5")
    ],
    targets: [
        .executableTarget(
            name: "YourApp",
            dependencies: [
                .product(name: "OpenMedKit", package: "openmed")
            ]
        )
    ]
)

The package manifest is defined in swift/OpenMedKit/Package.swift and includes dependencies for MLX, Transformers, and ZIPFoundation.

Choosing Your Inference Backend

OpenMedKit abstracts the model runtime behind the OpenMedBackend enum defined in OpenMedBackend.swift. You must choose between two execution paths:

  • MLX: Downloads Apple Silicon-optimized models from Hugging Face and runs inference locally using the MLX framework. Best for production iPhones and iPads.
  • CoreML: Loads a pre-converted .mlmodelc bundle shipped with your app. Required for iOS simulator testing or when you have existing CoreML assets.

The MLX backend requires downloading the model artifact on first launch. Use OpenMedModelStore.downloadMLXModel(repoID:) defined in OpenMedModelStore.swift to handle caching and file management.

import OpenMedKit

// Download and cache the model (async, runs once)
let modelDirectory = try await OpenMedModelStore.downloadMLXModel(
    repoID: "OpenMed/OpenMed-PII-ClinicalE5-Small-33M-v1-mlx"
)

// Initialize with MLX backend
let openmed = try OpenMed(
    backend: .mlx(modelDirectoryURL: modelDirectory)
)

// Extract PII entities
let entities = try openmed.extractPII(
    "Patient John Doe, DOB 1990-05-15, SSN 123-45-6789"
)

// entities is [EntityPrediction] containing label, text, confidence, and spans

CoreML Backend Setup (For Simulator or Bundled Models)

Use the CoreML backend when testing on simulators or when you prefer to bundle a converted model with your app binary. You need both the .mlmodelc directory and an id2label.json mapping file.

import OpenMedKit

// Locate bundled resources
let modelURL = Bundle.main.url(
    forResource: "OpenMedPII", 
    withExtension: "mlmodelc"
)!
let labelURL = Bundle.main.url(
    forResource: "id2label", 
    withExtension: "json"
)!

// Initialize with CoreML backend
let openmed = try OpenMed(
    backend: .coreML(
        modelURL: modelURL,
        id2labelURL: labelURL,
        tokenizerName: "OpenMed/OpenMed-PII-ClinicalE5-Small-33M-v1"
    )
)

// Run inference
let entities = try openmed.extractPII("Patient Jane Doe, MRN 123456")

The convenience initializer for the CoreML backend resides in OpenMedKit.swift.

Implementing Clinical NLP in SwiftUI

The following example mirrors the implementation in swift/OpenMedScanDemo/OpenMedScanDemo/ContentView.swift, demonstrating async model loading and entity display.

import SwiftUI
import OpenMedKit

struct ClinicalDocumentView: View {
    @State private var text = "Patient: Jane Doe, DOB: 01/15/1970, SSN: 000-00-0000"
    @State private var entities: [EntityPrediction] = []
    @State private var isLoading = false
    @State private var errorMessage: String?

    var body: some View {
        VStack(spacing: 16) {
            TextEditor(text: $text)
                .frame(height: 120)
                .border(Color.gray.opacity(0.5))

            Button(action: detectPII) {
                if isLoading {
                    ProgressView()
                } else {
                    Text("Detect PII")
                }
            }
            .disabled(isLoading)

            if let error = errorMessage {
                Text(error).foregroundColor(.red)
            }

            List(entities) { entity in
                VStack(alignment: .leading) {
                    Text("[\(entity.label)] \(entity.text)")
                        .font(.headline)
                    Text("Confidence: \(entity.confidence, specifier: "%.3f")")
                        .font(.caption)
                        .foregroundColor(.secondary)
                }
            }
        }
        .padding()
    }

    private func detectPII() {
        isLoading = true
        errorMessage = nil

        Task {
            do {
                // Switch to .coreML if running on simulator
                let modelDir = try await OpenMedModelStore.downloadMLXModel(
                    repoID: "OpenMed/OpenMed-PII-ClinicalE5-Small-33M-v1-mlx"
                )
                let openmed = try OpenMed(backend: .mlx(modelDirectoryURL: modelDir))
                entities = try openmed.extractPII(text)
            } catch {
                errorMessage = error.localizedDescription
            }
            isLoading = false
        }
    }
}

Key Source Files and Architecture

Understanding these files helps when debugging or extending functionality:

  • swift/OpenMedKit/Package.swift: Defines the Swift package structure and external dependencies (MLX, Transformers).
  • OpenMedBackend.swift: Contains the OpenMedBackend enum with .mlx(modelDirectoryURL:) and .coreML(modelURL:id2labelURL:tokenizerName:) cases.
  • OpenMedModelStore.swift: Implements downloadMLXModel(repoID:) for Hugging Face artifact management and local caching.
  • OpenMedKit.swift: Houses the OpenMed class public API, including extractPII(_:confidenceThreshold:) and analyzeText(_:confidenceThreshold:).
  • PostProcessing.swift: Smart post-processing logic for entity span repair and merging.
  • ContentView.swift: Reference SwiftUI implementation in the demo app showing end-to-end integration.

Summary

  • Add dependency: Use Swift Package Manager with https://github.com/maziyarpanahi/openmed
  • Choose backend: MLX for Apple Silicon performance on real devices; CoreML for simulator or bundled models
  • Download MLX models: Call OpenMedModelStore.downloadMLXModel(repoID:) to cache Hugging Face artifacts locally
  • Bundle CoreML models: Include .mlmodelc directories and id2label.json files in your app target
  • Initialize: Create an OpenMed instance using OpenMed(backend: .mlx(...)) or OpenMed(backend: .coreML(...))
  • Extract entities: Invoke extractPII(_:confidenceThreshold:) to receive [EntityPrediction] results with labels, confidence scores, and character spans

Frequently Asked Questions

Can I use OpenMedKit on the iOS simulator?

Yes, but only with the CoreML backend. The MLX backend requires Apple Silicon hardware and will not run on Intel-based simulators. For simulator testing, bundle a converted CoreML model (.mlmodelc) and initialize with OpenMed(backend: .coreML(modelURL:id2labelURL:tokenizerName:)).

What is the difference between extractPII and analyzeText?

Both methods perform named entity recognition defined in OpenMedKit.swift. extractPII(_:confidenceThreshold:) specifically targets personally identifiable information in clinical text (names, dates, SSNs, medical record numbers), while analyzeText(_:confidenceThreshold:) provides general clinical entity analysis. Both return arrays of EntityPrediction objects containing the entity text, label, confidence score, and character positions.

How does OpenMedKit handle model caching?

The OpenMedModelStore.downloadMLXModel(repoID:) method in OpenMedModelStore.swift automatically caches downloaded MLX artifacts in the application's local filesystem. Subsequent calls return the cached path immediately, avoiding redundant network requests across app launches.

Which backend offers better performance on modern iPhones?

The MLX backend delivers superior performance on iPhone 12, iPad Air/Pro, and Apple Silicon Macs by leveraging the Neural Engine and GPU acceleration. CoreML provides broader compatibility, particularly for older devices or when you require simulator support, but may have higher latency for complex clinical documents.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →