/natural-language
Tokenize, tag, and analyze natural language text using Apple's NaturalLanguage framework and translate between languages with the Translation framework. Use when adding language identification, sentiment analysis, named entity recognition, part-of-speech tagging, text
$ npx -y skills add dpearson2699/swift-ios-skills --skill natural-language --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/natural-language
Context preview
The summary Claude sees to decide when to auto-load this skill.
Tokenize, tag, and analyze natural language text using Apple's NaturalLanguage framework and translate between languages with the Translation framework. Use when adding language identification, sentiment analysis, named entity recognition, part-of-speech tagging, text
SKILL.md
natural-language.SKILL.mdname: natural-language
description: "Tokenize, tag, and analyze natural language text using Apple's NaturalLanguage framework and translate between languages with the Translation framework. Use when adding language identification, sentiment analysis, named entity recognition, part-of-speech tagging, text embeddings, or in-app translation to iOS/macOS/visionOS apps."
NaturalLanguage + Translation
Analyze natural language text for tokenization, part-of-speech tagging, named entity recognition, sentiment analysis, language identification, and word/sentence embeddings. Translate text between languages with the Translation framework.
> This skill covers two related frameworks: **NaturalLanguage** (`NLTokenizer`, `NLTagger`, `NLEmbedding`) for on-device text analysis, and **Translation** (`TranslationSession`, `LanguageAvailability`) for language translation.
**Scope boundary:** Use this skill after you already have text. It owns tokenization, language identification, POS/NER tagging, sentiment, embeddings, custom `NLModel` classifiers/taggers, and in-app translation. Hand off OCR to `vision-framework`, speech-to-text to `speech-recognition`, UI strings and locale formatting to `ios-localization`, and generative summarization or Apple Intelligence workflows to `apple-on-device-ai`.
Contents
- [Setup](#setup)
- [Tokenization](#tokenization)
- [Language Identification](#language-identification)
- [Part-of-Speech Tagging](#part-of-speech-tagging)
- [Named Entity Recognition](#named-entity-recognition)
- [Sentiment Analysis](#sentiment-analysis)
- [Text Embeddings](#text-embeddings)
- [Translation](#translation)
- [Common Mistakes](#common-mistakes)
- [Review Checklist](#review-checklist)
- [References](#references)
Setup
Import `NaturalLanguage` for text analysis and `Translation` for language translation. No special entitlements or capabilities are required for NaturalLanguage. Translation has split availability: system translation presentation is iOS 17.4+ / macOS 14.4+, while `TranslationSession`, `.translationTask()`, `LanguageAvailability`, and batch translation require iOS 18+ / macOS 15+. Direct `TranslationSession(installedSource:target:)` is the non-UI option, but only when the source and target languages are already installed on device.
import NaturalLanguage
import Translation
NaturalLanguage classes (`NLTokenizer`, `NLTagger`) are **not thread-safe**. Use each instance from one thread or dispatch queue at a time.
Tokenization
Segment text into words, sentences, or paragraphs with `NLTokenizer`.
import NaturalLanguage
func tokenizeWords(in text: String) -> [String] {
let tokenizer = NLTokenizer(unit: .word)
tokenizer.string = text
let range = text.startIndex..<text.endIndex
return tokenizer.tokens(for: range).map { String(text[$0]) }
}Token Units
| Unit | Description | |---|---| | `.word` | Individual words | | `.sentence` | Sentences | | `.paragraph` | Paragraphs | | `.document` | Entire document |
Enumerating with Attributes
Use `enumerateTokens(in:using:)` to detect numeric or emoji tokens.
let tokenizer = NLTokenizer(unit: .word)
tokenizer.string = text
tokenizer.enumerateTokens(in: text.startIndex..<text.endIndex) { range, attributes in
if attributes.contains(.numeric) {
print("Number: \(text[range])")
}
return true // continue enumeration
}Language Identification
Detect the dominant language of a string with `NLLanguageRecognizer`.
func detectLanguage(for text: String) -> NLLanguage? {
NLLanguageRecognizer.dominantLanguage(for: text)
}
// Multiple hypotheses with confidence scores
func languageHypotheses(for text: String, max: Int = 5) -> [NLLanguage: Double] {
let recognizer = NLLanguageRecognizer()
recognizer.processString(text)
return recognizer.languageHypotheses(withMaximum: max)
}Constrain the recognizer to expected languages for better accuracy on short text.
let recognizer = NLLanguageRecognizer()
recognizer.languageConstraints = [.english, .french, .spanish]
recognizer.processString(text)
let detected = recognizer.dominantLanguage
Part-of-Speech Tagging
Identify nouns, verbs, adjectives, and other lexical classes with `NLTagger`.
func tagPartsOfSpeech(in text: String) -> [(String, NLTag)] {
let tagger = NLTagger(tagSchemes: [.lexicalClass])
tagger.string = text
var results: [(String, NLTag)] = []
let range = text.startIndex..<text.endIndex
let options: NLTagger.Options = [.omitPunctuation, .omitWhitespace]
tagger.enumerateTags(in: range, unit: .word, scheme: .lexicalClass, options: options) { tag, tokenRange in
if let tag {
results.append((String(text[tokenRange]), tag))
}
return true
}
return results
}Common Tag Schemes
| Scheme | Output | |---|---| | `.lexicalClass` | Part of speech (noun, verb, adjective) | | `.nameType` | Named entity type (person, place, organization) | | `.nameTypeOrLexicalClass` | Combined NER + POS | | `.lemma` | Base form of a word | | `.language` | Per-token language | | `.sentimentScore` | Sentiment polarity score |
Named Entity Recognition
Extract people, places, and organizations.
func extractEntities(from text: String) -> [(String, NLTag)] {
let tagger = NLTagger(tagSchemes: [.nameType])
tagger.string = text
var entities: [(String, NLTag)] = []
let options: NLTagger.Options = [.omitPunctuation, .omitWhitespace, .joinNames]
tagger.enumerateTags(
in: text.startIndex..<text.endIndex,
unit: .word,
scheme: .nameType,
options: options
) { tag, tokenRange in
if let tag, tag != .other {
entities.append((String(text[tokenRange]), tag))
}
return true
}
return entities
}
// NLTag values: .personalName, .placeName, .organizationNameSentiment Analysis
Score tex
Read more
name: natural-language description: "Tokenize, tag, and analyze natural language text using Apple's NaturalLanguage framework and translate between languages with the Translation framework. Use when adding language identification, sentiment analysis, named entity recognition, part-of-speech tagging, text embeddings, or in-app translation to iOS/macOS/visionOS apps."
NaturalLanguage + Translation
Analyze natural language text for tokenization, part-of-speech tagging, named entity recognition, sentiment analysis, language identification, and word/sentence embeddings. Translate text between languages with the Translation framework.
> This skill covers two related frameworks: **NaturalLanguage** (`NLTokenizer`, `NLTagger`, `NLEmbedding`) for on-device text analysis, and **Translation** (`TranslationSession`, `LanguageAvailability`) for language translation.
**Scope boundary:** Use this skill after you already have text. It owns tokenization, language identification, POS/NER tagging, sentiment, embeddings, custom `NLModel` classifiers/taggers, and in-app translation. Hand off OCR to `vision-framework`, speech-to-text to `speech-recognition`, UI strings and locale formatting to `ios-localization`, and generative summarization or Apple Intelligence workflows to `apple-on-device-ai`.
Contents
- [Setup](#setup)
- [Tokenization](#tokenization)
- [Language Identification](#language-identification)
- [Part-of-Speech Tagging](#part-of-speech-tagging)
- [Named Entity Recognition](#named-entity-recognition)
- [Sentiment Analysis](#sentiment-analysis)
- [Text Embeddings](#text-embeddings)
- [Translation](#translation)
- [Common Mistakes](#common-mistakes)
- [Review Checklist](#review-checklist)
- [References](#references)
Setup
Import `NaturalLanguage` for text analysis and `Translation` for language translation. No special entitlements or capabilities are required for NaturalLanguage. Translation has split availability: system translation presentation is iOS 17.4+ / macOS 14.4+, while `TranslationSession`, `.translationTask()`, `LanguageAvailability`, and batch translation require iOS 18+ / macOS 15+. Direct `TranslationSession(installedSource:target:)` is the non-UI option, but only when the source and target languages are already installed on device.
import NaturalLanguage import Translation
NaturalLanguage classes (`NLTokenizer`, `NLTagger`) are **not thread-safe**. Use each instance from one thread or dispatch queue at a time.
Tokenization
Segment text into words, sentences, or paragraphs with `NLTokenizer`.
import NaturalLanguage
func tokenizeWords(in text: String) -> [String] {
let tokenizer = NLTokenizer(unit: .word)
tokenizer.string = text
let range = text.startIndex..<text.endIndex
return tokenizer.tokens(for: range).map { String(text[$0]) }
}Token Units
| Unit | Description | |---|---| | `.word` | Individual words | | `.sentence` | Sentences | | `.paragraph` | Paragraphs | | `.document` | Entire document |
Enumerating with Attributes
Use `enumerateTokens(in:using:)` to detect numeric or emoji tokens.
let tokenizer = NLTokenizer(unit: .word)
tokenizer.string = text
tokenizer.enumerateTokens(in: text.startIndex..<text.endIndex) { range, attributes in
if attributes.contains(.numeric) {
print("Number: \(text[range])")
}
return true // continue enumeration
}Language Identification
Detect the dominant language of a string with `NLLanguageRecognizer`.
func detectLanguage(for text: String) -> NLLanguage? {
NLLanguageRecognizer.dominantLanguage(for: text)
}
// Multiple hypotheses with confidence scores
func languageHypotheses(for text: String, max: Int = 5) -> [NLLanguage: Double] {
let recognizer = NLLanguageRecognizer()
recognizer.processString(text)
return recognizer.languageHypotheses(withMaximum: max)
}Constrain the recognizer to expected languages for better accuracy on short text.
let recognizer = NLLanguageRecognizer() recognizer.languageConstraints = [.english, .french, .spanish] recognizer.processString(text) let detected = recognizer.dominantLanguage
Part-of-Speech Tagging
Identify nouns, verbs, adjectives, and other lexical classes with `NLTagger`.
func tagPartsOfSpeech(in text: String) -> [(String, NLTag)] {
let tagger = NLTagger(tagSchemes: [.lexicalClass])
tagger.string = text
var results: [(String, NLTag)] = []
let range = text.startIndex..<text.endIndex
let options: NLTagger.Options = [.omitPunctuation, .omitWhitespace]
tagger.enumerateTags(in: range, unit: .word, scheme: .lexicalClass, options: options) { tag, tokenRange in
if let tag {
results.append((String(text[tokenRange]), tag))
}
return true
}
return results
}Common Tag Schemes
| Scheme | Output | |---|---| | `.lexicalClass` | Part of speech (noun, verb, adjective) | | `.nameType` | Named entity type (person, place, organization) | | `.nameTypeOrLexicalClass` | Combined NER + POS | | `.lemma` | Base form of a word | | `.language` | Per-token language | | `.sentimentScore` | Sentiment polarity score |
Named Entity Recognition
Extract people, places, and organizations.
func extractEntities(from text: String) -> [(String, NLTag)] {
let tagger = NLTagger(tagSchemes: [.nameType])
tagger.string = text
var entities: [(String, NLTag)] = []
let options: NLTagger.Options = [.omitPunctuation, .omitWhitespace, .joinNames]
tagger.enumerateTags(
in: text.startIndex..<text.endIndex,
unit: .word,
scheme: .nameType,
options: options
) { tag, tokenRange in
if let tag, tag != .other {
entities.append((String(text[tokenRange]), tag))
}
return true
}
return entities
}
// NLTag values: .personalName, .placeName, .organizationNameSentiment Analysis
Score tex
86 agent skills optimized for iOS 26+ development with Swift 6.3 and modern Apple frameworks.
Repo: dpearson2699/swift-ios-skills
Other skills on swift-ios-skills.
- /accessorysetupkit
Discover and configure Bluetooth and Wi-Fi accessories using AccessorySetupKit. Use when presenting a privacy-preserving accessory picker, defining discovery descriptors for BLE or Wi-Fi devices, handling accessory session events, migrating from CoreBluetooth permission-based
Open skill - /activitykit
Implement, review, or improve Live Activities and Dynamic Island experiences in iOS apps using ActivityKit. Use when building real-time updating widgets for the Lock Screen and Dynamic Island — delivery tracking, sports scores, ride-sharing status, workout timers, media
Open skill - /adattributionkit
Measure ad effectiveness with privacy-preserving attribution using AdAttributionKit. Use when registering ad impressions, handling attribution postbacks, updating conversion values, implementing re-engagement attribution, configuring publisher or advertiser apps, or replacing
Open skill - /alarmkit
Implement AlarmKit alarms and countdown timers for iOS and iPadOS with Lock Screen, Dynamic Island, StandBy, and paired Apple Watch system UI. Covers AlarmManager scheduling, AlarmAttributes and AlarmPresentation, system Stop and AlarmButton secondary actions, authorization,
Open skill - /app-clips
Build iOS App Clips with invocation URLs, App Clip Codes, NFC, QR codes, Safari banners, Maps, Messages, target setup, App Store Connect experiences, size/capability constraints, NSUserActivity routing, SKOverlay promotion, App Group/keychain handoff, ephemeral notifications,
Open skill - /app-intents
Implement App Intents for Siri, Shortcuts, Spotlight, widgets, Control Center, and Apple Intelligence on iOS. Covers AppIntent actions, AppEntity and EntityQuery models, AppShortcutsProvider phrases, IndexedEntity Spotlight indexing, WidgetConfigurationIntent, SnippetIntent, and
Open skill

