美文网首页
编写SDK注意事项

编写SDK注意事项

作者: woniu | 来源:发表于2022-06-07 20:29 被阅读0次

    SDK设计的几个原则:稳定性、可扩展性、无侵性、崩溃问题采集、相应位置的打点监听。

    一、稳定性

    SDK最最重要的一个原则就是稳定向,一般要保持崩溃率在万分之一二以下,否则用户那边是很难过的去的。那么我们要保证我们的稳定性就要做到以下几点来降低崩溃率。

    1、对使用的数据进行安全化处理

    不要太相信后端传过来的数据,有时候数据是nil让你崩的猝不及防,所以就需要对获取的数据进行安全化处理。
    所谓安全化处理,就是我们使用类别的方法,进行安全化处理,比如NSString、NSArray、NSDictonry,要对内部的数据做判空等处理。防止出现调用的数据出现nil或者数组越界从而引发的崩溃。

    2、初始化调用的方法要保证在主线程操作

    用户调用的时候会有各种奇葩的调用,有的甚至在子线程调用SDK的初始化方法,SDK一些定时操作会失效,导致功能缺失问题。所以在SDK初始化的方法里面要强制进入主线程,杜绝线程方面的问题。

    3、各种系统版本需要考虑,尽量要做到新老版本的方法判断调用。
      if (@available(iOS 15.0, *)) { //表区头会空出一段距离
            [UITableView appearance].sectionHeaderTopPadding = 0;
        }
    
    4、接口稳定

    接口并不轻易改变调用方法或者参数,有稳定回调、数据格式不发生变化等。这很重要,一旦修改,必然导致所有的客户都要修改,所以这是原则问题,在设计的时候就要考虑到。
    1、所有的回调都在主线程。
    2、无论成功还是失败,都要给出相应的结果。

    5、对应的各个手机类型都要做好适配避免出现UI问题

    二、可扩展性

    SDK的接口要有扩展性,随着SDK的迭代,可能需要的传参有增加。这就需要我们扩展SDK,如果我们使用直接一个个传递参数的的方式调用就会让SDK的方法调用十分冗长且不优美,而且还要用户修改调用方法,多方面考虑这种方式都不合理。
    所以,我们需要创建个对象,将传递的参数做为这个对象的属性,一旦需要增加参数,那么我们只需要增加属性就足够了,用户也只需要增加这个对象的参数配置就行了,调用方式也不用改变。

    + (BOOL)showMessage:(ZNMessageConfig *)config;
    

    三、无侵性

    1、不能影响宿主App功能。

    SDK对于宿主App的依赖应该足够小,如不能跟宿主App起相同的类名、使用相同的扩展、依赖相同的第三方库等

    2、不会导致宿主App卡顿。

    内部所有操作应该尽可能放在自定义子线程中

    3、尽量不使用第三方库。

    使用三方库这个是难免的,所以我们需要注意避免和用户的三方库产生冲突。
    a、需要rename类名包括类别以及类别方法,加上本公司的特定标识。
    b、extern 声明的外部全局变量,也是都需要修改的。

    .h文件声明
    初始化接口
    extern NSString * const kAPIInitGet;
    .m文件实现
    NSString * const kAPIInitGet =@"/sdk/api/v4.0/ticket/uploadlog";
    

    拓展:在开发中,我们通常会单独抽一个类来管理一些全局的变量或常量,通常搞一个GlobeConst文件,里面专门定义全局常量或常量。
    extern和#defineh定义的区别:
    extern与const组合:只需要定义一份全局常量或变量,多个文件共享。编译时刻,有类型检查,const仅仅用来修饰右边的变量,被const修饰的变量是只读的。
    #define 预编译,简单的字符串替换,没有类型检查,可以预编译表达式,也可以定义常量

    四、崩溃问题采集

    由于SDK在线上会面临各种各样的问题,所以我们需要实时统计SDK的崩溃问题,并及时修复,所以需要我们对SDK内的崩溃进行统计并上传。
    注册unCaughtExceptionHandler(),发现崩溃及时上报。

    1、采集的重点

    除了还需要采集崩溃的堆栈信息,还需要添加上附加信息,比如手机系统版本号、手机型号、SDK版本号等等重要标识,方便我们定位问题。

    2、发送时机

    不能在崩溃的时候直接发送给服务器,会导致我们收不到发送成功还是失败的信息,我们会在下次启动初始化SDK的时候发送出去。

    .h文件:
    + (void)setDefaultHandler;
    
    .m文件:
    #import "ANCrashHandler.h"
    #import "ANExceptionCollection.h" //采集崩溃信息存储起来
    #import <math.h>
    
    static NSUncaughtExceptionHandler *defaultExceptionHandler;
    
    // 崩溃时的回调函数
    void ANCrashHandler(NSException * exception) {
        // 数组越界,字典nil,调用未知方法.等等还有崩溃的控制器以及方法
        NSArray *arr = [exception callStackSymbols]; 
        NSString *callStackSymbols = [[arr subarrayWithRange:NSMakeRange(0, fmin(10, arr.count - 1))] componentsJoinedByString:@"\n"];
        BOOL isAN = [callStackSymbols containsString:@"ANMSS"];//采集SDK的文件标识
        if ([callStackSymbols AN_notEmpty] && isAN) {
            NSArray *components = [callStackSymbols componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
            components = [components filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self <> ''"]];
            NSString *stacktrace = [components componentsJoinedByString:@" "];        
            NSString *message = [NSString stringWithFormat:@"%@ %@", exception.name, exception.reason];
            [ANExceptionCollection anExceptionMessageSaveWithStacktrace:stacktrace message:message timestamp:@([AHSystemTool getTimestamp]) type:@"fatal"]; //加上自己的崩溃标识,比如版本号、手机型号
        }
        
        if (defaultExceptionHandler) {
            defaultExceptionHandler(exception);
        }
        
     }
    
    @implementation ANCrashHandler
    + (void)setDefaultHandler {
        defaultExceptionHandler = NSGetUncaughtExceptionHandler();
        NSSetUncaughtExceptionHandler(&ANCrashHandler);
    }
    @end
    

    相关文章

      网友评论

          本文标题:编写SDK注意事项

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