美文网首页
苹果审核上报

苹果审核上报

作者: jackyshan | 来源:发表于2020-06-06 10:13 被阅读0次

    介绍

    引自Apple
    App 正在改变世界,丰富人们的生活,并为像您一样的开发者提供前所未有的创新机会。因此,App Store 已成长为一个激动人心且充满活力的生态系统,正为数百万的开发者和超过十亿的用户提供服务。不管是开发新手,还是由经验丰富的程序员所组成的大型团队,我们都非常欢迎您为 App Store 开发 app,并希望能够帮助您了解我们的准则,以确保您的 app 能够快速通过审核流程。

    原因

    苹果审核规则很多,有时候一直正常提包,某一天换了一个审核人员,提审的包就被拒了。给的原因莫名其妙,自查很难定位到原因,改完能不能过,全靠运气。
    为了能够更好的过审,需要能全面监控苹果审核人员的操作,记录下来,并通过机器人接口上报钉钉群。

    钉钉机器人设置

    操作路径

    群设置-智能群助手-添加机器人-自定义【通过Webhook接入自定义服务】

    设置机器人

    自定义关键词begin

    记录Webhook地址

    https://oapi.dingtalk.com/robot/send?access_token=xxx
    

    代码实现

    判断uid是否是提审的,如果是,开始记录操作路径并上报,调用reportText这个接口

    + (BOOL)isApple {
        NSString *uid = [[[NSBundle mainBundle] infoDictionary] valueForKeyPath:@"Appconfig.alppeReivwUid"];
        if ([[IKAtomFactory sharedInstance].atom.userId isEqualToString:uid]) {
            return YES;
        }
        
        return NO;
    }
    

    实现如下

    //
    //  CJMtinorAlplpeReivw.m
    //  AFNetworking
    //
    //  Created by jackyshan on 2019/11/12.
    //
    
    #import "CJMtinorAlplpeReivw.h"
    #import <RSSwizzle/RSSwizzle.h>
    
    @interface CJMtinorAlplpeReivw()
    
    /** 上报队列 */
    @property (nonatomic, strong) NSMutableArray *textMArr;
    @property (nonatomic, strong) dispatch_source_t gcdTimer;
    @property (nonatomic, assign) NSInteger takeTime;// 花费时长
    @property(nonatomic, copy) NSString *bundleShortVersionString;
    @property(nonatomic, copy) NSString *bundleVersion;
    
    + (instancetype)sharedInstance;
    
    @end
    
    @implementation CJMtinorAlplpeReivw
    
    + (instancetype)sharedInstance {
        static CJMtinorAlplpeReivw *_sharedIns = nil;
        
        if (_sharedIns == nil) {
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                _sharedIns = [[[self class] alloc] init];
            });
        }
        
        return _sharedIns;
    }
    
    - (instancetype)init {
        if (self = [super init]) {
            _textMArr = [NSMutableArray array];
            [self startTimer];
        }
        
        return self;
    }
    
    - (void)startTimer {
        dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
        if (timer) {
            dispatch_source_set_timer(timer, dispatch_walltime(DISPATCH_TIME_NOW, NSEC_PER_SEC * 1), 3 *NSEC_PER_SEC, NSEC_PER_SEC * 1);
            dispatch_source_set_event_handler(timer, ^{
                [[CJMtinorAlplpeReivw sharedInstance] uploadTextQueue];
                self.takeTime += 3;
            });
            dispatch_resume(timer);
            self.gcdTimer = timer;
        }
    }
    
    - (void)uploadTextQueue {
        if (![CJMtinorAlplpeReivw isApple]) {
            return;
        }
        
        if ([CJMtinorAlplpeReivw sharedInstance].textMArr.count == 0) {
            return;
        }
        
        NSString *content = [NSString stringWithFormat:@"begin %@\n%@(%@)\ntt:%zds",[[NSBundle mainBundle] bundleIdentifier],self.bundleShortVersionString,self.bundleVersion,self.takeTime];
        for (NSString *text in [CJMtinorAlplpeReivw sharedInstance].textMArr) {
            content = [NSString stringWithFormat:@"%@\n%@", content, text?:@""];
        }
        [[CJMtinorAlplpeReivw sharedInstance].textMArr removeAllObjects];
        
        NSString *atoken = [[[NSBundle mainBundle] infoDictionary] valueForKeyPath:@"Appconfig.ddingtoken"];
        if (atoken.length == 0) {
            return;
        }
        
        NSString *urStr = [NSString stringWithFormat:@"https://oapi.dingtalk.com/robot/send?access_token=%@", atoken];
        NSDictionary *data = @{@"msgtype":@"text",
                               @"text":@{@"content":content}};
        NSURLSession *session = [NSURLSession sharedSession];
        NSURL *url = [NSURL URLWithString:urStr];
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        request.HTTPMethod = @"POST";
        [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
        request.HTTPBody = [NSJSONSerialization dataWithJSONObject:data options:NSJSONWritingPrettyPrinted error:nil];
        NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        }];
        [dataTask resume];
    }
    
    + (void)reportText:(NSString *)text {
        if (text.length == 0) {
            return;
        }
        [[CJMtinorAlplpeReivw sharedInstance].textMArr addObject:text];
    }
    
    + (BOOL)isApple {
        NSString *uid = [[[NSBundle mainBundle] infoDictionary] valueForKeyPath:@"Appconfig.alppeReivwUid"];
        if ([[IKAtomFactory sharedInstance].atom.userId isEqualToString:uid]) {
            return YES;
        }
        
        return NO;
    }
    
    - (NSString *)bundleShortVersionString {
        if (!_bundleShortVersionString) {
            _bundleShortVersionString = [[[NSBundle mainBundle]infoDictionary] objectForKey:@"CFBundleShortVersionString"];
        }
        return _bundleShortVersionString;
    }
    
    - (NSString *)bundleVersion {
        if (!_bundleVersion) {
            _bundleVersion = [[[NSBundle mainBundle]infoDictionary] objectForKey:@"CFBundleVersion"];
        }
        return _bundleVersion;
    }
    @end
    
    @implementation UIViewController (AlplpeRievew)
    
    + (void)load {
        [RSSwizzle swizzleInstanceMethod:@selector(viewDidAppear:) inClass:[UIViewController class] newImpFactory:^id(RSSwizzleInfo *swizzleInfo) {
            return ^void(__unsafe_unretained id self, BOOL animated) {
                if ([[self class] isKindOfClass:[UINavigationController class]]) {
                    return;
                }
                else if ([NSStringFromClass([self class]) hasPrefix:@"UI"]) {
                    return;
                }
                else if ([NSStringFromClass([self class]) hasPrefix:@"_UI"]) {
                    return;
                }
                else if ([[self class] isSubclassOfClass:[UIViewController class]]) {
                    NSString *text = [NSString stringWithFormat:@"e:%@", [self class]];
                    [CJMtinorAlplpeReivw reportText:text];
                }
                
            };
        } mode:RSSwizzleModeAlways key:NULL];
        
        [RSSwizzle swizzleInstanceMethod:@selector(viewDidDisappear:) inClass:[UIViewController class] newImpFactory:^id(RSSwizzleInfo *swizzleInfo) {
            return ^void(__unsafe_unretained id self, BOOL animated) {
                if ([[self class] isKindOfClass:[UINavigationController class]]) {
                    return;
                }
                else if ([NSStringFromClass([self class]) hasPrefix:@"UI"]) {
                    return;
                }
                else if ([NSStringFromClass([self class]) hasPrefix:@"_UI"]) {
                    return;
                }
                else if ([[self class] isSubclassOfClass:[UIViewController class]]) {
                    NSString *text = [NSString stringWithFormat:@"l:%@", [self class]];
                    [CJMtinorAlplpeReivw reportText:text];
                }
            };
        } mode:RSSwizzleModeAlways key:NULL];
        
        [RSSwizzle swizzleInstanceMethod:@selector(sendAction:to:from:forEvent:) inClass:[UIApplication class] newImpFactory:^id(RSSwizzleInfo *swizzleInfo) {
            return ^BOOL(__unsafe_unretained id self, SEL action, id target, id sender, UIEvent *event) {
                BOOL (*originalIMP)(__unsafe_unretained id, SEL, SEL, id, id, UIEvent*);
                originalIMP = (__typeof(originalIMP))[swizzleInfo getOriginalImplementation];
                BOOL res = originalIMP(self, @selector(sendAction:to:from:forEvent:), action, target, sender, event);
                
                __block BOOL isTouchEnd = NO;
                
                if (event && event.allTouches.count > 0) {
                    [event.allTouches enumerateObjectsUsingBlock:^(UITouch * _Nonnull obj, BOOL * _Nonnull stop) {
                        if (obj.phase == UITouchPhaseEnded) {
                            isTouchEnd = YES;
                        }
                    }];
                }
                
                if (isTouchEnd) {
                    if ([sender isKindOfClass:[UIButton class]]) {
                        [CJMtinorAlplpeReivw reportText:[NSString stringWithFormat:@"c:%@", [sender currentTitle] ?  : @"其他"]];
                    }
                }
                
                return res;
            };
        } mode:RSSwizzleModeAlways key:NULL];
        
        Class AppDelegate = NSClassFromString(@"AppDelegate");
        if (AppDelegate) {
            RSSwizzleInstanceMethod(AppDelegate,
                                    @selector(applicationDidBecomeActive:),
                                    RSSWReturnType(void),
                                    RSSWArguments(UIApplication *application),
                                    RSSWReplacement({
                RSSWCallOriginal(application);
                [CJMtinorAlplpeReivw reportText:@"ba"];
            }), RSSwizzleModeAlways, NULL);
            RSSwizzleInstanceMethod(AppDelegate,
                                    @selector(applicationDidEnterBackground:),
                                    RSSWReturnType(void),
                                    RSSWArguments(UIApplication *application),
                                    RSSWReplacement({
                RSSWCallOriginal(application);
                [CJMtinorAlplpeReivw reportText:@"eb"];
            }), RSSwizzleModeAlways, NULL);
        }
    }
    
    @end
    
    

    注意

    苹果提审有机器进行代码扫描,我们的代码里最好不要出现ReviewAppleMonitorApple等关键词

    相关文章

      网友评论

          本文标题:苹果审核上报

          本文链接:https://www.haomeiwen.com/subject/fwunzhtx.html