在Swift中用Alamofire处理JSON响应

对不起,我的英语不好 :)

我有一个问题来parsing在iOS应用程序的Swift的Alamofire的JSON响应。 我写了一个函数来返回一串JSON响应。 请求和响应处理我用Alamofire和JSON处理我用SwiftyJSON处理。 在开始我声明一个叫做jsonString的var值testing 。 然后我做一个REST服务的请求,并通过点击一个button来得到一个JSON响应。 这个回应我想用函数ping(url:String)返回 。 最后,我打印返回的答案作为一个testing。 但是在第一次点击button时,来自ping的返回值是test,而不是响应的JSONstring。 在第二次点击button我得到正确的返回值。 为什么我有这个问题。 Alamofire是否请求asynchronous操作? 我想等待回应。 我怎样才能解决问题,以获得正确的价值,第一次点击,而不是testing值?

这是我的代码:

var jsonString:String = "test" func ping(url:String) -> String { Alamofire.request(.GET, url) .response { (request, response, data, error) -> Void in let json = JSONValue(data as? NSData) self.jsonString = json.rawJSONString } return self.jsonString } @IBAction func checkOnlineStatus(sender: UIButton) { let response:String = ping("http://test.com") println(response)} 

在第一次点击,代码

 return self.jsonString 

将运行之前

 .response { (request, response, data, error) -> Void in let json = JSONValue(data as? NSData) self.jsonString = json.rawJSONString } 

您将在第一次获得无forms的self.jsonString,您第二次点击将获得第一次点击的请求数据。

如果你使用SwiftyJSON和Alamofire,你可以试试Alamofire-SwiftyJSON

你也可以尝试跑步

 dispatch_sync(dispatch_get_main_queue()) { // insert code you need done the first time around - it will wait } 

你遇到的问题是你正试图同步返回一个asynchronous方法的结果。

你有两个解决scheme:

  1. asynchronous返回结果
  2. 等待asynchronous调用完成

我已经写了几分钟前在这个线程上回答这个同样的问题,我build议你检查一下: https : //stackoverflow.com/a/33130512/422288

 pod 'Alamofire' pod 'SwiftyJSON' pod 'ReachabilitySwift' import UIKit import Alamofire import SwiftyJSON import SystemConfiguration class WebServiceHelper: NSObject { typealias SuccessHandler = (JSON) -> Void typealias FailureHandler = (Error) -> Void // MARK: - Internet Connectivity class func isConnectedToNetwork() -> Bool { var zeroAddress = sockaddr_in() zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size) zeroAddress.sin_family = sa_family_t(AF_INET) guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, { $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { SCNetworkReachabilityCreateWithAddress(nil, $0) } }) else { return false } var flags: SCNetworkReachabilityFlags = [] if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) { return false } let isReachable = flags.contains(.reachable) let needsConnection = flags.contains(.connectionRequired) return (isReachable && !needsConnection) } // MARK: - Helper Methods class func getWebServiceCall(_ strURL : String, isShowLoader : Bool, success : @escaping SuccessHandler, failure : @escaping FailureHandler) { if isConnectedToNetwork() { print(strURL) if isShowLoader == true { AppDelegate.getDelegate().showLoader() } Alamofire.request(strURL).responseJSON { (resObj) -> Void in print(resObj) if resObj.result.isSuccess { let resJson = JSON(resObj.result.value!) if isShowLoader == true { AppDelegate.getDelegate().dismissLoader() } debugPrint(resJson) success(resJson) } if resObj.result.isFailure { let error : Error = resObj.result.error! if isShowLoader == true { AppDelegate.getDelegate().dismissLoader() } debugPrint(error) failure(error) } } }else { CommonMethods.showAlertWithError("", strMessage: Messages.NO_NETWORK, withTarget: (AppDelegate.getDelegate().window!.rootViewController)!) } } class func getWebServiceCall(_ strURL : String, params : [String : AnyObject]?, isShowLoader : Bool, success : @escaping SuccessHandler, failure :@escaping FailureHandler){ if isConnectedToNetwork() { if isShowLoader == true { AppDelegate.getDelegate().showLoader() } Alamofire.request(strURL, method: .get, parameters: params, encoding: JSONEncoding.default, headers: nil).responseJSON(completionHandler: {(resObj) -> Void in print(resObj) if resObj.result.isSuccess { let resJson = JSON(resObj.result.value!) if isShowLoader == true { AppDelegate.getDelegate().dismissLoader() } success(resJson) } if resObj.result.isFailure { let error : Error = resObj.result.error! if isShowLoader == true { AppDelegate.getDelegate().dismissLoader() } failure(error) } }) } else { CommonMethods.showAlertWithError("", strMessage: Messages.NO_NETWORK, withTarget: (AppDelegate.getDelegate().window!.rootViewController)!) } } class func postWebServiceCall(_ strURL : String, params : [String : AnyObject]?, isShowLoader : Bool, success : @escaping SuccessHandler, failure :@escaping FailureHandler) { if isConnectedToNetwork() { if isShowLoader == true { AppDelegate.getDelegate().showLoader() } Alamofire.request(strURL, method: .post, parameters: params, encoding: JSONEncoding.default, headers: nil).responseJSON(completionHandler: {(resObj) -> Void in print(resObj) if resObj.result.isSuccess { let resJson = JSON(resObj.result.value!) if isShowLoader == true { AppDelegate.getDelegate().dismissLoader() } success(resJson) } if resObj.result.isFailure { let error : Error = resObj.result.error! if isShowLoader == true { AppDelegate.getDelegate().dismissLoader() } failure(error) } }) }else { CommonMethods.showAlertWithError("", strMessage: Messages.NO_NETWORK, withTarget: (AppDelegate.getDelegate().window!.rootViewController)!) } } class func postWebServiceCallWithImage(_ strURL : String, image : UIImage!, strImageParam : String, params : [String : AnyObject]?, isShowLoader : Bool, success : @escaping SuccessHandler, failure : @escaping FailureHandler) { if isConnectedToNetwork() { if isShowLoader == true { AppDelegate.getDelegate().showLoader() } Alamofire.upload( multipartFormData: { multipartFormData in if let imageData = UIImageJPEGRepresentation(image, 0.5) { multipartFormData.append(imageData, withName: "Image.jpg") } for (key, value) in params! { let data = value as! String multipartFormData.append(data.data(using: String.Encoding.utf8)!, withName: key) print(multipartFormData) } }, to: strURL, encodingCompletion: { encodingResult in switch encodingResult { case .success(let upload, _, _): upload.responseJSON { response in debugPrint(response) //let datastring = String(data: response, encoding: String.Encoding.utf8) // print(datastring) } case .failure(let encodingError): print(encodingError) if isShowLoader == true { AppDelegate.getDelegate().dismissLoader() } let error : NSError = encodingError as NSError failure(error) } switch encodingResult { case .success(let upload, _, _): upload.responseJSON { (response) -> Void in if response.result.isSuccess { let resJson = JSON(response.result.value!) if isShowLoader == true { AppDelegate.getDelegate().dismissLoader() } success(resJson) } if response.result.isFailure { let error : Error = response.result.error! as Error if isShowLoader == true { AppDelegate.getDelegate().dismissLoader() } failure(error) } } case .failure(let encodingError): if isShowLoader == true { AppDelegate.getDelegate().dismissLoader() } let error : NSError = encodingError as NSError failure(error) } } ) } else { CommonMethods.showAlertWithError("", strMessage: Messages.NO_NETWORK, withTarget: (AppDelegate.getDelegate().window!.rootViewController)!) } } } ================================== 

调用方法

让aParams:[String:String] = [“ReqCode”:Constants.kRequestCodeLogin,“StoreDCID”:strStoreID !,“CustEmail”:dictAddLogin [AddLoginConstants.kEmail] !,“Password”:dictAddLogin [AddLoginConstants.kPassword] !,“ DeviceID“:”DeviceIDtring“,”DeviceType“:”iOS“,]

  WebServiceHelper.postWebServiceCall(Constants.BaseURL, params: aParams as [String : AnyObject]?, isShowLoader: true, success: { (responceObj) in if "\(responceObj["RespCode"])" != "1" { let alert = UIAlertController(title: Constants.kAppName, message: "\(responceObj["RespMsg"])", preferredStyle: UIAlertControllerStyle.alert) let OKAction = UIAlertAction(title: "OK", style: .default) { (action:UIAlertAction!) in } alert.addAction(OKAction) self.present(alert, animated: true, completion: nil) } else { let aParams : [String : String] = [ "Password" : self.dictAddLogin[AddLoginConstants.kPassword]!, ] CommonMethods.saveCustomObject(aParams as AnyObject?, key: Constants.kLoginData) } }, failure: { (error) in CommonMethods.showAlertWithError(Constants.kALERT_TITLE_Error, strMessage: error.localizedDescription,withTarget: (AppDelegate.getDelegate().window!.rootViewController)!) }) }