SFSpeechRecognizer — το κύριο API της Apple για αναγνώριση ομιλίας στο οικοσύστημα iOS. Το πλαίσιο παρέχει πρόσβαση στον κινητήρα ASR της συσκευής μέσω του Speech.framework, υποστηρίζοντας ροή μεταγραφής σε πραγματικό χρόνο και εφάπαξ αναγνώριση αρχείων ήχου. Το SFSpeechRecognizer είναι διαθέσιμο σε iOS 10+, macOS 10.15+, watchOS 6+ και tvOS 17+. Με το iOS 17 η Apple πρόσθεσε μια πλήρη λειτουργία on-device που επιτρέπει την αναγνώριση ομιλίας χωρίς σύνδεση στο διαδίκτυο. Σύμφωνα με το 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 με χρονικές σημάνσεις, confidence, substringRange, alternativeSubstrings). Confidence για κάθε τμήμα (0..1) — επιτρέπει το φιλτράρισμα αναξιόπιστων τμημάτων. segments — βασικό χαρακτηριστικό του Speech.framework: παρέχει σχολιασμό κάθε λέξης με βεβαιότητα.
Αρχιτεκτονική SFSpeechRecognizer: AVFoundation (σύλληψη ήχου) → Audio Buffer → SFSpeechAudioBufferRecognitionRequest → SFSpeechRecognizer (κινητήρας ASR) → SFSpeechRecognitionResult → SFSpeechRecognitionTask (έλεγχος: cancel, finish, pause). Ο κινητήρας ASR της Apple χρησιμοποιεί υβριδική αρχιτεκτονική: Conformer (κωδικοποιητής) + RNNT (αποκωδικοποιητής) για on-device, Transducer για cloud. Τα μοντέλα είναι βελτιστοποιημένα για Apple Neural Engine (ANE). Στο A17 Pro το on-device ASR λειτουργεί με RTF 0.3–0.6 (ταχύτερο από πραγματικό χρόνο).
| Στοιχείο | Σκοπός | Έκδοση iOS |
|---|---|---|
| SFSpeechRecognizer | Κύρια κλάση αναγνώρισης | iOS 10+ |
| SFSpeechAudioBufferRecognitionRequest | Ζωντανή ροή ήχου | iOS 10+ |
| SFSpeechURLRecognitionRequest | Αρχείο ήχου (.wav, .m4a) | iOS 10+ |
| SFSpeechRecognitionTask | Διαχείριση αιτήματος (cancel, finish) | iOS 10+ |
| On-device recognition | ASR εκτός σύνδεσης | iOS 17+ |
| Combined Recognition | Υβριδικό on-device + cloud | iOS 17+ |
Απαιτήσεις ήχου: Το SFSpeechRecognizer δέχεται LPCM (16 kHz, 16 bit, mono) ή Opus (iOS 17+). Το AVFoundation μπορεί να συλλάβει buffer σε οποιαδήποτε μορφή, το αίτημα μετατρέπει αυτόματα. Ελάχιστο μήκος: 0,5 δευτερόλεπτα (ανίχνευση σιωπής). Μέγιστο: 1 λεπτό (cloud) / 2 λεπτά (on-device) ανά αίτημα. Για μεγάλη μεταγραφή, διαιρέστε τον ήχο σε κομμάτια 30–60 δευτερολέπτων με επικάλυψη 2–5 δευτερολέπτων.
Άδειες χρήστη: Το SFSpeechRecognizer απαιτεί δύο ρητές άδειες. NSMicrophoneUsageDescription (Privacy — Microphone Usage Description) — για πρόσβαση στο μικρόφωνο. NSSpeechRecognitionUsageDescription (Privacy — Speech Recognition Usage Description) — για πρόσβαση στην αναγνώριση ομιλίας. Και οι δύο είναι συμβολοσειρές που εξηγούν στο χρήστη γιατί. SFSpeechRecognizer.requestAuthorization — κλήση του διαλόγου άδειας. Καταστάσεις: notDetermined, denied, restricted, authorized. Χωρίς authorized η κλήση recognizer επιστρέφει σφάλμα 216 (Speech framework error).
Έλεγχος διαθεσιμότητας: SFSpeechRecognizer.isAvailable — ελέγχει εάν το ASR είναι διαθέσιμο για την τρέχουσα γλώσσα. Σε iOS 16- isAvailable = false χωρίς διαδίκτυο. Σε iOS 17+ isAvailable = true για γλώσσες on-device ακόμη και εκτός σύνδεσης. 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 καλείται με completion handler που μπορεί να επιστρέψει Error. Κύρια σφάλματα: 203 — no internet (cloud, iOS 16-); 216 — not authorized (χωρίς άδεια); 301 — audio error (πρόβλημα μικροφώνου/μορφής); 401 — service unavailable (υπερφόρτωση υπηρεσίας); 601 — language unavailable (γλώσσα δεν υποστηρίζεται στη συσκευή). Για on-device iOS 17+ κύρια σφάλματα: 301 (audio), 601 (language). Πάντα να διαχειρίζεστε το completion handler — τα σφάλματα μπορεί να προκύψουν οποιαδήποτε στιγμή κατά την εγγραφή.
Live ASR pipeline: AVAudioEngine (σύλληψη από μικρόφωνο) → installTap (buffer ήχου) → request.append(buffer) → SFSpeechRecognizer → recognitionTask → delegate/resultHandler. Το AVAudioEngine εξασφαλίζει χαμηλή καθυστέρηση (5–10 ms από μικρόφωνο σε buffer). SFSpeechRecognitionDelegate: didHypothesizeTranscription (κάθε 200–500 ms — μερικό κείμενο), didFinishRecognition (τελικό αποτέλεσμα). Task.isFinishing — μπορεί να ακυρωθεί όταν ολοκληρωθεί η αναγνώριση. Για συνεχή αναγνώριση (ατελείωτη υπαγόρευση) — δημιουργήστε νέο task μετά το isFinal.
SFSpeechRecognitionTaskDelegate: προαιρετικές μέθοδοι. speechRecognitionDidDetectSpeech (έναρξη ομιλίας) — για ένδειξη UI. didHypothesizeTranscription (προσωρινό κείμενο) — για εμφάνιση κατά την ομιλία. didFinishRecognition (τελικό αποτέλεσμα) — για καταγραφή κειμένου. didFinishSuccessfully (επιτυχία/σφάλμα) — για ολοκλήρωση. didProcessAudio (buffer ήχου επεξεργάστηκε) — για μετρητή 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 με on-device καταναλώνει 2–5% μπαταρία ανά ώρα (A15+).
SFSpeechURLRecognitionRequest — αίτημα για αναγνώριση αρχείου ήχου μέσω URL. Υποστηρίζει μορφές: .wav (16 kHz, 16 bit, mono), .m4a (AAC), .mp4, .mov. Μέγιστο μήκος: ~1 λεπτό για cloud, ~2 λεπτά για on-device. Για μεγαλύτερα αρχεία — διαιρέστε σε κομμάτια (AVAssetExportSession + trim). Το SFSpeechURLRecognitionRequest δεν υποστηρίζει ροή (χωρίς μερικά αποτελέσματα) — μόνο τελικό αποτέλεσμα. Για μερικά αποτελέσματα με αρχείο — μετατρέψτε σε Audio Buffer Request.
Λήψη μεταγραφής αρχείου ήχου: SFSpeechRecognizer.recognitionTask(with: request) resultHandler. Εξάγετε το bestTranscription.formattedString. Για χρονικές σημάνσεις σε επίπεδο λέξης — segments από bestTranscription.segments (segment.duration, segment.timestamp, segment.substring). Confidence ανά τμήμα — βεβαιότητα ASR σε κάθε λέξη (χρησιμοποιήστε για φιλτράρισμα). Εναλλακτικές παραλλαγές — εναλλακτικές transcriptionFormatter για λέξεις με χαμηλό confidence. Για αρχεία με πολλούς ομιλητές — το 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)
}
}
Κοπή μεγάλων αρχείων ήχου: για αρχεία > 1 λεπτού κόψτε σε κομμάτια 30–60 δευτερολέπτων με επικάλυψη 2–3 δευτερολέπτων (σύνδεση). AVAssetExportSession + CMTimeRange — εξαγωγή κομματιών. Εναλλακτική: UISelectionView (ο χρήστης επιλέγει τμήμα). Σύνδεση μεταγραφών: συνένωση κειμένων, σύνδεση μέσω επικάλυψης (τελευταίες 2–3 λέξεις προηγούμενου κομματιού συγκρίνονται με πρώτες 2–3 λέξεις επόμενου — αφαίρεση διπλοτύπων). Τα Vosk και Whisper υποστηρίζουν μεγάλο ήχο εγγενώς, το SFSpeechRecognizer — όχι. Για μεγάλη μεταγραφή συνιστώ το Whisper (Core ML) — χωρίς περιορισμό μήκους.
Λειτουργία On-device (iOS 17+): request.requiresOnDeviceRecognition = true. Το ASR εκτελείται τοπικά στο Apple Neural Engine (ANE). Πλεονεκτήματα: χωρίς διαδίκτυο, ιδιωτικότητα (ο ήχος δεν φεύγει από τη συσκευή), μηδενικό κόστος (δωρεάν), χαμηλή καθυστέρηση (RTF 0.3–0.6). Μειονεκτήματα: χαμηλότερη ακρίβεια (WER 12–14% vs 7–12%), περιορισμός 2 λεπτών ανά αίτημα, περιορισμένο σύνολο γλωσσών (δεν είναι διαθέσιμες και οι 60 γλώσσες on-device). Το μοντέλο on-device καταλαμβάνει ~50–100 MB στη συσκευή, φορτώνεται στο πρώτο αίτημα.
Cloud (iOS 16-): request.requiresOnDeviceRecognition = false (ή λείπει η παράμετρος). ASR στους διακομιστές Apple — ακριβέστερος (WER 7% EN, 12% RU), περισσότερες γλώσσες, έως 1 λεπτό ανά αίτημα. Απαιτεί διαδίκτυο (WiFi ή κινητό). Η Apple δεν χρεώνει τον προγραμματιστή για cloud ASR (δωρεάν). Όρια: 1 αίτημα ανά λεπτό ανά εφαρμογή (απροσδιόριστο), αλλά για κλίμακα παραγωγής η Apple μπορεί να περιορίσει. cloud ASR — ποιότητα best-effort, χωρίς SLA. Για εταιρικές εφαρμογές χρησιμοποιήστε Google Cloud ASR ή Whisper (Core ML).
| Παράμετρος | On-device (iOS 17+) | Cloud (iOS 10+) |
|---|---|---|
| Απαιτεί διαδίκτυο | Όχι | Ναι |
| WER (EN) | 10–12% | 7% |
| WER (RU) | 12–14% | 12% |
| Καθυστέρηση (RTF) | 0.3–0.6 | 0.3–0.8 (+δίκτυο) |
| Μέγ. μήκος | 2 λεπτά | 1 λεπτό |
| Ιδιωτικότητα | Πλήρης | Ο ήχος πηγαίνει στον διακομιστή |
| Δωρεάν | Ναι | Ναι |
Combined Recognition (iOS 17+): request.requiresOnDeviceRecognition = false με διαδίκτυο (cloud), = true εκτός σύνδεσης (fallback). Η Apple επιλέγει αυτόματα λειτουργία. Για εφαρμογές κρίσιμες για ακρίβεια: ελέγξτε το NetworkMonitor (NWPathMonitor) — με διαδίκτυο cloud, χωρίς αυτό on-device. Για εφαρμογές κρίσιμες για ιδιωτικότητα: πάντα on-device. Για μεταγραφή: cloud (ακριβέστερος). Για φωνητική είσοδο: on-device (ταχύτερος). Συνιστάται Combined: 80% cloud, 20% on-device fallback.
Φωνητική είσοδος σε προσαρμοσμένο πληκτρολόγιο — το SFSpeechRecognizer είναι ενσωματωμένο σε επεκτάσεις πληκτρολογίου (iOS 10+). Ο χρήστης πατάει το κουμπί μικροφώνου — το ASR μεταγράφει την ομιλία σε κείμενο και το εισάγει στο πεδίο κειμένου. Απαιτήσεις: μερικά αποτελέσματα (βλέπει το κείμενο σε πραγματικό χρόνο), on-device (το πληκτρολόγιο πρέπει να λειτουργεί χωρίς διαδίκτυο). SFSpeechRecognizer + AVSpeechSynthesizer — φωνητική είσοδος + φωνητική έξοδος. Για προσαρμοσμένο πληκτρολόγιο σε iOS 17+ χρησιμοποιήστε on-device. Περιορισμοί επέκτασης πληκτρολογίου: το AVAudioEngine είναι διαθέσιμο, αλλά με χρονικούς περιορισμούς (background execution limited).
Μεταγραφή συναντήσεων και διαλέξεων — εφαρμογές για εγγραφή και μεταγραφή ήχου (Otter.ai, Rev, Apple Voice Memos). Το SFSpeechURLRecognitionRequest επεξεργάζεται το αρχείο .m4a. Για μεγάλες εγγραφές (30–60 λεπτά) — Whisper Core ML (χωρίς περιορισμό μήκους). Τμήματα SFSpeechRecognizer με χρονικές σημάνσεις — για συγχρονισμό κειμένου με ήχο (επισήμανση κειμένου κατά την αναπαραγωγή). Confidence ανά τμήμα — για εμφάνιση αναξιόπιστων τμημάτων (κίτρινη επισήμανση). Για διαχωρισμό ομιλητών (ποιος μίλησε) — η Apple δεν παρέχει API, χρησιμοποιήστε pyannote-audio + Whisper στον διακομιστή.
Φωνητικές εντολές σε εφαρμογές iOS — SFSpeechRecognizer + VGS framework (Voice Grammar Services) για εκτέλεση εντολών: “ανοίξτε τις ρυθμίσεις”, “στείλτε μήνυμα”, “ανάψτε το φως”. Αναγνώριση βάσει γραμματικής: SFSpeechRecognitionRequest contextualStrings = συστοιχία εντολών. Αυτό αυξάνει την ακρίβεια αναγνώρισης εντολών στο 95% (έναντι 85% free-form). 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 για δημιουργία δομημένων εγγράφων με φωνή. Domain Adaptation: contextualStrings με ιατρικούς/νομικούς όρους (500+ φράσεις). SFSpeechRecognitionRequest.customLmProbability — επίδραση contextualStrings (0.1–1.0). Για ιατρική υπαγόρευση χρησιμοποιήστε on-device (ιδιωτικότητα δεδομένων ασθενούς). Whisper fine-tuned σε ιατρικά δεδομένα — εναλλακτική με WER 5% αντί 12% του βασικού SFSpeechRecognizer. Συμμόρφωση HIPAA: λειτουργία on-device (τα δεδομένα δεν φεύγουν από τη συσκευή). Για μεταγραφή επισκέψεων — SFSpeechURLRecognitionRequest + segments με χρονικές σημάνσεις ομιλητή.
Συχνές ερωτήσεις
SFSpeechRecognizer είναι διαθέσιμο από iOS 10, macOS 10.15, watchOS 6 και tvOS 17. Λειτουργία on-device — από iOS 17 (requiresOnDeviceRecognition). Σε iOS 10–16 το SFSpeechRecognizer λειτουργεί μόνο μέσω διακομιστών cloud Apple (απαιτεί διαδίκτυο). Σε όλες τις εκδόσεις απαιτείται ρητή άδεια χρήστη (NSMicrophoneUsageDescription + NSSpeechRecognitionUsageDescription). SFSpeechRecognizer.supportedLocales — δυναμική λίστα, εξαρτάται από την περιοχή και το μοντέλο συσκευής.
Ναι, με δημιουργία νέου recognitionTask μετά το isFinal. Επανεκκινήστε την εργασία μετά την ολοκλήρωση της προηγούμενης για συνεχή αναγνώριση. Σε iOS 17 η συνεχής on-device ASR καταναλώνει 2–5% μπαταρία ανά ώρα (A15+). Σε iOS 16- η συνεχής ASR απαιτεί διαδίκτυο (κατανάλωση δεδομένων ~1 MB/λεπτό). Για πραγματικά συνεχή αναγνώριση (πάντα ακούει) χρησιμοποιήστε 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 — αναξιόπιστες, επισημάνετέ τις στο UI. segments[i].timestamp — χρόνος έναρξης (TimeInterval). segments[i].duration — διάρκεια. segments[i].alternativeSubstrings — εναλλακτικές παραλλαγές αναγνώρισης λέξης. Για μεγάλα αρχεία, η επανάληψη στα segments δίνει per-word confidence χωρίς χειροκίνητη ανάλυση.
203 — είναι SFSpeechError.ErrorCode.opportunistic (χωρίς διαδίκτυο για cloud ASR). Συμβαίνει σε iOS 16- ή με request.requiresOnDeviceRecognition = false χωρίς διαδίκτυο. Λύση: ορίστε requiresOnDeviceRecognition = true (iOS 17+) για λειτουργία εκτός σύνδεσης. Σε iOS 16- χρησιμοποιήστε NWPathMonitor — όταν δεν υπάρχει διαδίκτυο εμφανίστε μήνυμα “για αναγνώριση ομιλίας απαιτείται διαδίκτυο”. Εναλλακτική: Vosk (εκτός σύνδεσης, iOS 12+) ως fallback όταν δεν υπάρχει δίκτυο.
SFSpeechRecognizer — ενσωματωμένο Apple API, δωρεάν, εύκολο στην ενσωμάτωση, αλλά με περιορισμό μήκους (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. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης