避免因为respondsToSelector:, performSelector:上线被拒

避免因为respondsToSelector:, performSelector:上线被拒

记得前段时间iOS开发者很多都收到了使用JSPatch被拒的邮件,

Your app, extension, and/or linked framework appears to contain code designed explicitly with the capability to change your app’s behavior or functionality after App Review approval, which is not in compliance with section 3.3.2 of the Apple Developer Program License Agreement and App Store Review Guideline 2.5.2. This code, combined with a remote resource, can facilitate significant changes to your app’s behavior compared to when it was initially reviewed for the App Store. While you may not be using this functionality currently, it has the potential to load private frameworks, private methods, and enable future feature changes.
This includes any code which passes arbitrary parameters to dynamic methods such as dlopen(), dlsym(), respondsToSelector:, performSelector:, method_exchangeImplementations(), and running remote scripts in order to change app behavior or call SPI, based on the contents of the downloaded script. Even if the remote resource is not intentionally malicious, it could easily be hijacked via a Man In The Middle (MiTM) attack, which can pose a serious security vulnerability to users of your app.
Please perform an in-depth review of your app and remove any code, frameworks, or SDKs that fall in line with the functionality described above before submitting the next update for your app for review.
Best regards
App store Review

导致很多开发者炸锅,大家都忙着去掉带有JSPatch的框架或者更新新的框架,
那时候记得我也是有很多的三方框架有问题,比如高德,比如bugly…

去掉热更新成为3月份的时候一大重要事件.
当然现在又回归了平静,

当然JSPatch等热更新框架的移除我们肯定都会做,但是也会有部分开发者压根就没有使用JSPatch热更新,但是应用也会收到邮件,
原因可能就在这里
这里写图片描述
我们有注意到responseToSelector和performSelector,
回想一下,我们会经常使用…
所以很多躺枪就在这里,我在JSPatch刚刚被限制的时候移除框架后仍然被拒,就是因为这两个方法.
于是我想到了替代这两个方法

#import <Foundation/Foundation.h>

@interface NSObject (Extension)

-(BOOL)canRunToSelector:(SEL)aSelector;

- (id)runSelector:(SEL)aSelector withObjects:(NSArray *)objects;

@end
#import "NSObject+Extension.h"
#import <objc/runtime.h>

@implementation NSObject (Extension)

-(BOOL)canRunToSelector:(SEL)aSelector{
    unsigned int methodCount =0;
    Method  *methodList = class_copyMethodList([self class],&methodCount);
    NSString *selectorStr = NSStringFromSelector(aSelector);

    BOOL result = NO;
    for (int i = 0; i < methodCount; i++) {
        Method temp = methodList[i];
        const char* selectorName =sel_getName(method_getName(temp));
        NSString *tempSelectorString = [NSString stringWithUTF8String:selectorName];
        NSLog(@"%@",tempSelectorString);
        if ([tempSelectorString isEqualToString:selectorStr]) {
            result = YES;
            break;
        }
    }
    free(methodList);
    return result;
}

- (id)runSelector:(SEL)aSelector withObjects:(NSArray *)objects {
    NSMethodSignature *methodSignature = [self methodSignatureForSelector:aSelector];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
    [invocation setTarget:self];
    [invocation setSelector:aSelector];

    NSUInteger i = 1;

    if (objects.count) {
        for (id object in objects) {
            id tempObject = object;
            [invocation setArgument:&tempObject atIndex:++i];
        }
    }
    [invocation invoke];

    if (methodSignature.methodReturnLength) {
        id value;
        [invocation getReturnValue:&value];
        return value;
    }
    return nil;
}

@end

通过这两个方法,我替换了邮件提到的两个危险的方法,虽然不是很完美,但是我们的应用没有问题了.顺利上架

其实方法本身不是很复杂,还是使用runtime,第一个方法是获取当前类的所有的实例方法名,跟提供的方法名做比较
第二个方法则是采用OC的另一种调用方法的实现NSInvocation,把原先的方法和参数等转换成采用NSInvocation调用而已.

两个方法不复杂,很多人稍微想一想都会有这样的类似的结果.

当然,现在写这个对于经历了JSPatch事件的开发者没有什么作用,因为事件已经过去近两个月了,但是我觉得我还是有必要把我的实现提供出来,方便刚刚参与到开发的小伙伴或者之前很碰巧没有碰到热更新的事件的开发者们.

欢迎访问我的iOS系列博客,刚刚开始写,大家也可以给点建议
系列:iOS开发-前言+大纲
http://blog.csdn.net/spicyShrimp/article/details/62218521

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值