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

前端 未结 1 429
余生分开走
余生分开走 2020-12-06 03:46

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 possib

相关标签:
1条回答
  • 2020-12-06 04:17

    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.

    0 讨论(0)
提交回复
热议问题