搜索
您的当前位置:首页正文

01|实用的轮子们

来源:二三娱乐

这篇文用于不定期更新记录自己使用的一些好用的轮子。


1.Alamofire
简而言之,用于向服务端网络请求,进行数据的获取和提交,文件的上传和下载。它的本质是基于URLSession�,对其进行了封装。

例子1:通过网络请求获取json,解析json。

//存在中文字符,需要进行编码转换
        let urlString = "这里替换成一个网络地址,可以含有中文字符。"
        let url = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
 //第二个参数是post或get,第三个参数是上传的参数。
 Alamofire.request(url!, method: .post, parameters: enterDic).responseJSON{ 
             response in
            //判断是否请求成功,成功则继续
            guard response.result.isSuccess else{
                print("Error while fetching tags: \(String(describing: response.result.error))")
                return
            }
            //JSON解析数据
            guard let  responseJSON = response.result.value as? [String: Any],
            let data = responseJSON["data"] as? [String: Any],
            let account = data["user_account"],
            let department = data["department"],
            let name = data["name"] else{              
                //数据解析失败,可能是登录失败。 
            }
            //登录成功则记住密码
        }

例子2:multipartFormData下的数据上传(包含上传图片)

Alamofire.upload(multipartFormData: {multipartFormData in
             //首先将图片进行转化以及压缩
            let data = UIImageJPEGRepresentation(self.getImage, 0.5)
            //不知道为什么,如果不加上文件名,上传返回值会提示,缺少参数
            let imageName = String(describing: NSDate()) + ".png"
            //这里是添加需要上传的数据,基本呈现键值对的形式         
            multipartFormData.append(data!, withName: "pic", fileName: imageName, mimeType: "image/png")
            multipartFormData.append(userAccount.data(using: String.Encoding.utf8)!, withName: "user_account")
            multipartFormData.append(projectNo.data(using: String.Encoding.utf8)!, withName: "project_no")
            multipartFormData.append(nodeCode.data(using: String.Encoding.utf8)!, withName: "node_code")
            multipartFormData.append(hintKey.data(using: .utf8)!, withName: "hint_key")
            multipartFormData.append(note.data(using: .utf8)!, withName: "note")
            multipartFormData.append(isOver.description.data(using: .utf8)!, withName: "is_over")
            //第二个参数 to: url,填写文件上传的url即可。
        }, to: url, encodingCompletion: {
            //我理解的是,这里会在上传结束之后进行一个回调。
            encodingResult in
            switch encodingResult{
            case .success(request: let upload, streamingFromDisk: _, streamFileURL: _):
                upload.responseJSON{ response in
                    debugPrint(response)
                    //JSON解析数据
                    guard let  responseJSON = response.result.value as? [String: Any],
                        let message = responseJSON["message"] as? String else{
                            return
                    }  
                    if message == "提交成功!"{               
                    }
                    else{                    
                        //上传失败提醒用户 
                        }
                    }
                }
            case .failure(let encodingError):
                print(encodingError)                
                //上传失败提醒用户
                }
            }
        })

2.AlamofireImage
这是对Alamofire的一个扩展,主要用于Image的下载(可能也有上传,自己并没有用)。在tableview中,使用它,cell可以在获得图片之后自己刷新UI。

例子: cell中的ImageView获取image,最终它会自己刷新UI。

//首先,自己没用到的参数,并不能删除
//第一个参数是获取image的url,第二个参数是默认的图片,第三个参数是图片过滤器
//第四个参数应该是一个回调方法,在这个过程中需要执行什么
//第五个参数是指运行在什么线程中
//第六个参数是指对图片进行什么转换,第七个应该是和缓存有关
//第八个参数是一个结束之后的回调
cell?.imageV.af_setImage(withURL: Url!, placeholderImage: #imageLiteral(resourceName: "load_fail"), 
filter: ImageFilter.self as? ImageFilter, progress: { (Progress) in }, 
progressQueue:  DispatchQueue.main, imageTransition: UIImageView.ImageTransition.noTransition, 
runImageTransitionIfCached: true, completion: { response in })

