我在Swift中针对iOS应用解析Alamofire上的JSON响应时遇到问题。我写了一个函数来返回一个JSON响应字符串。我使用Alamofire执行的请求和响应处理以及使用SwiftyJSON执行的JSON处理。在开始时,我声明一个名为 jsonString 的var,其值为 test 。然后,我向REST服务发出请求,并通过单击按钮获取JSON响应。我希望使用函数 ping(url:String)返回此响应。最后,我打印返回的响应作为测试。但是,首次点击按钮时, ping 的返回值为测试,而不是响应的JSON字符串。在第二次单击按钮时,我得到正确的返回值。为什么我有这个问题。 Alamofire请求是异步操作吗?我想等待回应。如何解决问题以便在第一次点击时获得正确的价值,而不是测试作为价值?
这是我的代码:
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)}
答案 0 :(得分:3)
在第一次点击时,代码
return self.jsonString
将在
之前运行.response {
(request, response, data, error) -> Void in
let json = JSONValue(data as? NSData)
self.jsonString = json.rawJSONString
}
你将在第一次从self.jsonString获得nil,你第二次点击将获得第一次点击的请求数据。
如果您使用SwiftyJSON和Alamofire,可以尝试Alamofire-SwiftyJSON
答案 1 :(得分:1)
您也可以尝试运行
dispatch_sync(dispatch_get_main_queue()) {
// insert code you need done the first time around - it will wait
}
答案 2 :(得分:0)
您遇到的问题是您试图同步返回异步方法的结果。
您有两种解决方案:
几分钟前我已经在这个帖子上写过对这个问题的回复,我建议你查看一下:https://stackoverflow.com/a/33130512/422288
答案 3 :(得分:0)
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”:“DeviceIDString”,“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)!)
})
}