一:加密(PBKDF2 , AES)
1,[UInt8] :
将Data数据转换为[UInt8](bytes字节数组)
//获取安全随机数 static func getRandomSalt(length: Int) -> (Data, OSStatus){ var data = Data(count: length) var local = data let result = local.withUnsafeMutableBytes { mutableBytes in SecRandomCopyBytes(kSecRandomDefault, data.count, mutableBytes) } // (数据,结果) return (local,result) }
// Data -> [UInt8] 将Data数据转换为[UInt8](bytes字节数组) let ivbytes = local.withUnsafeBytes { [UInt8](UnsafeBufferPointer(start: $0, count: local.count)) }
二 ,闭包使用
1,作网络请求参数:
/** POST NSDictionary-result */ static func POST_DICT(urlStr:String,paramDic:NSDictionary?,headerDic:[String:String]? ,success:@escaping ((_ result:NSDictionary)->()) ,failure:@escaping ((_ err : NSError) -> ())){ // Lute : 1234567890 https://cloudbackup.hwcloudtest.cn:18443/servicesupport/updateserver/data/COTA?ParamId=BTFCM530 // let urlStr = "https://cloudbackup.hwcloudtest.cn:18443/servicesupport/updateserver/data/COTA?ParamId=BTFCM530" let url = NSURL.init(string: urlStr) let request : NSMutableURLRequest = NSMutableURLRequest.init(url: url! as URL) request.httpMethod = "POST" // Header // > 字典形式统一设置Header // request.allHTTPHeaderFields = headerDic // > 逐条设置Header // request.setValue("1234567890", forHTTPHeaderField:"Device-ID") let session: URLSession = URLSession.shared let dataTask: URLSessionDataTask = session.dataTask(with: request as URLRequest) { (data, response, error) in if(error == nil){ // 解析数据 //(此处返回的数据是JSON格式的,因此使用NSJSONSerialization进行反序列化处理) var dict:NSDictionary? = nil do { dict = try (((JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.init(rawValue: 0)) as? NSDictionary))) } catch let err as NSError { LogUtils.print(err) } LogUtils.print("session === %@",dict as Any) if dict != nil { success(dict!) }else { ToastUtils.show("版本检查异常") let err = NSError.init(domain: "网络请求数据解析异常!", code: 10000, userInfo: nil) failure(err as NSError) } }else { ToastUtils.show("网络请求异常") failure(error! as NSError) } } // 执行任务 dataTask.resume() }
二 , 属性变量参数
var selectedCallBack: ((_ selectPeripheral: CBPeripheral) -> ())?
convenience init(cancelCallBack: (() -> ())?, selectedCallBack: ((_ selectPeripheral: CBPeripheral) -> ())?) {
self.init(frame: CGRect(x: 0 , y: 0, UIScreen.main.bounds.width , height: UIScreen.main.bounds.height))
addSubview(coverView)
self.cancelCallBack = cancelCallBack
self.selectedCallBack = selectedCallBack
self.tableView.delegate = self
self.tableView.dataSource = self
tableView.tableFooterView = UIView(frame: CGRect(x: 0, y: 0, 0, height: 0.1))
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
defer {
tableView.deselectRow(at: indexPath, animated: true)
}
let device = dataSource[indexPath.row]
if selectedCallBack != nil {
selectedCallBack!(device)
}
dismiss()
}
三, APPStore版本更新.
// 检查版本更新 func checkAppVersion(){ NetUtil.POST_DICT(urlStr: "http://itunes.apple.com/cn/lookup?id=1438415183", paramDic: nil, headerDic: nil, success: { (result) in let version = ((result["results"] as! NSArray)[0] as! NSDictionary).object(forKey: "version") LogUtils.print("APPStore version =",version!) let localVersion = (Bundle.main.infoDictionary! as NSDictionary)["CFBundleShortVersionString"] as! NSString LogUtils.print(localVersion) let result = localVersion.compare(version as! String, options: .numeric) if result == ComparisonResult.orderedAscending { // localVersion smaller LogUtils.print("APPStore get a new Version!") UserDefaults.standard.set(true, forKey: Const.APPSTORE_NEW_VERSION) }else { UserDefaults.standard.set(false, forKey: Const.APPSTORE_NEW_VERSION) } }, failure: { (error) in LogUtils.print("NetUtil Post err =",error) }) }
四, 多Target ,马甲开发。
========= 判断该控制器是否正在显示=======
+(BOOL)isCurrentViewControllerVisible:(UIViewController *)viewController { return (viewController.isViewLoaded && viewController.view.window); }
也可以将该方法定义在UIViewController的分类中, 方便多处调用
假如一个UIView对象当前正在显示,那么它的window属性肯定为非空值。
虽然官方文档未说明UIView未显示时window属性的取值,但是经过简单的测试,大部分情况下UIView未显示时,
window的值为空,因此依据此判断当前UIViewController是否正在显示。但是访问UIViewController的view属性时,
可能会引起view加载(假如此时还未加载),这是不必要的,而且还可能引起无法预期的问题。因此在访问view属性之前,最好先检查isViewLoaded属性来避免上述问题。
六, 蓝牙 BLE
1,APP打开了蓝牙权限时,系统蓝牙打开提示框 是否开启key : CBCentralManagerOptionShowPowerAlertKey