2

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

我在为 iOS 应用程序在 Swift 中解析 A​​lamofire 上的 JSON 响应时遇到问题。我写了一个函数来返回一串 JSON 响应。我使用Alamofire进行的请求和响应处理以及我使用SwiftyJSON进行的 JSON 处理。在开始时,我声明了一个名为jsonString的变量,其值为test。然后我向 REST 服务发出请求,并通过单击按钮获得 JSON 响应。我想用函数ping(url:String)返回这个响应。最后,我打印返回的响应作为测试。但是在第一次单击按钮时,ping的返回值是test而不是响应的 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)}
4

4 回答 4

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

于 2014-09-24T02:59:32.647 回答
1

你也可以试试跑步

dispatch_sync(dispatch_get_main_queue()) {
  // insert code you need done the first time around - it will wait
}
于 2014-11-20T09:07:07.390 回答
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)!)
        })
    }
于 2016-12-10T15:43:24.187 回答
0

您遇到的问题是您试图同步返回异步方法的结果。

你有两个解决方案:

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

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

于 2015-10-14T17:52:31.400 回答