美文网首页
最近调试的2个小bug记录

最近调试的2个小bug记录

作者: seasonZhu | 来源:发表于2019-07-11 10:28 被阅读0次

最近一周都在调试OC项目中的bug.

枚举中定义的值,存入数据库中再取出来就改变了

之前定义了一个枚举, 里面有一个枚举项是Error,我给它赋值为-9999

/**
 车的控制器类型
 */
typedef NS_ENUM(NSUInteger, CarAuthType) {
    
    /**
     通过网络请求进行控制
     */
    
    CarAuthTypeSmartTravel = 10010, // 智慧出行
    CarAuthTypeGeofence = 10017, // 电子围栏
    CarAuthTypeWifi = 10001, // 车载Wifi
    CarAuthTypeCarflow = 10003, // 车载流量
    CarAuthTypeCarTrack = 10004, // 车辆追踪
    CarAuthTypeTrafficReport = 10005, // 车况报告
    CarAuthTypeDrivingReport = 10006, // 驾驶行为
    CarAuthTypeLllegal = 10007, // 违章查询
    CarAuthTypeTrackList = 10008, // 行车日志
    CarAuthTypeError = -9999, // 类型错误
    
    /*
     本地控制
     */
    CarAuthTypeOnlineStore = 1000, // 在线商店
    CarAuthTypeMapUpdate = 1001, // 地图升级
    CarAuthTypeCallService = 1002, // 一键呼叫
    CarAuthTypeUpweek = 1003, // 预约保养
    CarAuthTypeAccountControl = 1004, // 账号模块
    CarAuthTypeDiscover = 1005, // 发现模块
    
};

然后我需要将其与网络请求获取的code码进行匹配,下面这种写法看起来很奇葩,比如网络请求返回的code为10010,但是我还是用OC的枚举表示,并且使用switch,这里借鉴的是Swift中的匹配模式的思路,一般情况下大家更喜欢在这里使用if else if else 结构.

/**
 通过serviceCode获取业务类型
 悲剧的OC 这个枚举不是一个对象,所以不能返回nil 我不得不定义了Error类型
 @param serviceCode 业务码
 @return 业务类型
 */
- (CarAuthType)getCarAuthTypeFromServiceCode:(NSString *)serviceCode {
    NSInteger code = ((NSNumber *)serviceCode).integerValue;
    switch (code) {
        case CarAuthTypeSmartTravel:
            return CarAuthTypeSmartTravel;
            
        case CarAuthTypeGeofence:
            return CarAuthTypeGeofence;
            
        case CarAuthTypeWifi:
            return CarAuthTypeWifi;
            
        case CarAuthTypeCarflow:
            return CarAuthTypeCarflow;
            
        case CarAuthTypeCarTrack:
            return CarAuthTypeCarTrack;
            
        case CarAuthTypeTrafficReport:
            return CarAuthTypeTrafficReport;
            
        case CarAuthTypeDrivingReport:
            return CarAuthTypeDrivingReport;

        case CarAuthTypeLllegal:
            return CarAuthTypeLllegal;
            
        case CarAuthTypeTrackList:
            return CarAuthTypeTrackList;
            
        default:
            return CarAuthTypeError;
    }
}

最后我要将这个业务类型保存到数据库中,使用的数据库框架是FMDB,使用了LKDBHelper工具进行了封装.
那么问题就来了,定义的CarAuthTypeError明明为-9999,然后写入数据库后拿出来的却是-512000,我个人觉得这个地方和数据的位数与这个负号运算符有关系
我将CarAuthTypeError定义为9999,这样话数据库写与读都没有异常.
结论:
虽然在OC中我们经常定义枚举,并且定义其值,而且有关错误的值会向负数定义,但是在数据库操作上可能会出现不必要的麻烦,所以可以将错误类型定义为较大的正整数

字符+问题

这是我在Xcode上,编写的需要传递给后台的字符串

appId=dssp&message={"message":{"body":"2组合商品(流量+多服务+地图升级)","channel":"APP","orderNo":"2019071014000059511706","payType":"TENWXPAY","productId":"45","subject":"CAPSA商城2019071014000059511706","timeOut":"","totalFee":"0.01","tradeType":"APP","vin":"VF7CAPSA000000077"}}&protocolId=TENWXPAY010401&t=1562738401861&thirdInfoId=7&userId=2667

这是后台接收到我的字符串

