【问题标题】:How to access the method in the Private API framework and pass the value to it?如何访问 Private API 框架中的方法并将值传递给它?
【发布时间】:2021-09-13 09:31:44
【问题描述】:

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

因此,出于研究目的,我选择了 MFMessageComposer,我想禁用对从代码中传递的任何输入的编辑。

我试着把我的手放在这上面,我用下面的方式编码。我所做的是走私有框架的路径并访问了一个名为CKSMSComposeController 的特定类,它具有上述方法。我提到了 ChatKit.framework https://github.com/nst/iOS-Runtime-Headers/blob/master/PrivateFrameworks/ChatKit.framework/CKSMSComposeController.h

class dump

我将NSLog(@"Result %@", success ? @"YES" : @"NO"); 的日志记录为YES,但即使将NO 传递给上面的选择器,我仍然无法禁用对收件人的编辑

有人能告诉我我传递参数的方式是否正确吗? 因为 -(void)setCanEditRecipients:(BOOL)arg1;` 是私有方法框架接受 bool 作为参数,我在上面的代码中传递 NO

这只是针对私有框架的内部研究。我在哪里做错了?请告诉

【问题讨论】:

  • 如果你使用 KVC 作为 init 方法,为什么不使用它作为 setter 呢? setCanEditRecipients 是类方法吗?
  • @Willeke '- (void)setCanEditRecipients:(bool)arg1;'它在链接github.com/nst/iOS-Runtime-Headers/blob/master/… 中是这样写的,所以可能是一个类方法。在这种情况下你有什么建议?

标签: swift objective-c xcode iphone-privateapi mfmessagecomposeview


【解决方案1】:

Objective-C中,类方法以+开头,实例方法以-开头。

// Following is an instance method because it starts with `-`
- (void)setCanEditRecipients:(bool)arg1;

上述方法不适用于以下代码。

Class CKSMSComposeController = NSClassFromString(@"CKSMSComposeController");
SEL sel = NSSelectorFromString(@"setCanEditRecipients:");

// `CKSMSComposeController` is a class - NOT an instance
if ([CKSMSComposeController respondsToSelector:sel]) {
    // will not enter if's body
}

最重要的是 - 您不应该创建自己的实例并对其进行自定义。您应该对系统在屏幕上显示的实例进行自定义。

这是你可以尝试的方法 -

- (void) showMessageComposeViewController {
    if ([MFMessageComposeViewController canSendText]) {
        MFMessageComposeViewController* messageController = [[MFMessageComposeViewController alloc] init];
        messageController.recipients = @[@"555-555-5555"];
        messageController.body = @"Example message";
        
        [self presentViewController:messageController animated:YES completion:^{
            
            // Allow enough time for the UI to be loaded fully
            dispatch_after(1, dispatch_get_main_queue(), ^{
                // Since `MFMessageComposeViewController` is a `UINavigationController`, we can access it's first view controller like this
                UIViewController* targetVC = messageController.viewControllers.firstObject;
                
                // Check if the instance is of correct class type
                if ([targetVC isKindOfClass:NSClassFromString(@"CKSMSComposeController")]) {
                    
                    SEL sel1 = NSSelectorFromString(@"setCanEditRecipients:");
                    if ([targetVC respondsToSelector:sel1]) {
                        // put breakpoint here to check whether this line is executed
                        [targetVC performSelector:sel1 withObject:@NO];
                    }
                    
                    SEL sel2 = NSSelectorFromString(@"setTextEntryContentsVisible:");
                    if ([targetVC respondsToSelector:sel2]) {
                        // put breakpoint here to check whether this line is executed
                        [targetVC performSelector:sel2 withObject:@NO];
                    }
                }
            });
        }];
    }
}

【讨论】:

  • 感谢您的回复,但不幸的是代码不起作用并且显示相同的行为,我可以编辑收件人以及编辑框。你试过吗?
  • 我做了 nslog,我可以看到日志正在打印在您建议放置断点的位置,但不幸的是,禁用编辑字段和收件人的代码对我不起作用。你能从你身边试试吗?
  • @Fionashoff 此答案提供了有关如何确保您在实例上调用私有方法的信息。它不能保证它会解决你认为它可能会解决的问题。请考虑提出不同的问题。
  • 我在问题中明确提到我要禁用消息编辑框并添加收件人。你误解了这个问题不是我的错。没有用的答案有什么用?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-02
  • 2012-10-02
  • 1970-01-01
  • 1970-01-01
  • 2012-05-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多