Loading...
Loading...
Core ML, Create ML, Vision framework, Natural Language framework, on-device ML integration. Use when user wants image classification, text analysis, object detection, sound classification, model optimization, or custom model integration. Covers Core ML vs Foundation Models decision.
npx skill4agent add rshankras/claude-code-apple-skills core-ml@Generableapple-intelligence/foundation-models/VNRecognizeTextRequestGlob: **/*Model*.swift, **/*Classifier*.swift, **/*Predictor*.swift, **/*.mlmodel, **/*.mlmodelc, **/*.mlpackage
Grep: "import CoreML" or "import Vision" or "import NaturalLanguage".mlmodel.mlpackage.mlmodelc// Option 1: Auto-generated class (simplest)
let model = try MyImageClassifier(configuration: MLModelConfiguration())
// Option 2: Generic MLModel loading (flexible)
let url = Bundle.main.url(forResource: "MyModel", withExtension: "mlmodelc")!
let config = MLModelConfiguration()
config.computeUnits = .all // CPU + GPU + Neural Engine
let model = try MLModel(contentsOf: url, configuration: config)
// Option 3: Async loading (recommended for large models)
let model = try await MLModel.load(contentsOf: url, configuration: config)// Type-safe prediction with auto-generated class
let input = MyImageClassifierInput(image: pixelBuffer)
let output = try model.prediction(input: input)
print(output.classLabel) // "cat"
print(output.classLabelProbs) // ["cat": 0.95, "dog": 0.04, ...]
// Batch predictions
let batch = MLArrayBatchProvider(array: inputs)
let results = try model.predictions(from: batch)| Capability | Request Class | Custom Model Needed? |
|---|---|---|
| Image classification | | No (built-in) |
| Object detection | | Yes |
| Face detection | | No |
| Face landmarks | | No |
| Text recognition (OCR) | | No |
| Body pose | | No |
| Hand pose | | No |
| Barcode detection | | No |
| Image saliency | | No |
| Horizon detection | | No |
| Rectangle detection | | No |
| Image similarity | | No |
// Multiple requests on the same image
let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
try handler.perform([
textRequest, // OCR
faceRequest, // Face detection
barcodeRequest // Barcode scanning
])
// Each request's results are populated independentlylet tagger = NLTagger(tagSchemes: [.sentimentScore])
tagger.string = "This app is amazing!"
let (tag, _) = tagger.tag(at: text.startIndex, unit: .paragraph, scheme: .sentimentScore)
// tag?.rawValue == "0.9" (positive)let language = NLLanguageRecognizer.dominantLanguage(for: "Bonjour le monde")
// language == .frenchlet tokenizer = NLTokenizer(unit: .word)
tokenizer.string = "Hello, world!"
tokenizer.enumerateTokens(in: text.startIndex..<text.endIndex) { range, _ in
print(text[range]) // "Hello" then "world"
return true
}let tagger = NLTagger(tagSchemes: [.nameType])
tagger.string = "Tim Cook visited Apple Park in Cupertino."
tagger.enumerateTags(in: text.startIndex..<text.endIndex, unit: .word, scheme: .nameType) { tag, range in
if let tag, tag != .other {
print("\(text[range]): \(tag.rawValue)")
// "Tim": PersonalName, "Cook": PersonalName
// "Apple Park": OrganizationName, "Cupertino": PlaceName
}
return true
}import coremltools as ct
from coremltools.models.neural_network import quantization_utils
model = ct.models.MLModel("MyModel.mlmodel")
# Float16 quantization (safe default)
model_fp16 = quantization_utils.quantize_weights(model, nbits=16)
model_fp16.save("MyModel_fp16.mlmodel")
# Int8 quantization (aggressive, test accuracy)
model_int8 = quantization_utils.quantize_weights(model, nbits=8)
model_int8.save("MyModel_int8.mlmodel")from coremltools.optimize.coreml import palettize_weights, OpPalettizerConfig
config = OpPalettizerConfig(nbits=4) # 16 unique values per tensor
model_palettized = palettize_weights(model, config)from coremltools.optimize.torch.pruning import MagnitudePruner, MagnitudePrunerConfig
config = MagnitudePrunerConfig(target_sparsity=0.75) # Remove 75% of weights
pruner = MagnitudePruner(model, config)let config = MLModelConfiguration()
// Best performance — let system choose CPU, GPU, or Neural Engine
config.computeUnits = .all
// CPU only — predictable latency, no GPU/NE contention
config.computeUnits = .cpuOnly
// CPU + Neural Engine — good balance, avoids GPU contention with UI
config.computeUnits = .cpuAndNeuralEngine
// CPU + GPU — when Neural Engine unavailable
config.computeUnits = .cpuAndGPUfunc classify(_ image: UIImage) async throws -> String {
let model = try await MLModelManager.shared.model(named: "Classifier")
// Prediction runs off main thread via structured concurrency
let input = try MLDictionaryFeatureProvider(dictionary: ["image": image.pixelBuffer!])
let result = try await Task.detached {
try model.prediction(from: input)
}.value
return result.featureValue(for: "classLabel")?.stringValue ?? "unknown"
}// Process multiple images efficiently
let inputs = images.map { MyModelInput(image: $0.pixelBuffer!) }
let batch = MLArrayBatchProvider(array: inputs)
let results = try model.predictions(from: batch)
for i in 0..<results.count {
let output = results.features(at: i)
print(output.featureValue(for: "classLabel")?.stringValue ?? "")
}// Compile .mlmodel to .mlmodelc at install (not runtime)
// This is done automatically when you add .mlmodel to Xcode target
// For downloaded models, compile once and cache:
let compiledURL = try MLModel.compileModel(at: downloadedModelURL)
let permanentURL = appSupportDir.appendingPathComponent("MyModel.mlmodelc")
try FileManager.default.copyItem(at: compiledURL, to: permanentURL)templates.md| Capability | Files Generated |
|---|---|
| Any Core ML | |
| Image classification | |
| Text analysis | |
| Vision requests | |
| Custom model | |
| Camera + ML | |
Sources/Sources/ML/App/Services/App/Services/ML/App/App/ML/ML/ML/
├── MLModelManager.swift # Central model lifecycle management
├── ImageClassifier.swift # Vision-based image classification (if needed)
├── TextAnalyzer.swift # NaturalLanguage wrapper (if needed)
├── ModelConfig.swift # Compute unit configuration
└── VisionService.swift # Vision request pipeline (if needed).mlmodel