appId=dssp&message={"message":{"body":"2组合商品(流量 多服务 地图升级)","channel":"APP","orderNo":"2019071014000059511706","payType":"TENWXPAY","productId":"45","subject":"CAPSA商城2019071014000059511706","timeOut":"","totalFee":"0.01","tradeType":"APP","vin":"VF7CAPSA000000077"}}&protocolId=TENWXPAY010401&t=1562738401861&thirdInfoId=7&userId=2667

注意看其中的细微差别没有, 注意body中文字,iOS端是有+号的,而后台Java解析后是没有+的号.
其实这个位置的问题是我们前后端 都要用同一个Key拼接后取md5,然后做校验,明显的前后端的字符串不一样,那么获取的md5也会不一样.
其实这里的主要问题就是iOS对字符串的编码问题,对于上面的字符串,其实我们不应该直接用这种原始的编码,而是要做一点过滤

NSString *body = [[NSString stringWithFormat:@"appId=%@&userId=%@&protocolId=%@&thirdInfoId=%@&t=%@&h=%@&message=%@",request.appId,request.userId,request.protocolId,request.thirdInfoId,request.t,request.h,request.message] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:@"#%<>[\\]^`{|}\"]+"].invertedSet];
NSLog(@"body: %@", body);

其实这个问题在Alamofire中已经有很明显的代码,自己在阅读的时候,看到过却没有去深究其原因,这也是自己的问题呀

    /// Returns a percent-escaped string following RFC 3986 for a query string key or value.
    ///
    /// RFC 3986 states that the following characters are "reserved" characters.
    ///
    /// - General Delimiters: ":", "#", "[", "]", "@", "?", "/"
    /// - Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
    ///
    /// In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow
    /// query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/"
    /// should be percent-escaped in the query string.
    ///
    /// - parameter string: The string to be percent-escaped.
    ///
    /// - returns: The percent-escaped string.
    public func escape(_ string: String) -> String {
        let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
        let subDelimitersToEncode = "!$&'()*+,;="

        var allowedCharacterSet = CharacterSet.urlQueryAllowed
        allowedCharacterSet.remove(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)")

        var escaped = ""

        //==========================================================================================================
        //
        //  Batching is required for escaping due to an internal bug in iOS 8.1 and 8.2. Encoding more than a few
        //  hundred Chinese characters causes various malloc error crashes. To avoid this issue until iOS 8 is no
        //  longer supported, batching MUST be used for encoding. This introduces roughly a 20% overhead. For more
        //  info, please refer to:
        //
        //      - https://github.com/Alamofire/Alamofire/issues/206
        //
        //==========================================================================================================

        if #available(iOS 8.3, *) {
            escaped = string.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? string
        } else {
            let batchSize = 50
            var index = string.startIndex

            while index != string.endIndex {
                let startIndex = index
                let endIndex = string.index(index, offsetBy: batchSize, limitedBy: string.endIndex) ?? string.endIndex
                let range = startIndex..<endIndex

                let substring = string[range]

                escaped += substring.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? String(substring)

                index = endIndex
            }
        }

        return escaped
    }

相关文章

  • 最近调试的2个小bug记录

    最近一周都在调试OC项目中的bug. 枚举中定义的值,存入数据库中再取出来就改变了 之前定义了一个枚举, 里面有一...

  • 记录使用performSelector产生的bug和调试过程

    说说NSObject的 performSelector 系列函数 记录调试这个bug的过程 说说遇到的bug   ...

  • 微信小程序时间转时间戳小bug

    记录微信小程序开发中一次遇到的bug,时间转时间戳,在调试工具中用new Date(时间戳).getTime()或...

  • 常见bug解决系列--linux安装openJdk1.8但jst

    前言 此系列文章长期连载,旨在记录常见bug问题,供大家调试自查使用 bug描述 linux虚拟机安装的openJ...

  • iOS Bug调试小技巧

    我们在开发中,经常遇到偶现的bug,这些bug很多都是网络差的情况下出现的,而且都是用户出现的,我们在正常测试过程...

  • Bug 调试

    定位问题首先一定要想法确定 bug 的原因,或者定位 bug 的位置,那个文件的哪一行。对于安开发来说有很多时候。...

  • Bug调试

  • 调试Bug

    1. 数组初始化 A = np.zeros(n_symb) 初始化的数组,当计算时,结果的值是复数,但是赋值给A的...

  • 解决xib自定义tableFooterView一个神奇的bug

    最近看视频学习,做一个demo的时候碰到一个神奇的bug,后来经过各种搜索、调试和修改代码虽然把这个bug解决了,...

  • 小程序小bug记录

    1、text标签样式无效 自定义组件中css条件渲染class,动态点击切换css样式,同一个text标签重复点击...

网友评论

      本文标题:最近调试的2个小bug记录

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