这是我发现的...
仅查看转储的私有 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
没问题……它只是不再为您提供 SMS内容。因此,如果您将以下代码放入通知处理程序中,您应该能够看到消息文本:
- (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 数据库时收到权限被拒绝错误。
我的代码片段只是获取最新的文本内容。 这是一个使用数据库做更多事情的例子。看QuerySMS
方法。
另外,这里是sms.db数据库格式的链接。你可以在那里找到你需要的其他东西。或者,只需将 sms.db 复制到您的计算机,然后使用Firefox SQLiteManager 插件之类的东西浏览它。祝你好运!
更新:我在 iOS 上的多进程 SQLite 线程安全上发布的问题中的一些信息