不懂[IMDMessageStore sharedInstance] 意思/用法,希望详解!!

http://stackoverflow.com/questions/16219799/block-sms-on-ios6上面看到一篇文章,对于里面的
[IMDMessageStore sharedInstance] performBlock:^{ IMDChatRecordDeleteChatForGUID([NSString stringWithFormat:@“SMS;-;%@”, sender]); }];不是很理解,也不是很懂,资料也少的很,所以希望大牛们,给出解释,以及怎么用!谢谢!

用于取得 IMDMessageStore 的单实例,有学过C++不?简单的说,类似拿到 一个IMDMessageStore实例的self指针,可以直接用这个实例的方法。

就目前来看,关于越狱开发的公开资料,尤其是私有函数/框架的具体用法非常少,基本都需要采用逆向工程的方式来搞清楚来龙去脉,这也是我们出书的原因之一。说到IMDMessageStore,我碰巧在SMSNinja这个应用中使用到了相关的框架,在此作一个简单说明,如有错误,还请指出:
从iOS 7开始,不管是SMS还是iMessage,都是先由SpringBoard负责接收,简单处理后交由imagent进行落地。SpringBoard底层负责处理message的主要是IMCore.framework和IMFoundation.framework这2个框架,将一条SMS/iMessage视作一个FZMessage,将一个对话条目视作一个IMChat。通过IMChatRegistry这个类,可以获取所有的IMChat;IMChat则可以进一步获取此chat中的所有FZMessage。在SpringBoard做完自己的工作后,将FZMessage交由imagent继续处理,此时FZMessage没有变,但SpringBoard中的IMChat变成了imagent中的IMDChat,IMChatRegistry变成了IMDChatRegistry。IMChat和IMDChat是2个不同的类,但如果chatIdentifier相同,则代表同一个对话条目。也就是说,SpringBoard处理FZMessage的类名采用了IM前缀,而imagent采用了IMD前缀,因此IMDMessageStore就是存活在imagent中的一个单例。至于你提到的IMDChatRecordDeleteChatForGUID,如果你打开IMDChat.h就会看到一个guid的property,通过我上面提到的方法,在imagent里先获取IMDChatRegistry,再得到对应的IMDChat,就可以调用此函数删除这个chat。但是虽然在底层删除了这个chat,SpringBoard的缓存里可能还保留这个chat,就要进一步刷新SpringBoard的缓存来达到彻底清空的目的。关于SMS/iMessage的操作有些复杂,我的三言两语不能以偏概全,以上只是提供一个思路,让你少走弯路,但剩下的必须要走的路,还得你自己来

你是不懂这些方法的用法,还是连这个语句的语法都不明白?

经过@snakeninny的提示,我去api中看了看,原来是引用错误了。
我原来是这样引用的,#import <IMDaemonCore/IMDaemonCore.h>
后来看了看#import <IMDaemonCore/IMDMessageStore.h> 这样就ok了,看来还是自己不细心导致的!

问题有来了,接着上面的问题,有好多东西不懂,不懂imagent 怎么实现,是由系统自行实现,还是我们自己人为实现?以及IMChat 怎么转化为IMDChat,这些都不懂,希望大大指点!
实在感激不尽
我的代码是这样的,如图所示!

我运行就报错了,错误信息如下所示!

这的不知道咋解决了,希望大大指点迷津!!!!

经过昨晚的苦战熬夜,看api看出了点门路,但是还是不对,总觉得中间少些什么东西,而且还是报错,很无语,只好洗洗睡了,早上赶紧更贴,希望的到进一步的回复

我的代码如上所示,运行过程中还是有错误,错误信息如下,


请大大们给解决一哈,感激不尽!

出错的原因是你调用了[NSObject sharedDaemon],而这个方法并不存在

你详细描述一下你的目的,然后把整段代码贴上来,得到解答的可能性会高一些。现在你的描述和代码都只是一个小片段,大部分人应该都不知所云,就更不会回答了

**最近对ios发送消息这块比较感兴趣
所以想在界面发完消息后,直接删除,同时短信界面也不显示,也就是不往本地sms数据库存或者就是它存了我们人为的用代码删除掉,我发送短信或是iMessage是手动使用机器发的,之后,通过通知收到短信代码如下

  • (void)postNotificationName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo
    {
    %orig;
    // 发送失败

    // __kIMChatMessageFailureCountChangedNotification
    if (![aName isEqualToString:@"__kIMChatItemsDidChangeNotification"])
    {
    return;
    }
    NSLog(@“aUserInfo = %@”,aUserInfo);

    for (IMChatItem* chatItem in aUserInfo@"__kIMChatItemsKey"])
    {
    IMMessage* msg = [chatItem message];//Incoming message object

      // 创建FZMessage
      FZMessage *fm = [msg _fzMessage];
    
      NSString *accountID = fm.accountID;
      NSString *service = fm.service;
      NSString *guid = fm.guid;
      NSString *chatIdentifier =  fm.handle;
      NSString *participants = nil;
      NSString *roomName = fm.roomName;
      NSString *lastAddressedLocalHandle = nil;
    
      // 方法一:创建IMDChat 
      IMDChat *dChat = [IMDChat alloc] initWithAccountID:accountID 
                                        service:service 
                                        guid:guid 
                                        chatIdentifier:chatIdentifier 
                                        participants:participants 
                                        roomName:roomName 
                                        lastAddressedLocalHandle:lastAddressedLocalHandle 
                                        state:0 
                                        style:nil];
      方法二:创建IMDChat 
      IMDChat *dChat = [IMDChat alloc] init];
      dChat.lastMessage = fm;
      
      [IMDMessageStore sharedInstance] performBlock:^{
    
             [IMDMessageStore sharedInstance] deleteMessageGUIDs:[NSArray arrayWithObject:[dChat guid]]];
    
      }];
    

    }
    }

