首页 文章

在Swift中使用Alamofire处理JSON响应

提问于
浏览
1

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

我在Swift中针对iOS应用程序解析Alamofire上的JSON响应时遇到问题 . 我写了一个函数来返回一个JSON响应字符串 . 请求和响应处理我使用Alamofire和JSON处理我使用SwiftyJSON . 在开始时,我声明一个名为 jsonString 的var,其值为 test . 然后,我向REST服务发出请求,并通过单击按钮获取JSON响应 . 这个响应我想用函数 ping(url:String) 返回 . 最后,我打印返回的响应作为测试 . 但是在第一次单击按钮时, ping 的返回值是 test 而不是响应的JSON字符串 . 在第二次单击按钮时,我得到正确的返回值 . 为什么我有这个问题 . Alamofire请求是异步操作吗?我想等待回应 . 如何解决问题以便在第一次点击时获得正确的值而不是 test 作为值?

这是我的代码:

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

    在第一次单击时,代码

    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

    你也可以尝试跑步

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

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

    你有两个解决方案:

    • 异步返回结果

    • 等待异步调用完成

    我've written a response to this very same question a few minutes ago on this thread, I' ll建议你看一下:https://stackoverflow.com/a/33130512/422288

  • 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)!)
            })
        }
    

相关问题