美文网首页
最近调试的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记录

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