// // ResourceAllocationUtils.swift // MTP2_iOS // // Created by Muchinfo on 2018/6/28. // Copyright © 2018年 Muchinfo. All rights reserved. // import Foundation import Reachability import SwiftDate enum ConfigType: String { case appVersion = "appVersion" case url = "url" } /// 通用配置工具类 class ConfigUtils { /// getValue /// - Parameter key: key /// - Returns: Any static func getValue(key: ConfigType) -> Any? { if let path = Bundle.main.path(forResource: "Config", ofType: "plist"), let dic = NSDictionary(contentsOfFile: path) { return dic[key.rawValue] } return nil } /// 资源类型 /// /// - mineFunctionModule: 我的模块功能项 /// - functionModule: 大功能模块 /// - payWay: 支付方式 /// - tradeLink: 链路信息模块 /// - supportOAuth: 是否支持三方登录 /// - isShowTotleVolume: 是否展示成交量 /// - SupportResetPwd 是否支持重置密码 /// - SupportMobileLogin 是否支持手机登录 /// - AreaUrl: 通用地址 enum ResourceType: String { case mineFunctionModule = "mine's function module" case functionModule = "function module" case payWay = "pay way" case tradeLink = "trade link" case supportOAuth = "SupportOAuth" case SupportResetPwd = "SupportResetPwd" case SupportMobileLogin = "SupportMobileLogin" case UpdateUrl = "UpdateUrl" case AreaUrl = "areaUrl" } /// getValue /// - Parameter key: ResourceType /// - Returns: Any static func getValue(key: ResourceType) -> Any? { if let appVersion = ConfigUtils.getValue(key: .appVersion) as? String, let path = Bundle.main.path(forResource: appVersion, ofType: ".plist"), let dic = NSDictionary(contentsOfFile: path) { return dic[key.rawValue] } return nil } /// 获取对应服务的服务地址信息 /// - Parameter type: type /// - Returns: String static func getServiceUrl(resourceType type: ResourceType) -> String? { /// 判断是否第一次运行 guard let array = ConfigUtils.getValue(key: .tradeLink) as? Array> else { dPrint("【\(#function)】错误的配置文件") return "" } switch type { case .AreaUrl: /// 通用地址 #if DEBUG return (array[0]["addressUrl"] as? String) ?? "" #else return (array[0]["addressUrl_release"] as? String) ?? "" #endif case .UpdateUrl: /// app更新地址 return (array[0]["updateUrl"] as? String) ?? "" default: return "" } } } /// 错误码工具类 class ErrorCodeUtils { static func getValue(key: String) -> Any? { if let path = Bundle.main.path(forResource: "ErrorCode", ofType: "plist"), let dic = NSDictionary(contentsOfFile: path) { return dic[key] } return nil } } /// 错误信息工具类 class ErrorUtils { static func desc(_ errorCode: Int?) -> String { /// 先判断网络装药 let reachability = try! Reachability() /// 检测网络连接状态 if reachability.connection != .unavailable { /// 先尝试从数据库中获取 let entity = try? DatabaseHelper.getError(errorcode: "\(errorCode ?? -60001)") if entity != nil { return entity!.errordesc! } /// 再深度从自定义错误中获取 if let errorMessage = ErrorCodeUtils.getValue(key: String(errorCode ?? -60001)) as? String { return errorMessage } return "请求超时" } return "当前网络不可用" } } /// 合规性校验工具 class RegularUtils { /// 检查电话号码 /// /// - Parameter str: 待校验字符串 /// - Returns: 是否验证通过 static func checkPhoneNumber(with str: String) -> Bool { let regex = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$" let test = NSPredicate(format: "SELF MATCHES %@", regex) return test.evaluate(with: str) } /// 校验只包含数字 /// /// - Parameter str: 待校验字符串 /// - Returns: 是否验证通过 static func checkNumber(with str: String) -> Bool { let regex = "\\d+" let test = NSPredicate(format: "SELF MATCHES %@", regex) return test.evaluate(with: str) } /// 校验是否有效身份证号码 /// - Parameter cardNo: 身份证号码 /// - Returns: 校验结果 static func isValidIDCard(_ cardNo: String) -> Bool { let regex = "^(^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$)|(^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])((\\d{4})|\\d{3}[Xx])$)$" let predicate = NSPredicate(format: "SELF MATCHES %@", regex) /// 校验18位有效身份证 if !predicate.evaluate(with: cardNo) || cardNo.count != 18 { return false } /// 将前17位加权因子保存在数组里 let idCardWiArray = ["7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2"] /// 这是除以11后,可能产生的11位余数、验证码,也保存成数组 let idCardYArray = ["1", "0", "10", "9", "8", "7", "6", "5", "4", "3", "2"] /// 用来保存前17位各自乖以加权因子后的总和 var idCardWiSum = 0 for i in 0..<17 { let subStrIndex = Int(NSString(string: cardNo).substring(with: NSRange(location: i, length: 1)))! let idCardWiIndex = Int(idCardWiArray[i])! idCardWiSum += subStrIndex*idCardWiIndex } /// 计算出校验码所在数组的位置 let idCardMod=idCardWiSum%11 /// 得到最后一位身份证号码 let idCardLast = NSString(string: cardNo).substring(with: NSRange(location: 17, length: 1)) /// 不管大小写都过 if idCardMod == 2 { if idCardLast.uppercased() != "X" { return false } } else { /// 用计算出的验证码与最后一位身份证号码匹配,如果一致,说明通过,否则是无效的身份证号码 if idCardLast != idCardYArray[idCardMod] { return false } } return true } /// 密码校验 /// /// - Parameter str: 待校验字符串 /// - Returns: 是否验证通过 static func checkAllCharactersPatten(check str: String) -> Bool { let lowercase = ".*[a-z]+.*" let captial = ".*[A-Z]+.*" let number = ".*[0-9]+.*" let punctuation = ".*[`~!@#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?]+.*" let test1 = NSPredicate(format: "SELF MATCHES %@", lowercase) let test2 = NSPredicate(format: "SELF MATCHES %@", captial) let test3 = NSPredicate(format: "SELF MATCHES %@", number) let test4 = NSPredicate(format: "SELF MATCHES %@", punctuation) var regularNum = 0 if test1.evaluate(with: str) { regularNum += 1 } if test2.evaluate(with: str) { regularNum += 1 } if test3.evaluate(with: str) { regularNum += 1 } if test4.evaluate(with: str) { regularNum += 1 } return regularNum >= 3 } /// 校验证件号 /// /// - Parameter str: 待检验字符串 /// - Returns: 是否验证通过 static func checkCertificate(with str: String) -> Bool { if str.count > 30 || str.contains("{") || str.contains("}") || str.contains("(") || str.contains(")") || str.contains("*") { return false } else { return true } } static func stringPaddedForBase64(_ base64String: String) -> String { let paddedLength = base64String.count + (base64String.count%3) return base64String.padding(toLength: paddedLength, withPad: "=", startingAt: 0) } } /// 日期工具类 class DateUtils { /// 判断两个日期是否在同年的同一个月 static func judgeSameYearMonth(target: Date, source: Date = Date()) -> Bool { let calendar = Calendar.current let targetComponents = calendar.dateComponents(Set([.year, .month]), from: target) let sourceComponents = calendar.dateComponents(Set([.year, .month]), from: source) if calendar.date(from: targetComponents)!.compare(calendar.date(from: sourceComponents)!) == .orderedSame { return true } return false } /// 获取带T的时间戳的时间字符串 /// - Parameter dateString: dateString /// - Returns: String static func getTDateString(_ dateString: String, _ formatter: String = "yyyy-MM-dd") -> String { let dateFormatter = DateFormatter() let tempLocale = dateFormatter.locale dateFormatter.locale = Locale(identifier: "en_US_POSIX") dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" let date = dateFormatter.date(from: dateString) ?? Date() dateFormatter.dateFormat = formatter dateFormatter.locale = tempLocale return dateFormatter.string(from: date) } /// 获取带T的时间戳的时间字符串 /// - Parameter dateString: dateString /// - Returns: String static func getTDate(_ dateString: String, _ formatter: String = "yyyy-MM-dd") -> Date { let string = dateString.getTDateString() guard let date = string.toDate(formatter: formatter) else { return Date() } return date } /// 获取两个时间戳间隔时分秒 /// - Parameters: /// - timer1: timer1 /// - timer2: timer2 /// - count: count /// - Returns: String static func diffs(_ timer1: TimeInterval, _ timer2: TimeInterval, _ count: Double) -> DateComponents? { let formatter = DateFormatter() formatter.dateStyle = .medium formatter.timeStyle = .short formatter.dateFormat = "YYYY-MM-dd HH:mm:ss" let date1 = Date(timeIntervalSince1970: timer1-count) let date2 = Date(timeIntervalSince1970: timer2) /// 日历对象(方便比较两个日期之间的差距) let calendar = Calendar.current return calendar.dateComponents(Set([.hour, .minute, .second]), from: date1, to: date2) } } /// 以后用这个方法输出log信息,可以在release下剔除log /// /// - Parameter item: 输出内容 func dPrint(_ item: @autoclosure () -> Any) { #if DEBUG debugPrint(item()) #endif }