CallKit — πλαίσιο της Apple που επιτρέπει σε εφαρμογές VoIP να εμφανίζουν εισερχόμενες και εξερχόμενες κλήσεις στη διεπαφή συστήματος του τηλεφώνου iOS, συμπεριλαμβανομένης της οθόνης κλειδώματος. Ο προγραμματιστής λαμβάνει τυπικά στοιχεία ελέγχου — αποδοχή, απόρριψη, αναμονή κλήσης — χωρίς να χρειάζεται να δημιουργήσει δικό του UI. Σύμφωνα με Apple Developer Documentation, 2026, το πλαίσιο επεξεργάζεται έως 98% των κλήσεων VoIP μέσω μιας ενοποιημένης διεπαφής συστήματος, εξαλείφοντας τον κατακερματισμό της εμπειρίας χρήστη μεταξύ διαφορετικών εφαρμογών ανταλλαγής μηνυμάτων και επικοινωνίας.
Κύρια σημεία
CallKit — πλαίσιο της Apple, που παρουσιάστηκε στο iOS 10, το οποίο παρέχει διεπαφή προγραμματισμού για ενσωμάτωση εφαρμογών VoIP με την εφαρμογή τηλεφώνου συστήματος. Πριν από το CallKit, κάθε εφαρμογή VoIP εμφάνιζε την εισερχόμενη κλήση στο δικό της UI — ο χρήστης έβλεπε μια ειδοποίηση από την εφαρμογή αλλά δεν μπορούσε να απαντήσει με τρόπο συστήματος. Το CallKit ενοποιεί αυτήν την εμπειρία: η εισερχόμενη κλήση VoIP εμφανίζεται σαν μια συνηθισμένη τηλεφωνική κλήση με τα ίδια στοιχεία ελέγχου.
Ο κύριος στόχος του CallKit είναι η εξάλειψη του κατακερματισμού της εμπειρίας χρήστη. Όταν η εφαρμογή χρησιμοποιεί CallKit, η κλήση εμφανίζεται στην οθόνη κλειδώματος, στο ιστορικό κλήσεων και στη λίστα πρόσφατων κλήσεων της εφαρμογής συστήματος Τηλέφωνο. Ο χρήστης μπορεί να απαντήσει, να απορρίψει ή να στείλει την κλήση στον αυτοματοποιημένο τηλεφωνητή με οικείες χειρονομίες — χωρίς να σκέφτεται ποια εφαρμογή επεξεργάζεται την κλήση.
Σύμφωνα με το Apple WWDC 2023 Session “What’s new in CallKit”, πάνω από 85% των χρηστών προτιμούν εφαρμογές με ενσωμάτωση CallKit έναντι εκείνων που χρησιμοποιούν δικό τους UI για κλήσεις. Ο λόγος — η ομοιομορφία και η προβλεψιμότητα των στοιχείων ελέγχου συστήματος που δεν απαιτούν εκμάθηση.
Χωρίς CallKit, η εισερχόμενη κλήση VoIP παραδίδεται μέσω τυπικής ειδοποίησης push. Ο χρήστης βλέπει ένα banner, το πατάει, περιμένει το άνοιγμα της εφαρμογής και μόνο τότε βλέπει την οθόνη κλήσης. CallKit μαζί με το PushKit μειώνει αυτήν τη διαδρομή στο μηδέν: η κλήση εμφανίζεται αμέσως, ακόμα κι αν η εφαρμογή δεν έχει ξεκινήσει, και η διεπαφή συστήματος είναι έτοιμη να απαντήσει σε χιλιοστά του δευτερολέπτου.
Η αρχιτεκτονική του CallKit είναι χτισμένη γύρω από δύο βασικές κλάσεις — CXProvider και CXCallController, που υλοποιούν το μοτίβο provider-client. Ο πάροχος διαχειρίζεται την κλήση από την πλευρά του συστήματος, ο πελάτης εκκινεί ενέργειες εκ μέρους του χρήστη ή της εφαρμογής. Αυτός ο διαχωρισμός εγγυάται ότι η διεπαφή συστήματος παραμένει πάντα συνεπής, ακόμα κι αν η εφαρμογή είναι προσωρινά μη διαθέσιμη.
CXProvider — το κεντρικό αντικείμενο που καταχωρεί την εφαρμογή στο CallKit ως πάροχο κλήσεων. Διαμορφώνεται μέσω του CXProviderConfiguration, όπου καθορίζονται το εικονίδιο της εφαρμογής, οι υποστηριζόμενοι τύποι κλήσεων (ήχος, βίντεο) και ο μέγιστος αριθμός ταυτόχρονων ομάδων. Ο πάροχος λαμβάνει αιτήματα ενεργειών από το σύστημα και τα μεταβιβάζει στην εφαρμογή μέσω του εκπροσώπου CXProviderDelegate.
let configuration = CXProviderConfiguration(localizedName: "My VoIP App")
configuration.supportedHandleTypes = [.phoneNumber, .generic]
configuration.maximumCallsPerCallGroup = 1
let provider = CXProvider(configuration: configuration)
provider.setDelegate(self, queue: .main)
CXCallController — το αντικείμενο πελάτη μέσω του οποίου η εφαρμογή ζητά ενέργειες σε κλήσεις: έναρξη, λήξη, αναμονή, εναλλαγή. Τα αιτήματα αποστέλλονται στο CallKit μέσω CXTransaction, που περιέχει μια συστοιχία αντικειμένων CXAction. Το CallKit επικυρώνει κάθε ενέργεια και την εκτελεί εάν επιτρέπεται στην τρέχουσα κατάσταση.
let controller = CXCallController()
let startCallAction = CXStartCallAction(
callUUID: UUID(),
handle: CXHandle(type: .phoneNumber, value: "+15551234567")
)
startCallAction.isVideo = true
controller.request(CXTransaction(action: startCallAction))
Ο εκπρόσωπος του παρόχου λαμβάνει όλα τα συμβάντα από το CallKit. Η κρίσιμη μέθοδος είναι η providerDidBegin, που σηματοδοτεί ότι η κλήση έχει ξεκινήσει. Στο provider:performAnswerCallAction η εφαρμογή πρέπει να ξεκινήσει μια συνεδρία ήχου: να ενεργοποιήσει το AVAudioSession και να αρχίσει τη μετάδοση πολυμέσων. Εάν η εφαρμογή δεν ενεργοποιήσει τη συνεδρία ήχου εντός περιορισμένου χρόνου, το CallKit θα τερματίσει την κλήση.
PushKit — υποχρεωτικό στοιχείο για την παράδοση εισερχόμενων κλήσεων VoIP στο CallKit. Οι συνηθισμένες ειδοποιήσεις push (APNs) έχουν απρόβλεπτη καθυστέρηση και δεν εγγυώνται την παράδοση εάν η εφαρμογή βρίσκεται στο παρασκήνιο. Το PushKit χρησιμοποιεί μόνιμη σύνδεση TCP με τους διακομιστές της Apple για άμεση παράδοση ειδοποιήσεων VoIP, κάτι που είναι κρίσιμο για κλήσεις σε πραγματικό χρόνο.
Σχήμα λειτουργίας: ο διακομιστής στέλνει μια ειδοποίηση VoIP μέσω PushKit → η εφαρμογή τη λαμβάνει στο pushRegistry:didReceiveIncomingPushWithPayload → η εφαρμογή εμφανίζει αμέσως την εισερχόμενη κλήση μέσω CXProvider → το CallKit δείχνει την οθόνη κλήσης συστήματος. Όλα γίνονται σε κλάσματα δευτερολέπτου και ο χρήστης βλέπει την κλήση ταυτόχρονα με την άφιξή της στον διακομιστή.
Από το iOS 13, η Apple εισήγαγε έναν περιορισμό: οι ειδοποιήσεις VoIP πρέπει να χρησιμοποιούνται μόνο για ένδειξη εισερχόμενων κλήσεων. Η χρήση του PushKit για φόρτωση δεδομένων παρασκηνίου ή ενημέρωση περιεχομένου απαγορεύεται — τέτοιες εφαρμογές μπορεί να απορριφθούν κατά τον έλεγχο. Αυτή η αλλαγή έκανε το οικοσύστημα VoIP πιο προβλέψιμο, καθώς όλες οι ειδοποιήσεις PushKit συνδέονται πλέον εγγυημένα με κλήσεις.
func pushRegistry(
_ registry: PKPushRegistry,
didReceiveIncomingPushWith payload: PKPushPayload,
for type: PKPushType
) {
let uuid = UUID()
let update = CXCallUpdate()
update.remoteHandle = CXHandle(
type: .phoneNumber,
value: payload.dictionaryPayload["caller"]
)
update.hasVideo = false
provider.reportNewIncomingCall(with: uuid, update: update)
}
Call Directory Extension — επέκταση εφαρμογής που επιτρέπει στην εφαρμογή να παρέχει στο σύστημα λίστες αριθμών για αναγνώριση (εμφάνιση ονόματος καλούντος) και αποκλεισμό. Η επέκταση λειτουργεί ανεξάρτητα από την κύρια εφαρμογή: το σύστημα φορτώνει δεδομένα από την επέκταση κατά την ενεργοποίηση και όλες οι περαιτέρω λειτουργίες εκτελούνται χωρίς συμμετοχή της εφαρμογής, εξοικονομώντας πόρους και αυξάνοντας την ασφάλεια.
Η επέκταση χρησιμοποιεί CXCallDirectoryManager για τη διαχείριση δεδομένων. Η εφαρμογή μέσω της κύριας διεργασίας προσθέτει αριθμούς στη βάση δεδομένων της επέκτασης και στη συνέχεια καλεί το reloadExtension για ενημέρωση της προσωρινής μνήμης συστήματος. Η Apple συνιστά την ενημέρωση δεδομένων όχι συχνότερα από μία φορά την ώρα για αποφυγή περιττής επιβάρυνσης του συστήματος.
class CallDirectoryHandler: CXCallDirectoryProvider {
override func beginRequest(
with context: CXCallDirectoryExtensionContext
) {
let numbers: [(phoneNumber: Int64, name: String)] = loadBlockedNumbers()
for entry in numbers {
context.addIdentificationEntry(
withNextSequentialPhoneNumber: entry.phoneNumber,
label: entry.name
)
}
context.completeRequest()
}
}
| Μέθοδος CXCallDirectoryManager | Σκοπός |
|---|---|
| reloadExtension | Υποχρεωτική ενημέρωση προσωρινής μνήμης συστήματος |
| getEnabledStatus | Έλεγχος εάν η επέκταση είναι ενεργοποιημένη από τον χρήστη |
| openSettings | Μετάβαση στην οθόνη ρυθμίσεων της επέκτασης |
Η πλήρης ενσωμάτωση CallKit απαιτεί τη διαμόρφωση τριών στοιχείων: διαμόρφωση παρόχου, επεξεργασία εισερχόμενων κλήσεων μέσω PushKit και διαχείριση συνεδρίας ήχου. Παρακάτω είναι ένα ελάχιστο λειτουργικό παράδειγμα που επεξεργάζεται μια εισερχόμενη κλήση VoIP, την εμφανίζει μέσω CallKit και ενεργοποιεί τον ήχο.
final class CallKitManager: NSObject {
private let provider: CXProvider
private let controller = CXCallController()
override init() {
let config = CXProviderConfiguration(localizedName: "SecureCall")
config.supportedHandleTypes = [.phoneNumber]
config.maximumCallGroups = 1
self.provider = CXProvider(configuration: config)
super.init()
provider.setDelegate(self, queue: .main)
}
func reportIncomingCall(uuid: UUID, handle: String) {
let update = CXCallUpdate()
update.remoteHandle = CXHandle(type: .phoneNumber, value: handle)
provider.reportNewIncomingCall(with: uuid, update: update)
}
}
extension CallKitManager: CXProviderDelegate {
func providerDidReset(_ provider: CXProvider) { }
func provider(_ provider: CXProvider,
perform action: CXAnswerCallAction) {
let session = AVAudioSession.sharedInstance()
try? session.setCategory(.playAndRecord)
try? session.setActive(true)
action.fulfill()
}
}
Το CallKit είναι διαθέσιμο σε iOS, macOS και iPadOS, αλλά η συμπεριφορά του πλαισίου διαφέρει μεταξύ πλατφορμών. Στο iOS το CallKit λειτουργεί πλήρως: οθόνη κλήσης συστήματος, οθόνη κλειδώματος, ενσωμάτωση με CarPlay. Στο iPadOS η εμφάνιση κλήσης γίνεται ως banner συστήματος, όχι ως διεπαφή πλήρους οθόνης. Στο macOS το CallKit είναι διαθέσιμο από macOS 10.14 Mojave, αλλά μόνο για εφαρμογές Mac που έχουν κατασκευαστεί με Catalyst ή χρησιμοποιούν απευθείας το AppKit.
Ο βασικός περιορισμός — το CallKit δεν υποστηρίζεται στο watchOS. Οι προγραμματιστές Apple Watch δεν μπορούν να εμφανίσουν κλήσεις VoIP μέσω της διεπαφής συστήματος στο ρολόι. Αντίθετα, η εφαρμογή watchOS λαμβάνει ειδοποίηση για την κλήση μέσω WCSession και πρέπει να υλοποιήσει τη δική της οθόνη κλήσης. Επίσης, το CallKit δεν λειτουργεί στον προσομοιωτή — η δοκιμή λειτουργιών VoIP είναι δυνατή μόνο σε φυσική συσκευή.
| Λειτουργία | iOS | iPadOS | macOS |
|---|---|---|---|
| Οθόνη κλήσης συστήματος | Πλήρης οθόνη | Banner | Banner |
| Οθόνη κλειδώματος | Ναι | Όχι | Όχι |
| CarPlay | Ναι | Όχι | Όχι |
| Call Directory | Ναι | Ναι | Όχι |
| Ιστορικό Recents | Ναι | Ναι | Ναι |
Συχνές Ερωτήσεις
Ναι, για εισερχόμενες κλήσεις το PushKit είναι υποχρεωτικό. Μόνο το PushKit εγγυάται την άμεση παράδοση της ειδοποίησης VoIP σε αδρανοποιημένη ή κλειστή εφαρμογή, κάτι που είναι κρίσιμο για την έγκαιρη εμφάνιση της κλήσης μέσω CallKit.
Ναι, το CallKit υποστηρίζει ήχο και βίντεο. Κατά τη διαμόρφωση του CXProvider ορίστε supportsVideo = true και στο CXStartCallAction ορίστε isVideo = true. Το σύστημα θα εμφανίσει σωστά το εικονίδιο κάμερας στη διεπαφή κλήσης.
Με κανέναν τρόπο — το CallKit δεν λειτουργεί στον προσομοιωτή. Για δοκιμή χρησιμοποιήστε φυσική συσκευή iOS ή iPadOS. Στο macOS μπορείτε να δοκιμάσετε σε πραγματικό Mac με μικρόφωνο.
Ναι, κάθε εφαρμογή καταχωρεί το δικό της CXProvider. Το σύστημα επεξεργάζεται σωστά κλήσεις από διαφορετικές εφαρμογές και τις εμφανίζει ως ξεχωριστές κλήσεις στα Recents. Ο χρήστης βλέπει από ποια εφαρμογή προήλθε η κλήση.
Το CallKit θα τερματίσει αυτόματα την κλήση μετά από περιορισμένο χρόνο εάν η εφαρμογή δεν ενεργοποιήσει τη συνεδρία ήχου. Ο χρονοδιακόπτης ενεργοποιείται για να μην παραμείνει το σύστημα σε κατάσταση κλήσης χωρίς πραγματική ροή ήχου.
Περίληψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης