├── .gitignore ├── LICENSE ├── NetBaseUrl.swift ├── NetworkTool.swift └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | # Package.resolved 41 | .build/ 42 | 43 | # CocoaPods 44 | # 45 | # We recommend against adding the Pods directory to your .gitignore. However 46 | # you should judge for yourself, the pros and cons are mentioned at: 47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 48 | # 49 | # Pods/ 50 | 51 | # Carthage 52 | # 53 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 54 | # Carthage/Checkouts 55 | 56 | Carthage/Build 57 | 58 | # fastlane 59 | # 60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 61 | # screenshots whenever they are needed. 62 | # For more information about the recommended setup visit: 63 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 64 | 65 | fastlane/report.xml 66 | fastlane/Preview.html 67 | fastlane/screenshots/**/*.png 68 | fastlane/test_output 69 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 cxm 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NetBaseUrl.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NetBaseUrl.swift 3 | // Kongming_Swift 4 | // 5 | // Created by chenXming on 2018/5/25. 6 | // Copyright © 2018年 bitauto. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | //MARK: - 反馈接口 11 | //反馈提交 12 | let cmd_custInsertUserFeedback = "cust/insertUserFeedback" 13 | // 反馈 列表 14 | let cmd_custSelectUserFeedback = "cust/selectUserFeedback" 15 | //图片上传 反馈 16 | let cmd_custImgUpdate = "cust/imgUpdate" 17 | 18 | //MARK: - 内容营销 19 | //栏目列表 20 | let cmd_contentDictList = "content/dictList" 21 | //产品列表 22 | let cmd_contentUserProduct = "content/app/product" 23 | //产品详情 24 | let cmd_contentProductInfo = "content/product/info" 25 | //往期回顾 列表 26 | let cmd_contentProductHistoryList = "content/app/historyProduct" 27 | 28 | //MARK: - 发票模块 29 | //筛选条件 30 | let cmd_GetInvoiceMenu = "GetInvoiceMenu" 31 | //发票列表 32 | let cmd_GetInvoiceList = "GetInvoiceList" 33 | // 发票明细 34 | let cmd_GetInvoiceInfo = "GetInvoiceInfo" 35 | //合同信息 36 | let cmd_GetInvoiceContractInfo = "GetInvoiceContractInfo" 37 | //更新签收状态 38 | let cmd_SaveInvoiceStatus = "SaveInvoiceStatus" 39 | //上传回执信息 40 | let cmd_SaveInvoiceUrl = "SaveInvoiceUrl" 41 | //获取审批信息 42 | let cmd_GetInvoiceLog = "GetInvoiceLog" 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /NetworkTool.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkTool.swift 3 | // Kongming_Swift 4 | // 5 | // Created by chenXming on 2018/5/4. 6 | // Copyright © 2018年 bitauto. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Alamofire 11 | import SwiftyJSON 12 | import SVProgressHUD 13 | // 登录服务 14 | private var LogInBase_Url = "" 15 | // 孔明普通服务 16 | private var ProgressBase_Url = "" 17 | // 发票服务 18 | //private var BillHttpsSever = "" 19 | 20 | /* 21 | * 配置你的网络环境 22 | */ 23 | enum NetworkEnvironment{ 24 | case Development 25 | case Test 26 | case Distribution 27 | } 28 | 29 | let CurrentNetWork : NetworkEnvironment = .Test 30 | 31 | private func judgeNetwork(network : NetworkEnvironment = CurrentNetWork){ 32 | 33 | if(network == .Development){ 34 | 35 | LogInBase_Url = "http://dev-***.com/common-portal/" 36 | ProgressBase_Url = "http://dev-***.com/isp-kongming/" 37 | 38 | 39 | }else if(network == .Test){ 40 | 41 | LogInBase_Url = "http://test-***.com/common-portal/" 42 | ProgressBase_Url = "http://test-***.com/isp-kongming/" 43 | 44 | }else{ 45 | 46 | LogInBase_Url = "https://***.com/common-portal/" 47 | ProgressBase_Url = "https://***.com/isp-kongming/" 48 | 49 | } 50 | 51 | } 52 | 53 | 54 | protocol NetworkToolDelegate { 55 | // 登录请求 56 | static func goToLogin(userName:String,password:String,completionHandler: @escaping(_ dict:[String : AnyObject]) -> (), errorHandler: @escaping(_ errorMsg : String) ->(), networkFailHandler: @escaping(_ error : Error) -> ()) 57 | //GET 请求 58 | static func makeGetRequest(baseUrl : String,parameters : [String:AnyObject],successHandler: @escaping(_ json:JSON) ->(),errorMsgHandler : @escaping(_ errorMsg : String) ->(),networkFailHandler:@escaping(_ error : Error) -> ()) 59 | 60 | //POST 请求 61 | static func makePostRequest(baseUrl : String,parameters : [String:Any],successHandler: @escaping(_ json:JSON) ->(),errorMsgHandler : @escaping(_ errorMsg : String) ->(),networkFailHandler:@escaping(_ error : Error) -> ()) 62 | 63 | /* 图片上传 请求 64 | * imageData : 图片二进制数组 65 | */ 66 | static func upDataIamgeRequest(baseUrl : String,parameters : [String : String],imageArr : [UIImage],successHandler: @escaping(_ dict:JSON) ->(),errorMsgHandler : @escaping(_ errorMsg : String) -> (),networkFailHandler: @escaping(_ error:Error) -> ()) 67 | 68 | } 69 | 70 | extension NetworkToolDelegate{ 71 | 72 | // 图片上传 73 | static func upDataIamgeRequest(baseUrl : String,parameters : [String : String],imageArr : [UIImage],successHandler: @escaping(_ dict:JSON) ->(),errorMsgHandler : @escaping(_ errorMsg : String) -> (),networkFailHandler: @escaping(_ error:Error) -> ()){ 74 | 75 | judgeNetwork(); 76 | 77 | let URL = ProgressBase_Url + baseUrl 78 | 79 | let userCookies = UserDefaults.standard.object(forKey: "userCookies") 80 | 81 | var header : [String : String]? 82 | 83 | if(userCookies != nil){ 84 | 85 | header = ["Cookie":"\(userCookies!)","Set-Cookie":"\(userCookies!)","X-Requested-With":"XMLHttpRequest","Content-Type" : "application/json; charset=utf-8"] 86 | 87 | } 88 | 89 | if(imageArr.count == 0){ 90 | 91 | return; 92 | } 93 | 94 | let image = imageArr.first; 95 | let imageData = UIImageJPEGRepresentation(image!, 0.5) 96 | 97 | Alamofire.upload(multipartFormData: { (multipartFormData) in 98 | 99 | multipartFormData.append(imageData!, withName: "file", fileName: "file.jpg", mimeType: "image/jpeg") 100 | //如果需要上传多个文件,就多添加几个 101 | //multipartFormData.append(imageData, withName: "file", fileName: "123456.jpg", mimeType: "image/jpeg") 102 | //...... 103 | 104 | }, usingThreshold: SessionManager.multipartFormDataEncodingMemoryThreshold, to: URL, method: .post, headers: header) { (encodingResult) in 105 | 106 | // print(encodingResult) 107 | switch encodingResult { 108 | case .success(let upload, _, _): 109 | //连接服务器成功后,对json的处理 110 | upload.responseJSON { response in 111 | //解包 112 | guard let value = response.result.value else { return } 113 | let json = JSON(value) 114 | // print(json) 115 | // 请求成功 但是服务返回的报错信息 116 | guard json["errorCode"].intValue == 0 else { 117 | 118 | if(json["errorCode"].intValue == 50000){ // Token 过期重新登录 119 | 120 | errorMsgHandler(json["errorMsg"].stringValue) 121 | 122 | SVProgressHUD.showInfo(withStatus: "授权失效,请重新登录!") 123 | 124 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+1.5) { 125 | NotificationCenter.default.post(name: NSNotification.Name(rawValue: RELOGIN_NOTIFY), object: nil) 126 | } 127 | return 128 | } 129 | 130 | errorMsgHandler(json["errorMsg"].stringValue) 131 | return 132 | } 133 | 134 | if json["result"].dictionary != nil{ 135 | 136 | successHandler(json["result"]) 137 | return 138 | }else{ 139 | 140 | successHandler(json) 141 | return 142 | } 143 | } 144 | /* 145 | //获取上传进度 146 | upload.uploadProgress(queue: DispatchQueue.global(qos: .utility)) { progress in 147 | print("图片上传进度: \(progress.fractionCompleted)") 148 | } 149 | */ 150 | 151 | case .failure(let encodingError): 152 | 153 | networkFailHandler(encodingError) 154 | //打印连接失败原因 155 | // print(encodingError) 156 | 157 | } 158 | } 159 | } 160 | 161 | // Get 请求 162 | static func makeGetRequest(baseUrl : String,parameters : [String:AnyObject],successHandler: @escaping(_ json:JSON) ->(),errorMsgHandler : @escaping(_ errorMsg : String) ->(),networkFailHandler:@escaping(_ error : Error) -> ()){ 163 | 164 | judgeNetwork(); 165 | 166 | let URL = ProgressBase_Url + baseUrl 167 | 168 | let dict = parameters 169 | let userCookies = UserDefaults.standard.object(forKey: "userCookies") 170 | 171 | 172 | var header : [String : String]? 173 | 174 | if(userCookies != nil){ 175 | 176 | header = ["Cookie":"\(userCookies!)","Set-Cookie":"\(userCookies!)","X-Requested-With":"XMLHttpRequest"] 177 | 178 | } 179 | 180 | Alamofire.request(URL, method: .get, parameters: dict, encoding: URLEncoding.default, headers: header).responseJSON { (response) in 181 | 182 | print("resopnse===\(response)") 183 | // 网络连接或者服务错误的提示信息 184 | guard response.result.isSuccess else 185 | { networkFailHandler(response.error!); return } 186 | 187 | if let value = response.result.value { 188 | let json = JSON(value) 189 | // 请求成功 但是服务返回的报错信息 190 | guard json["errorCode"].intValue == 0 else { 191 | 192 | if(json["errorCode"].intValue == 50000){ // Token 过期重新登录 193 | 194 | errorMsgHandler(json["errorMsg"].stringValue) 195 | 196 | SVProgressHUD.showInfo(withStatus: "授权失效,请重新登录!") 197 | 198 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+1.5) { 199 | 200 | NotificationCenter.default.post(name: NSNotification.Name(rawValue: RELOGIN_NOTIFY), object: nil) 201 | } 202 | return 203 | } 204 | 205 | errorMsgHandler(json["errorMsg"].stringValue) 206 | 207 | return 208 | } 209 | 210 | if json["result"].dictionary != nil{ 211 | 212 | successHandler(json["result"]) 213 | return 214 | }else{ 215 | 216 | successHandler(json) 217 | return 218 | } 219 | } 220 | } 221 | } 222 | 223 | static func makePostRequest(baseUrl : String,parameters : [String:Any],successHandler: @escaping(_ json:JSON) ->(),errorMsgHandler : @escaping(_ errorMsg : String) ->(),networkFailHandler:@escaping(_ error : Error) -> ()){ 224 | 225 | let manager = SessionManager.default 226 | manager.delegate.sessionDidReceiveChallenge = { 227 | session,challenge in 228 | return (URLSession.AuthChallengeDisposition.useCredential,URLCredential(trust:challenge.protectionSpace.serverTrust!)) 229 | } 230 | 231 | 232 | judgeNetwork(); 233 | 234 | let URL = ProgressBase_Url + baseUrl 235 | 236 | let userCookies = UserDefaults.standard.object(forKey: "userCookies") 237 | 238 | var header : [String : String]? 239 | 240 | if(userCookies != nil){ 241 | 242 | header = ["Cookie":"\(userCookies!)","Set-Cookie":"\(userCookies!)","X-Requested-With":"XMLHttpRequest","Content-Type" : "application/json; charset=utf-8"] 243 | 244 | } 245 | // JSONEncoding 与 URLEncoding 服务接受数据的区别 246 | Alamofire.request(URL, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: header).responseJSON { (response) in 247 | 248 | print(response.response?.allHeaderFields as Any) 249 | print(response); 250 | // 网络连接或者服务错误的提示信息 251 | guard response.result.isSuccess else 252 | { 253 | networkFailHandler(response.error!); 254 | return 255 | } 256 | 257 | if let value = response.result.value { 258 | let json = JSON(value) 259 | // print(json) 260 | // 请求成功 但是服务返回的报错信息 261 | guard json["errorCode"].intValue == 0 else { 262 | 263 | if(json["errorCode"].intValue == 50000){ // Token 过期重新登录 264 | 265 | errorMsgHandler(json["errorMsg"].stringValue) 266 | 267 | SVProgressHUD.showInfo(withStatus: "授权失效,请重新登录!") 268 | 269 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+1.5) { 270 | NotificationCenter.default.post(name: NSNotification.Name(rawValue: RELOGIN_NOTIFY), object: nil) 271 | } 272 | return 273 | } 274 | 275 | errorMsgHandler(json["errorMsg"].stringValue) 276 | return 277 | } 278 | if json["result"].dictionary != nil{ 279 | 280 | successHandler(json["result"]) 281 | return 282 | }else{ 283 | 284 | successHandler(json) 285 | return 286 | } 287 | } 288 | } 289 | } 290 | 291 | 292 | static func goToLogin(userName:String,password:String,completionHandler: @escaping(_ dict:[String : AnyObject]) -> (), errorHandler: @escaping(_ errorMsg : String) ->(), networkFailHandler: @escaping(_ error : Error) -> ()){ 293 | 294 | 295 | judgeNetwork(); 296 | let url = LogInBase_Url + "common/portal/login" 297 | 298 | 299 | let dict = ["username":userName,"password":password,"apt":"3"] 300 | Alamofire.request(url, method: .get, parameters: dict, encoding:URLEncoding.default, headers: nil).responseJSON { (response) in 301 | 302 | print(response) 303 | 304 | // 网络连接或者服务错误的提示信息 305 | guard response.result.isSuccess else 306 | { networkFailHandler(response.error!); return } 307 | // 保存 cookies 308 | let headerFields = response.response?.allHeaderFields as! [String : String] 309 | let userCookie = headerFields["Set-Cookie"] 310 | // print("userCookie>>>>>>\(userCookie ?? "0000000")") 311 | UserDefaults.standard.set(userCookie, forKey: "userCookies") 312 | UserDefaults.standard.synchronize() 313 | 314 | if let value = response.result.value { 315 | let json = JSON(value) 316 | print(json) 317 | // 请求成功 但是服务返回的报错信息 318 | guard json["errorCode"].intValue == 0 else { errorHandler(json["errorMsg"].stringValue); return } 319 | 320 | if let resultDict = json["result"].dictionary{ 321 | 322 | completionHandler(resultDict as [String : AnyObject]) 323 | 324 | } 325 | } 326 | } 327 | } 328 | } 329 | 330 | struct NetworkTool: NetworkToolDelegate {} 331 | 332 | 333 | 334 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SwiftRrequestFile 2 | Swift构建项目,使用Alamofire进行网络请求的进一步封装。 3 | 主要适用于Swift新手,具体的封装思路可以去我的[简书](https://www.jianshu.com/p/fd3672151539). 4 | --------------------------------------------------------------------------------