在Swift中使用Alamofire处理JSON响应

时间:2014-09-21 06:24:33

标签: ios iphone json swift alamofire

抱歉我的英语不好:)

我在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)}

4 个答案:

答案 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)

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

您有两种解决方案:

  1. 异步返回结果
  2. 等待异步调用完成
  3. 几分钟前我已经在这个帖子上写过对这个问题的回复,我建议你查看一下: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)!)
        })
    }