我说说使用两种创建IMDChat 的效果,第一种我打印是有东西的。**
但是第二种就没内容了,就只有IMDChat的架子,没实际值,
第二中方法的思路:我看了大大前面回复的内容说是要把IMChat转换成IMDchat之后进行删除,于是我看api发现IMDChat中有一个属性也是叫
@property(retain) FZMessage *lastMessage; // @synthesize lastMessage=_lastMessage;
所以我就想从IMMessage中取得的FZMessage的值,直接赋予IMDChat,但是这样做的结果是只有IMDChat的结构,没有实际数值.
所以我用第一种,自己手动构造IMDchat实例化时需要的参数,也只有部分,不是所有的参数都有值,但是依然报错。
错误信息如下
Mar 26 15:16:03 romejiangteki-iPod securityd[521] : MS:Notice: Injecting: (null) [securityd] (793.00)
Mar 26 15:16:03 romejiangteki-iPod SpringBoard[489] : +[NSObject sharedDaemon]: unrecognized selector sent to class 0x3af6ab48
Mar 26 15:16:03 romejiangteki-iPod SpringBoard[489] : *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘+[NSObject sharedDaemon]: unrecognized selector sent to class 0x3af6ab48’
*** First throw call stack:
而且手机老手重启,让"Exit Safe Mode",好郁闷哦,求解啊????

首先,报的错是+[NSObject sharedDaemon]: unrecognized selector sent to class 0x3af6ab48,也就是说程序在某个地方显式/隐式调用了[NSObject sharedDaemon]这个方法,但NSObject是没有这个方法的。所以为了排除你的错误,你首先需要检查自己的代码有没有显式调用+[NSObject sharedDaemon];其次,就是在之前的回复我也说过,IMDChat这个类是存在于imagent里的,你hook的这个函数是来自哪个进程?再者,发送iMessage后系统应该会自动生成一个IMDChat,你要做的是想办法获取这个IMDChat然后进行删除操作,而不是自己创建一个新实例再删掉这个实例,否则你的操作对系统原先的IMDChat是没有任何影响的

**
%hook NSNotificationCenter
// @interface CKMadridMessage : NSObject{}

// - (IMMessage*)imMessage;

// @end

  • (void)postNotificationName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo
    {
    %orig;
    // 发送失败

    // __kIMChatMessageFailureCountChangedNotification
    if (![aName isEqualToString:@"__kIMChatItemsDidChangeNotification"])
    {
    return;
    }
    NSLog(@“aUserInfo = %@”,aUserInfo);

    for (IMChatItem* chatItem in aUserInfo@"__kIMChatItemsKey"])
    {
    IMMessage* msg = [chatItem message];//Incoming message object

      // 创建FZMessage
      FZMessage *fm = [msg _fzMessage];
    
      NSString *accountID = fm.accountID;
      NSString *service = fm.service;
      NSString *guid = fm.guid;
      NSString *chatIdentifier =  fm.handle;
      NSString *participants = nil;
      NSString *roomName = fm.roomName;
      NSString *lastAddressedLocalHandle = nil;
    
      // 方法一:创建IMDChat 
      IMDChat *dChat = [IMDChat alloc] initWithAccountID:accountID 
                                        service:service 
                                        guid:guid 
                                        chatIdentifier:chatIdentifier 
                                        participants:participants 
                                        roomName:roomName 
                                        lastAddressedLocalHandle:lastAddressedLocalHandle 
                                        state:0 
                                        style:nil];
      // 方法二:创建IMDChat 
      // IMDChat *dChat = [IMDChat alloc] init];
      // dChat.lastMessage = fm;
      
      [IMDMessageStore sharedInstance] performBlock:^{
    
             [IMDMessageStore sharedInstance] deleteMessageGUIDs:[NSArray arrayWithObject:[dChat guid]]];
    
      }];
    

    }
    }

%end**
这是我处理接受通知的整个方法,我hook的就是****NSNotificationCenter这个类
大大你回复的这句话”IMDChat这个类是存在于imagent里的“,不知道怎么弄,如果我要用这个IMDChat的东西,我怎么加到imagent里面呀?

你把帖子好好编辑一下,代码格式规整一下。
有的类是通用的,比如Foundation.framework里的NSObject,但有些类只适用于一些特定的进程,比如你在SpringBoard中就无法获取IMDChat这个类的实例。我说的情况可以用下面的伪代码说明:

%hook SomeImagentClass
- (void)saveMessageToChat:(IMDChat *)chat
{
    %orig;
    if (IsTargetChat(chat)) [chat removeFromDatabase];
}
%end