SFSpeechRecognizer هو واجهة برمجة التطبيقات الرئيسية من Apple للتعرف على الكلام في نظام iOS البيئي. يوفر الإطار الوصول إلى محرك ASR للجهاز من خلال Speech.framework، ويدعم النسخ التدفقي في الوقت الفعلي والتعرف الفردي على ملفات الصوت. SFSpeechRecognizer متاح على iOS 10+ وmacOS 10.15+ وwatchOS 6+ وtvOS 17+. مع iOS 17، أضافت Apple وضعًا كاملاً على الجهاز يسمح بالتعرف على الكلام بدون اتصال بالإنترنت. وفقًا لـ Apple Speech Documentation، 2025، يتم استخدام SFSpeechRecognizer في أكثر من 200,000 تطبيق على App Store ويعالج ملايين الطلبات يوميًا بمعدل WER 7% باللغة الإنجليزية.
الخلاصة
SFSpeechRecognizer هو فئة من Speech.framework تمثل أداة التعرف على الكلام للغة معينة. يتم تهيئتها مع Locale (ru_RU، en_US، zh_CN). يدير SFSpeechRecognizer طلب التعرف (SFSpeechRecognitionRequest) ويعيد نتيجة (SFSpeechRecognitionResult) مع النسخ والبيانات الوصفية. يدعم نوعين من الطلبات: SFSpeechAudioBufferRecognitionRequest (تدفق صوتي مباشر) وSFSpeechURLRecognitionRequest (ملف صوتي). كلاهما يعيد SFTranscription — مصفوفة من الفرضيات البديلة للتعرف.
SFSpeechRecognitionResult يحتوي على: bestTranscription (أفضل فرضية، SFTranscription)، transcriptions (جميع البدائل)، isFinal (نهائي/مؤقت). SFTranscription يحتوي على: formattedString (نص)، segments (مصفوفة من SFTranscriptionSegment مع الطوابع الزمنية، الثقة، substringRange، alternativeSubstrings). الثقة لكل مقطع (0..1) — تسمح بتصفية الأجزاء غير الموثوقة. تعتبر segments ميزة رئيسية في Speech.framework: فهي توفر علامات لكل كلمة مع درجات الثقة.
هندسة SFSpeechRecognizer: AVFoundation (التقاط الصوت) → Audio Buffer → SFSpeechAudioBufferRecognitionRequest → SFSpeechRecognizer (محرك ASR) → SFSpeechRecognitionResult → SFSpeechRecognitionTask (تحكم: إلغاء، إنهاء، إيقاف مؤقت). يستخدم محرك ASR من Apple بنية هجينة: Conformer (مشفر) + RNNT (مفك شفرة) للجهاز، Transducer للسحابة. النماذج محسّنة لـ Apple Neural Engine (ANE). على A17 Pro، يعمل ASR على الجهاز مع RTF 0.3–0.6 (أسرع من الوقت الفعلي).
| المكون | الغرض | إصدار iOS |
|---|---|---|
| SFSpeechRecognizer | فئة التعرف الرئيسية | iOS 10+ |
| SFSpeechAudioBufferRecognitionRequest | تدفق صوتي مباشر | iOS 10+ |
| SFSpeechURLRecognitionRequest | ملف صوتي (.wav، .m4a) | iOS 10+ |
| SFSpeechRecognitionTask | إدارة الطلب (إلغاء، إنهاء) | iOS 10+ |
| التعرف على الجهاز | ASR بدون اتصال | iOS 17+ |
| التعرف المدمج | هجين على الجهاز + سحابة | iOS 17+ |
متطلبات الصوت: يقبل SFSpeechRecognizer LPCM (16 كيلوهرتز، 16 بت، أحادي) أو Opus (iOS 17+). يمكن لـ AVFoundation التقاط المخازن المؤقتة بأي تنسيق، ويقوم الطلب بالتحويل تلقائيًا. الحد الأدنى للطول: 0.5 ثانية (كشف الصمت). الحد الأقصى: دقيقة واحدة (سحابة) / دقيقتان (على الجهاز) لكل طلب. للنسخ الطويل، قسم الصوت إلى أجزاء من 30–60 ثانية مع تداخل 2–5 ثوانٍ.
تصاريح المستخدم: يتطلب SFSpeechRecognizer تصريحين صريحين. NSMicrophoneUsageDescription (الخصوصية — وصف استخدام الميكروفون) — للوصول إلى الميكروفون. NSSpeechRecognitionUsageDescription (الخصوصية — وصف استخدام التعرف على الكلام) — للوصول إلى التعرف على الكلام. كلاهما نصوص تشرح السبب للمستخدم. SFSpeechRecognizer.requestAuthorization — يعرض حوار التصريح. الحالات: notDetermined، denied، restricted، authorized. بدون الحالة authorized، استدعاء recognizer يُرجع خطأ 216 (خطأ في إطار Speech).
التحقق من التوفر: SFSpeechRecognizer.isAvailable — يتحقق مما إذا كان ASR متاحًا للغة الحالية. على iOS 16-، isAvailable = false بدون إنترنت. على iOS 17+، isAvailable = true للغات على الجهاز حتى بدون اتصال. SFSpeechRecognizer.supportedLocales — طريقة ثابتة للحصول على قائمة اللغات المدعومة من الجهاز. يُوصى بالتحقق من isAvailable قبل كل تشغيل (قد يقوم المستخدم بتعطيل Siri/الإملاء في الإعدادات). يعتمد التوفر على المنطقة: الصينية — فقط في الصين، العربية — في الإمارات.
// إعداد SFSpeechRecognizer
import Speech
SFSpeechRecognizer.requestAuthorization { status in
guard status == .authorized else { return }
}
let recognizer = SFSpeechRecognizer(locale: Locale(identifier: "ru_RU"))!
guard recognizer.isAvailable else {
print("ASR غير متاح. فعّل Siri والإملاء في الإعدادات")
return
}
let request = SFSpeechAudioBufferRecognitionRequest()
request.requiresOnDeviceRecognition = true
معالجة الأخطاء: يتم استدعاء SFSpeechRecognizer مع معالج إكمال قد يعيد خطأ. الأخطاء الرئيسية: 203 — لا يوجد إنترنت (سحابة، iOS 16-)؛ 216 — غير مصرح به (لا يوجد تصريح)؛ 301 — خطأ صوتي (مشكلة في الميكروفون/التنسيق)؛ 401 — الخدمة غير متاحة (الخدمة محملة بشكل زائد)؛ 601 — اللغة غير متاحة (اللغة غير مدعومة على الجهاز). للجهاز على iOS 17+، الأخطاء الرئيسية: 301 (صوت)، 601 (لغة). تعامل دائمًا مع معالج الإكمال — يمكن أن تحدث الأخطاء في أي وقت أثناء التسجيل.
خط أنابيب ASR المباشر: AVAudioEngine (التقاط الميكروفون) → installTap (مخزن الصوت) → request.append(buffer) → SFSpeechRecognizer → recognitionTask → delegate/resultHandler. يوفر AVAudioEngine زمن استجابة منخفض (5–10 مللي ثانية من الميكروفون إلى المخزن). SFSpeechRecognitionDelegate: didHypothesizeTranscription (كل 200–500 مللي ثانية — نص جزئي)، didFinishRecognition (النتيجة النهائية). Task.isFinishing — يمكن الإلغاء عند اكتمال التعرف. للتعرف المستمر (إملاء لا نهائي)، أنشئ مهمة جديدة بعد isFinal.
SFSpeechRecognitionTaskDelegate: طرق اختيارية. speechRecognitionDidDetectSpeech (بداية الكلام) — للإشارة في واجهة المستخدم. didHypothesizeTranscription (نص وسيط) — للعرض أثناء التحدث. didFinishRecognition (النتيجة النهائية) — لتثبيت النص. didFinishSuccessfully (نجاح/خطأ) — للإكمال. didProcessAudio (تمت معالجة المخزن الصوتي) — لمقياس RMS. يُوصى بتطبيق didHypothesizeTranscription — يرى المستخدم النص فورًا بدون تأخير. النسخ النهائي للحفظ.
// التعرف على الكلام المباشر
let audioEngine = AVAudioEngine()
let request = SFSpeechAudioBufferRecognitionRequest()
request.shouldReportPartialResults = true
recognitionTask = recognizer.recognitionTask(with: request) { result, error in
if let result = result {
textView.text = result.bestTranscription.formattedString
}
if error != nil || result?.isFinal == true {
audioEngine.stop()
request.endAudio()
}
}
let inputNode = audioEngine.inputNode
let recordingFormat = inputNode.outputFormat(forBus: 0)
inputNode.installTap(onBus: 0, bufferSize: 1024,
format: recordingFormat) { buffer, _ in
request.append(buffer)
}
audioEngine.prepare()
try audioEngine.start()
التعرف المستمر: لوضع “الاستماع دائمًا” (الإدخال الصوتي، المساعد)، يلزم إعادة تشغيل المهمة بعد isFinal. أنشئ حلقة: finishTask → request = SFSpeechAudioBufferRecognitionRequest() → recognitionTask = recognizer.recognitionTask(with: request). لتجنب الفجوات، قم بتداخل نهاية مهمة مع بداية التالية (ابدأ طلبًا جديدًا قبل 1–2 ثانية من انتهاء السابق). AVFoundation AVAudioSession — قم بتكوين .playAndRecord للتشغيل والتسجيل المتزامنين. على iOS 17+، يستهلك ASR المستمر على الجهاز 2–5% من البطارية في الساعة (A15+).
SFSpeechURLRecognitionRequest — طلب للتعرف على ملف صوتي بواسطة URL. يدعم التنسيقات: .wav (16 كيلوهرتز، 16 بت، أحادي)، .m4a (AAC)، .mp4، .mov. الطول الأقصى: ~دقيقة واحدة للسحابة، ~دقيقتان للجهاز. للملفات الأطول، قسم إلى أجزاء (AVAssetExportSession + trim). SFSpeechURLRecognitionRequest لا يدعم التدفق (لا توجد نتائج جزئية) — فقط النتيجة النهائية. للحصول على نتائج جزئية مع ملف، قم بالتحويل إلى طلب Audio Buffer.
الحصول على نسخ ملف الصوت: SFSpeechRecognizer.recognitionTask(with: request) resultHandler. استخرج bestTranscription.formattedString. للطوابع الزمنية على مستوى الكلمة — segments من bestTranscription.segments (segment.duration، segment.timestamp، segment.substring). الثقة لكل مقطع — ثقة ASR لكل كلمة (استخدمها للتصفية). الفرضيات البديلة — بدائل transcriptionFormatter للكلمات ذات الثقة المنخفضة. للملفات التي بها عدة متحدثين، قد يعيد SFSpeechRecognitionRequest طلبات متعددة (واحد لكل متحدث، iOS 17+).
// نسخ ملف الصوت
let audioURL = Bundle.main.url(forResource: "recording", withExtension: "m4a")!
let request = SFSpeechURLRecognitionRequest(url: audioURL)
request.requiresOnDeviceRecognition = true
recognizer.recognitionTask(with: request) { result, error in
guard let result = result, error == nil else {
print("خطأ: \(error?.localizedDescription ?? "unknown")")
return
}
let transcription = result.bestTranscription
let text = transcription.formattedString
let words = transcription.segments.map { segment in
Word(text: segment.substring,
start: segment.timestamp,
duration: segment.duration,
confidence: segment.confidence)
}
}
تقسيم ملفات الصوت الطويلة: للملفات > دقيقة واحدة، قسم إلى أجزاء من 30–60 ثانية مع تداخل 2–3 ثوانٍ (توصيل). AVAssetExportSession + CMTimeRange — تصدير الأجزاء. بديل: UISelectionView (يختار المستخدم مقطعًا). توصيل النسخ: دمج النصوص، التوصيل عن طريق التداخل (تتم مقارنة آخر 2–3 كلمات من الجزء السابق مع أول 2–3 كلمات من الجزء التالي — إزالة التكرار). يدعم Vosk وWhisper الصوت الطويل أصلاً، SFSpeechRecognizer لا يدعم. للنسخ الطويل، أوصي بـ Whisper (Core ML) — بدون حد للطول.
وضع على الجهاز (iOS 17+): request.requiresOnDeviceRecognition = true. يعمل ASR محليًا على Apple Neural Engine (ANE). المزايا: لا حاجة للإنترنت، الخصوصية (الصوت لا يغادر الجهاز)، تكلفة صفرية (مجاني)، زمن استجابة منخفض (RTF 0.3–0.6). العيوب: دقة أقل (WER 12–14% مقابل 7–12%)، حد 2 دقيقة لكل طلب، مجموعة لغات محدودة (ليست كل 60 لغة متاحة على الجهاز). النموذج على الجهاز يشغل ~50–100 MB على الجهاز ويتم تنزيله عند الطلب الأول.
السحابة (iOS 16-): request.requiresOnDeviceRecognition = false (أو المعامل غائب). ASR على خوادم Apple — أكثر دقة (WER 7% EN، 12% RU)، لغات أكثر، حتى دقيقة واحدة لكل طلب. يتطلب إنترنت (WiFi أو خلوي). Apple لا تفرض رسومًا على المطورين مقابل ASR السحابي (مجاني). الحدود: طلب واحد في الدقيقة لكل تطبيق (غير محدد)، ولكن Apple قد تحد من النطاق الإنتاجي. ASR السحابي يوفر جودة أفضل جهد بدون SLA. للتطبيقات المؤسسية، استخدم Google Cloud ASR أو Whisper (Core ML).
| المعامل | على الجهاز (iOS 17+) | السحابة (iOS 10+) |
|---|---|---|
| يتطلب إنترنت | لا | نعم |
| WER (EN) | 10–12% | 7% |
| WER (RU) | 12–14% | 12% |
| زمن الاستجابة (RTF) | 0.3–0.6 | 0.3–0.8 (+شبكة) |
| الحد الأقصى للطول | دقيقتان | دقيقة واحدة |
| الخصوصية | كاملة | الصوت يغادر الجهاز |
| مجاني | نعم | نعم |
التعرف المدمج (iOS 17+): request.requiresOnDeviceRecognition = false مع الإنترنت (سحابة)، = true بدون اتصال (احتياطي). Apple تختار الوضع تلقائيًا. للتطبيقات الحساسة للدقة: تحقق من NetworkMonitor (NWPathMonitor) — استخدم السحابة مع الإنترنت، على الجهاز بدونه. للتطبيقات الحساسة للخصوصية: دائمًا على الجهاز. للنسخ: سحابة (أكثر دقة). للإدخال الصوتي: على الجهاز (أسرع). يُوصى بالوضع المدمج: 80% سحابة، 20% احتياطي على الجهاز.
الإدخال الصوتي في لوحة المفاتيح المخصصة — SFSpeechRecognizer مدمج في ملحقات لوحة المفاتيح (iOS 10+). يضغط المستخدم على زر الميكروفون، يقوم ASR بنسخ الكلام إلى نص وإدراجه في حقل النص. المتطلبات: نتائج جزئية (رؤية النص في الوقت الفعلي)، على الجهاز (يجب أن تعمل لوحة المفاتيح بدون إنترنت). SFSpeechRecognizer + AVSpeechSynthesizer — إدخال صوتي + إخراج صوتي. للوحات المفاتيح المخصصة على iOS 17+، استخدم على الجهاز. قيود ملحق لوحة المفاتيح: AVAudioEngine متاح ولكن مع قيود زمنية (التنفيذ في الخلفية محدود).
نسخ الاجتماعات والمحاضرات — تطبيقات لتسجيل ونسخ الصوت (Otter.ai، Rev، Apple Voice Memos). SFSpeechURLRecognitionRequest يعالج ملفات .m4a. للتسجيلات الطويلة (30–60 دقيقة) — Whisper Core ML (بدون حد للطول). segments من SFSpeechRecognizer مع الطوابع الزمنية — لمزامنة النص مع الصوت (تمييز النص أثناء التشغيل). الثقة لكل مقطع — لعرض الأجزاء غير الموثوقة (تمييز باللون الأصفر). للتمييز بين المتحدثين (من تحدث) — Apple لا توفر API، استخدم pyannote-audio + Whisper على الخادم.
الأوامر الصوتية في تطبيقات iOS — SFSpeechRecognizer + إطار VGS (Voice Grammar Services) لتنفيذ الأوامر: “افتح الإعدادات”، “أرسل رسالة”، “شغّل الضوء”. التعرف القائم على القواعد: SFSpeechRecognitionRequest contextualStrings = مصفوفة من الأوامر. هذا يحسن دقة التعرف على الأوامر إلى 95% (مقابل 85% للشكل الحر). SFSpeechRecognitionTask.cancel — للمقاطعة بعد تنفيذ الأمر. VGS + SFSpeechRecognizer + Shortcuts — أوامر صوتية مخصصة بدون كتابة واجهة مستخدم. لإمكانية الوصول: Voice Control (مدمج) + SFSpeechRecognizer (أوامر مخصصة).
// الأوامر الصوتية مع سلاسل سياقية
let request = SFSpeechAudioBufferRecognitionRequest()
request.requiresOnDeviceRecognition = true
request.shouldReportPartialResults = true
request.contextualStrings = ["open contacts", "send message",
"show notifications", "تشغيل الضوء"]
recognitionTask = recognizer.recognitionTask(with: request) { result, _ in
guard let text = result?.bestTranscription.formattedString.lowercased() else { return }
voiceCommands.first { text.contains($0) }.map { command in
DispatchQueue.main.async { self.executeCommand(command) }
recognitionTask?.cancel()
}
}
الإملاء في التطبيقات الطبية والقانونية — SFSpeechRecognizer لإنشاء مستندات منظمة بالصوت. تكييف المجال: contextualStrings مع مصطلحات طبية/قانونية (500+ عبارة). SFSpeechRecognitionRequest.customLmProbability — تأثير contextualStrings (0.1–1.0). للإملاء الطبي، استخدم على الجهاز (خصوصية بيانات المريض). Whisper مضبوط على بيانات طبية — بديل مع WER 5% بدلاً من 12% لـ SFSpeechRecognizer الأساسي. الامتثال HIPAA: وضع على الجهاز (البيانات لا تغادر الجهاز). لنسخ المواعيد — SFSpeechURLRecognitionRequest + segments مع طوابع زمنية للمتحدث.
الأسئلة الشائعة
SFSpeechRecognizer متاح منذ iOS 10 وmacOS 10.15 وwatchOS 6 وtvOS 17. وضع على الجهاز منذ iOS 17 (requiresOnDeviceRecognition). على iOS 10–16، يعمل SFSpeechRecognizer فقط من خلال خوادم السحابة من Apple (يتطلب إنترنت). جميع الإصدارات تتطلب إذنًا صريحًا من المستخدم (NSMicrophoneUsageDescription + NSSpeechRecognitionUsageDescription). SFSpeechRecognizer.supportedLocales — قائمة ديناميكية، تعتمد على المنطقة وطراز الجهاز.
نعم، عن طريق إنشاء recognitionTask جديدة بعد isFinal. أعد تشغيل المهمة بعد انتهاء السابقة للتعرف المستمر. على iOS 17، يستهلك ASR المستمر على الجهاز 2–5% من البطارية في الساعة (A15+). على iOS 16-، يتطلب ASR المستمر إنترنت (حركة مرور ~1 ميجابايت/دقيقة). للتعرف المستمر حقًا (الاستماع دائمًا)، استخدم Vosk (بدون اتصال) أو Whisper Core ML. SFSpeechRecognizer لا يدعم وضع التشغيل الدائم على iOS 16-.
استخدم result.bestTranscription.segments — كل SFTranscriptionSegment يحتوي على confidence (Float 0..1) للكلمة. segments[i].substring — نص الكلمة. segments[i].confidence — ثقة ASR في تلك الكلمة. الكلمات ذات confidence < 0.5 غير موثوقة — قم بتمييزها في واجهة المستخدم. segments[i].timestamp — وقت البدء (TimeInterval). segments[i].duration — المدة. segments[i].alternativeSubstrings — فرضيات التعرف البديلة للكلمة. للملفات الطويلة، التنقل عبر segments يعطي ثقة لكل كلمة بدون تحليل يدوي.
203 هو SFSpeechError.ErrorCode.opportunistic (لا يوجد إنترنت لـ ASR السحابي). يحدث على iOS 16- أو عندما request.requiresOnDeviceRecognition = false بدون إنترنت. الحل: قم بتعيين requiresOnDeviceRecognition = true (iOS 17+) للعمل بدون اتصال. على iOS 16-، استخدم NWPathMonitor — عند عدم وجود إنترنت، اعرض رسالة تقول “التعرف على الكلام يتطلب اتصالاً بالإنترنت”. بديل: Vosk (بدون اتصال، iOS 12+) كاحتياطي عند عدم توفر شبكة.
SFSpeechRecognizer — API مدمج من Apple، مجاني، سهل التكامل، ولكن مع حدود للطول (1–2 دقيقة)، دقة WER 7–14% وفقط لنظام iOS البيئي. Whisper Core ML — مفتوح المصدر (MIT)، يدعم 99 لغة، WER 6–10%، بدون حد للطول، ولكن يتطلب تكاملًا يدويًا، نماذج Core ML (39M–769M معامل)، RTF 0.5–6 (أبطأ من SFSpeechRecognizer). SFSpeechRecognizer — للإدخال الصوتي القياسي. Whisper — للنسخ عالي الدقة للصوت الطويل.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.