2014-09-21 99 views
1

對不起我的英語不好:)手柄JSON響應斯威夫特

我必須分析在斯威夫特的iOS應用在Alamofire JSON響應的問題。我寫了一個函數來返回一串JSON響應。請求和響應處理我使用Alamofire和JSON處理我使用SwiftyJSON。在開始時,我聲明瞭一個名爲的變量jsonString,其值爲測試。然後,我向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)} 

回答

3

在第一次點擊,該代碼

return self.jsonString 

運行之前

.response { 
     (request, response, data, error) -> Void in 

     let json = JSONValue(data as? NSData) 
     self.jsonString = json.rawJSONString 
} 

你會得到無形成在self.jsonString第一次,你第二次點擊將獲得第一次點擊的請求數據。

如果使用SwiftyJSON和Alamofire你可以嘗試Alamofire-SwiftyJSON

+0

非常感謝...我會試試:) – Martin 2014-09-24 16:20:55

1

您也可以嘗試運行

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

您遇到的問題是,您要同步返回異步方法的結果。

有兩種解決方法:

  1. 返回結果異步
  2. 等待異步調用完成

我寫這個同樣的問題的答覆在幾分鐘前在這個帖子上,我建議你看看: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:[字符串:字符串] = [ 「ReqCode」:Constants.kRequestCodeLogin, 「StoreDCID」:strStoreID! 「CustEmail」:dictAddLogin [AddLoginConstants.kEmail]! 「密碼」: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)!) 
     }) 
    }