** 注: 在Alamofire & AlamofireImage中,具体执行的代码都是在UI跑完之后才进入方法里执行(并非主线程同步执行,而是异步),第一次只是跑一遍方法名。所以要注意!!!编码顺序!!!**

3.Locksmith

注: 之所以选择这个库,是因为在存储时有一个参数是Account,用来辨识存取的内容是在哪一个“名”下(类似命名空间,可增强唯一性,否则可能因为参数名相同和其他项目串了存储的数据)。

它是一个集成keychain的第三方库,可用于一些隐私性信息的存储。一般账户密码不要用NSUserDefaults进行存储,这个的安全性相比较于keychain要低得多。

例子:存储用户名和密码以作为记住密码,自动登录之用。

//存储账户和密码,导入库之后,直接Locksmith即可调用方法。
let dic = ["user": user,"password":password,"autoenter":self.isAuto,"remember": self.isRemember] as [String : Any]
            //登录成功则记住密码,这个库有个问题就是,它的方法是在try catch中的。
            do {
                try Locksmith.updateData(data: dic, forUserAccount: self.myAccount )
            } catch let error{
                print(error)
            }

    //判断登录界面自动登录
    func isAutoEnterF(){        
        let dictKey = Locksmith.loadDataForUserAccount(userAccount: self.myAccount)        
        var isAuto = dictKey?["autoenter"] as? Bool
        var isRemember = dictKey?["remember"] as? Bool        
        if isAuto == nil{
            isAuto = false
        }
        if isRemember == nil{
            isRemember = false
        }
        if isRemember! {
            btnSRemember.setImage(#imageLiteral(resourceName: "btn_select"), for: .normal)
            //取值 -> 赋值
            textUser.text = dictKey?["user"] as? String
            textPassword.text = dictKey?["password"] as? String
            if isAuto! {
                btnSAutoEnter.setImage(#imageLiteral(resourceName: "btn_select"), for: .normal)                
                self.isAuto = true
                self.isRemember = true
                //自动登录
                postEnterInfo(user: textUser.text!, password: textPassword.text!)
            }
        }else{
            //没有记住密码也就不可能自动登录,保证输入框为空
            textUser.text = ""
            textPassword.text = ""
        }        
    }

4.Reachability
用于检测和监测手机的网络状态,防止在网络不符合的情况下进行一些操作导致用户体验不佳或出现BUG,可以设置在wifi下和本机网络下的一些使用权限以节省用户流量。

例子:在代理中进行判断,手机网络状况。

var reach: Reachability?
reach = Reachability.forInternetConnection()
        if (reach?.isReachable())!{
            print("有网")
        } else{
            print("没网")

        }

5.SwiftyJSON
用于解析和生成JSON数据。它非常好的一点是,不用做太多的判断,一层一层的取值判断再得到最终想要取的值。

例子:解析JSON数据

 //JSON解析数据 网络请求得到
            guard let  responseJSON = response.result.value as? [String: Any],
                let _ = responseJSON["message"] as? String else{
                    return
            }
            //初始化一个JSON
            let json = JSON.init(responseJSON)
            let data = json["data"]
            let count = data.count
  
            for i in 0..<count{
                var arynodename = [String]()
                var arynodecode = [String]()
                let name = data[i]["name"]
                let hintkey = data[i]["hint_key"]
                //可以进行隔空取值了
                let nodenum = json["data"][i]["minor_node"]
                let num = nodenum.count
                arynodename.append(name.rawValue as! String)
                arynodecode.append(name.rawValue as! String)
                self.aryHintKey.append(hintkey.rawValue as! String)
                for j in 0 ..< num{
                    let minor_node = json["data"][i]["minor_node"][j]
                    arynodename.append(minor_node["name"].rawValue as! String)
                    arynodecode.append(minor_node["code"].rawValue as! String)
                }
                self.aryNodeName.append(arynodename)
                self.aryNodeCode.append(arynodecode)
                
            }

Top