I would like to know if it is possible to get an SMS broadcast when a text comes in. I also want to retrieve the whole body and sender info. I want to know if this is possible through Private Frameworks only without jailbreaking. I'm not going to sell the app, it's just for my personal phone but I'm trying to avoid the jailbreak cat and mouse.
1 Answers
Here is how I do it. No jailbreak required, only private APIs.
Private APIs declarations
CoreTelephony framework:
extern CFStringRef const kCTMessageReceivedNotification;
CFNotificationCenterRef CTTelephonyCenterGetDefault();
void CTTelephonyCenterAddObserver(CFNotificationCenterRef ct, void* observer, CFNotificationCallback callBack, CFStringRef name, const void *object, CFNotificationSuspensionBehavior sb);
void CTTelephonyCenterRemoveObserver(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object);
Private IMDPersistence framework:
int IMDMessageRecordGetMessagesSequenceNumber();
Private ChatKit framework: CKDBMessage
can be found here
Subscribing to incoming SMS notification
CTTelephonyCenterAddObserver(CTTelephonyCenterGetDefault(),
NULL,
TelephonyObserver,
kCTMessageReceivedNotification,
NULL,
CFNotificationSuspensionBehaviorHold);
As of iOS 8 you can't pass NULL
for notification name argument to receive all telephony notifications. You must tell it which notification you would like to observer, just like with darwin notifiction center.
The callback
void TelephonyObserver(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
if ([(__bridge NSString*)name isEqualToString:(__bridge NSString*)kCTMessageReceivedNotification])
{
SmsReceived();
}
}
Reading message contents
void SmsReceived()
{
int lastID = IMDMessageRecordGetMessagesSequenceNumber();
CKDBMessage* msg = [[CKDBMessage alloc] initWithRecordID:lastID];
}
What we are doing here. After we received notification that SMS was received we are getting the last row ID in the SMS database (lastID
). Then creating message object with that ID. msg
will contain all the message contents.
Using CKDBMessage
and initWithRecordID:
you can access any SMS database record. If row ID is not found initWithRecordID:
will return nil.
Works on iOS 7.x - 9.1. Tested only on SMS messages but should work with MMS as well. User in comments tested successfully on iMessages.
iOS 8.3 UPDATE
As of iOS 8.3 you can't receive kCTMessageReceivedNotification
notification without jailbreak. You need entitlement
<key>com.apple.CommCenter.fine-grained</key>
<array>
<string>spi</string>
</array>
iOS 11 update
As of iOS 11 you can't use CKDBMessage
. Apple added another rule to the sandbox and probably requires the app to be signed with specific entitlement to be able to use that API.

- 9,400
- 1
- 30
- 47
-
Thanks creker. It going to be a few weeks before I get a chance to tackle this but I really appreciate it. In the mean time if anyone verifies that this works/doesn't work with ios 8 and/or iMessages that would be a big help. – John Smith Oct 30 '14 at 04:44
-
Works with sms and iMessage under iOS 8.1.2... @creker is there also an event for outgoing sms?! – davidOhara Jan 27 '15 at 14:22
-
@davidOhara, should be `kCTMessageSentNotification`. Please report your test results with it. – creker Jan 27 '15 at 15:34
-
@creker Is it also possible to get the duration of sending or receiving a message?! – davidOhara Jan 28 '15 at 11:27
-
@davidOhara, duration? – creker Jan 28 '15 at 14:49
-
@davidOhara, don't think so. Don't event see it in the database - there is `date_delivered` column but it's zero for every row. – creker Jan 28 '15 at 15:09
-
Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/69744/discussion-between-davidohara-and-creker). – davidOhara Jan 28 '15 at 15:11
-
@creker would you come to chat please?! – davidOhara Jan 28 '15 at 15:17
-
@creker I am stuck with trying to call `IMDMessageRecordGetMessagesSequenceNumber`, I can't seem to figure out how to declare/call it... I have tried everything from not declaring ("implicit declaration.. in C99" error), in the .h, in the .m, adding `IMDPersistence.framework` (gives `clang error framework not found`)... I have managed to call the `CT` functions by adding the `ATCall.h` header which contains these functions, and it works and send me a notification when receiving texts, but I can't figure out a way to compile with this function to get the message ID... – Aviel Gross Mar 19 '15 at 12:40
-
@AvielGross Were you able to figure it out? – damirstuhec May 31 '15 at 11:11
-
@damirstuhec yes, please see these answers I wrote about this: http://stackoverflow.com/a/29191820/2242359 http://stackoverflow.com/a/29191737/2242359 – Aviel Gross May 31 '15 at 13:26