简体   繁体   中英

Get SMS broadcast with text body without Jailbreak BUT private frameworks in IOS

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM