使用ios4.x我可以使用以下代码获取“kCTMessageReceivedNotification”通知时的消息
CTTelephonyCenterAddObserver( ct, NULL, callback,NULL,NULL, CFNotificationSuspensionBehaviorHold);
if ([notifyname isEqualToString:@"kCTMessageReceivedNotification"])//receive message
{
NSDictionary *info = (NSDictionary *)userInfo;
CFNumberRef msgID = (CFNumberRef)[info objectForKey:@"kCTMessageIdKey"];
int result;
CFNumberGetValue((CFNumberRef)msgID, kCFNumberSInt32Type, &result);
Class CTMessageCenter = NSClassFromString(@"CTMessageCenter");
id mc = [CTMessageCenter sharedMessageCenter];
id incMsg = [mc incomingMessageWithId: result];}
但是对于ios5我不能这样做因为incMsg是nil,所以我能做些什么来获取消息?
由于
答案 0 :(得分:8)
这是我发现的......
只需查看转储的私有API,看起来 ChatKit.framework 可能有所帮助。看一眼 CKSMSService.h
或CKMadridService.h表示iMessage消息。
CKSMSService
中有几种方法,我很快就试图调整自己的方法:
- (void)_receivedMessage: (id)arg1 replace:(BOOL)arg2 replacedRecordIdentifier:(int)arg3 postInternalNotification:(BOOL)arg4;
- (void)_receivedMessage: (id)arg1 replace:(BOOL)arg2 postInternalNotification:(BOOL)arg3;
但在iOS 5.0.1上我没有看到其中任何一个被调用(也许是我的错误?)。所以,我试图直接从sqlite SMS数据库中获取消息。注意...我没有构建完整的应用程序,注册通知。我假设你的代码让kCTMessageReceivedNotification
没问题......它只是不再给你短信内容了。因此,如果您将以下代码放在通知处理程序中,您应该能够看到消息文本:
- (NSString *) mostRecentSMS {
NSString *text = @"";
sqlite3 *database;
if(sqlite3_open([@"/private/var/mobile/Library/SMS/sms.db" UTF8String], &database) == SQLITE_OK) {
sqlite3_stmt *statement;
// iOS 4 and 5 may require different SQL, as the .db format may change
const char *sql4 = "SELECT text from message ORDER BY rowid DESC"; // TODO: different for iOS 4.* ???
const char *sql5 = "SELECT text from message ORDER BY rowid DESC";
NSString *osVersion =[[UIDevice currentDevice] systemVersion];
if([osVersion hasPrefix:@"5"]) {
// iOS 5.* -> tested
sqlite3_prepare_v2(database, sql5, -1, &statement, NULL);
} else {
// iOS != 5.* -> untested!!!
sqlite3_prepare_v2(database, sql4, -1, &statement, NULL);
}
// Use the while loop if you want more than just the most recent message
//while (sqlite3_step(statement) == SQLITE_ROW) {
if (sqlite3_step(statement) == SQLITE_ROW) {
char *content = (char *)sqlite3_column_text(statement, 0);
text = [NSString stringWithCString: content encoding: NSUTF8StringEncoding];
sqlite3_finalize(statement);
}
sqlite3_close(database);
}
return text;
}
现在,请确保此应用安装在 / Applications / 中。如果您只是构建此应用程序,并使用Xcode正常安装,那么由于应用程序沙盒,您将获得打开sqlite数据库的权限被拒绝错误。
我的代码段只获取最新的文本内容。 Here's an example of doing a little more with the database。查看QuerySMS
方法。
此外,这是 sms.db 的link on the database format。你可以在那里找到你需要的其他东西。或者,只需将sms.db复制到您的计算机,然后使用Firefox SQLiteManager plugin之类的内容进行浏览。祝你好运!
更新:来自question I posted on multi-process SQLite thread safety on iOS
的一些信息答案 1 :(得分:1)
您可以参考以下链接
答案 2 :(得分:1)
我想在非越狱的iOS8设备上获取最后一条消息:
CKDBMessage.h
标题中获取ChatKit
并将该文件添加到您的项目中。kCTMessageReceivedNotification
至CTTelephonyCenterAddObserver
使用此功能获取上次收到的消息的信息:
void SmsReceived()
{
NSLog(@"GOT SMS");
//open IMDPersistence framework
void *libHandle = dlopen("/System/Library/PrivateFrameworks/IMDPersistence.framework/IMDPersistence", RTLD_NOW);
//make/get symbol from framework + name
IMDMessageRecordGetMessagesSequenceNumber = (int (*)())dlsym(libHandle, "IMDMessageRecordGetMessagesSequenceNumber");
// get id of last SMS from symbol
int lastID = IMDMessageRecordGetMessagesSequenceNumber();
NSLog(@"%d", lastID);
// close (release?) framework -> needed??
dlclose(libHandle);
// get message object
dlopen("/System/Library/PrivateFrameworks/ChatKit.framework/ChatKit", RTLD_LAZY);
Class CKDBMessageClass = NSClassFromString(@"CKDBMessage");// objc_getClass("CKDBMessage");
CKDBMessage *msg = [[CKDBMessageClass alloc] initWithRecordID:lastID];
NSString *text = msg.text;
NSLog(@"text: %@", text);
}