【问题标题】:Import ChatKit (i.e., Private Framework) OR using CKDBMessage somehow导入 ChatKit(即私有框架)或以某种方式使用 CKDBMessage
【发布时间】:2015-03-19 17:53:51
【问题描述】:

首先 - 我知道私有框架/API 不会让我进入 AppStore,这仅供私人使用/研究。

我无法使用ChatKit.framework 编译我的项目。

基本上我需要以某种方式初始化一个CKDBMessage 对象并从中获取内容。

我尝试的 first 方法是能够调用它:

    CKDBMessage* msg = [[CKDBMessage alloc] initWithRecordID:lastID];
    NSLog(@"GOT SMS: %@", msg.text);

我无法使用这些解决方案的任何组合对其进行编译:

  • 只需将CKDBMessage.h 添加到我的项目中
  • 添加ChatKit.framework的所有标头
  • 还要添加ChatKit.framework 文件本身

我在Headers 文件夹中有标题和框架文件,我尝试添加任何/所有这些构建设置,都在递归/非递归上:

  • 框架搜索路径 -> $(PROJECT_DIR)/Headers
  • 标题搜索路径 ->
    • $(SRCROOT)/Headers/ChatKit.framework/Headers
    • $(SRCROOT)/Headers
  • 用户标题搜索路径->
    • $(SRCROOT)/Headers
    • $(SRCROOT)/Headers/ChatKit.framework/Headers

始终搜索用户路径始终为“是”

我尝试的第二件事是在运行时做所有事情,这就是我所拥有的:

Class CKDBMessage = NSClassFromString(@"CKDBMessage");// objc_getClass("CKDBMessage");

SEL sel = @selector(initWithRecordID:);

NSMethodSignature *signature = [CKDBMessage methodSignatureForSelector:sel];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
invocation.selector = sel;
[invocation setArgument:&lastID atIndex:2];
[invocation invoke];

NSObject * msgWeak = [CKDBMessage alloc];
[invocation getReturnValue:&msgWeak];
NSObject *msg = msgWeak;

NSString *text = [msg performSelector:@selector(text)];

NSLog(@"text: %@", text);

这里我在invocationWithMethodSignature: 崩溃,因为 NSClassFromString 返回 nil 而不是类...

对这两种方法有什么想法吗?

这是未越狱的,iOS8(.2),使用 Xcode6

【问题讨论】:

    标签: ios objective-c iphone xcode6 iphone-privateapi


    【解决方案1】:

    好吧,没有多少人看过这个,但为了我们的 wiki 社区,我设法通过将 CKDBMessage.h 文件添加到我的项目来解决这个问题(实际上我添加了 ChatKit 的所有标题,但我没有认为有必要),而不是像这样使用dlopen动态加载框架:

    dlopen("/System/Library/PrivateFrameworks/ChatKit.framework/ChatKit", RTLD_LAZY)
    

    所以我的完整解决方案是:

    dlopen("/System/Library/PrivateFrameworks/ChatKit.framework/ChatKit", RTLD_LAZY);
    
    Class CKDBMessageClass = NSClassFromString(@"CKDBMessage");
    CKDBMessage *msg = [[CKDBMessageClass alloc] initWithRecordID:lastID];
    
    NSString *text = msg.text;
    NSLog(@"text: %@", text);
    

    获取最后一条消息的ID涉及到另一个框架:IMDPersistence

    //SomeFile.h
    // ...
    //declare the function:
    static int (*IMDMessageRecordGetMessagesSequenceNumber)();
    
    // SomeFile.m
    // ...
    //open IMDPersistence framework
    void *libHandleIMD = dlopen("/System/Library/PrivateFrameworks/IMDPersistence.framework/IMDPersistence", RTLD_LAZY);
    
    //make/get symbol from framework + name
    IMDMessageRecordGetMessagesSequenceNumber = (int (*)())dlsym(libHandleIMD, "IMDMessageRecordGetMessagesSequenceNumber");
    
    // get id of last SMS from symbol
    int lastID = IMDMessageRecordGetMessagesSequenceNumber();
    

    现在您可以使用lastID 来获取消息内容...

    【讨论】:

    • 嗨,你能分享更多细节吗? dlopen,RTLD_LAZY 显示错误。未声明的标识符
    • 您必须为 dlopen 包含#include 。在我这边,我想知道你的 lastID 是从哪里得到的?
    • 应该是CKDBMessage *msg = ...
    • 嘿 @AvielGross 这曾经在 iOS 10 及更低版本上运行良好。但是在最新的 iOS 11 Beta 上,我看到了这个:Database": __XPCIMDMessageStoreSendXPCMessage has failed。你在那里试过吗?有什么想法可以让它在 11 上运行吗?谢谢!
    • @Jan 我不得不承认我很惊讶苹果一直到 11 来解决这个问题......我不再真正处理这个问题所以不幸的是我不知道应该做什么...您可以检查 iOS 11 的类转储,查看消息等内容。
    【解决方案2】:

    目前,我使用的是 XCode 10。在这里我们可以在 PrivateFrameworks 路径中看到一个 MessagesKit.frameworkMessagesKit.framework 包含 SOMessageHelper 文件,我们可以在其中看到 sendSMS 函数。

    功能:

    (void)sendMessageText:(id)arg1 toRecipient:(id)arg2 withCompletionBlock:(CDUnknownBlockType)arg3;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-01
      • 2011-05-11
      • 1970-01-01
      • 1970-01-01
      • 2011-05-11
      • 1970-01-01
      • 2015-04-29
      相关资源
      最近更新 更多