2014-09-21 3 views
1

извините за мой плохой английский :)Handle JSON ответ с Alamofire в Swift

У меня есть проблема для синтаксического анализа ответа JSON над Alamofire в Swift для приложения IOS. Я написал функцию, чтобы вернуть строку ответа JSON. Обработка запроса и ответа выполняется с помощью Alamofire и обработки JSON с помощью SwiftyJSON. В начале я объявляю var под названием jsonString со значением test. Затем я делаю запрос к службе REST и получаю ответ JSON, нажимая кнопку. Этот ответ я хочу вернуться с помощью функции ping (url: String). В конце я напечатаю возвращаемый ответ в качестве теста. Но при первом нажатии на кнопку возвращаемое значение от ping - тест, а не строка ответа 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

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: [String: String] = [ "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)!) 
     }) 
    } 
Смежные вопросы