在Swift中使用Alamofire处理XML数据

我开始在目前的ios项目中使用cocoapods。 我需要使用SOAP以简单的方式为我的ios项目获取内容。 我用谷歌搜索了它,Alamofire pod对我来说很棒。 因为我使用的是Swift编程语言。

我很容易看到这个吊舱。 但我的Web服务返回XML结果。 我想序列化以对此XML结果进行排序。 但我不能。

当我用浏览器调用我的Web服务时,我得到了这种结果

在此处输入图像描述

Alamofire响应方法是这样的:

Alamofire.request(.GET, "http://my-web-service-domain.com", parameters: nil) .response { (request, response, data, error) in println(request) println(response) println(error) } 

当我运行此方法时,我在终端上看到此输出:

  { URL: http://my-web-service-domain.com } Optional( { URL: http://my-web-service-domain.com } { status code: 200, headers { "Cache-Control" = "private, max-age=0"; "Content-Length" = 1020; "Content-Type" = "text/xml; charset=utf-8"; Date = "Thu, 18 Jun 2015 10:57:07 GMT"; Server = "Microsoft-IIS/7.5"; "X-AspNet-Version" = "2.0.50727"; "X-Powered-By" = "ASP.NET"; } }) nil 

我想得到一个数组的结果,在浏览器上看到我的故事板。 有人可以帮助我如何使用Alamofire框架或Swift语言序列化这些数据吗?

如果我没有误解你的描述,我想你想获得XML数据并解析它,对吧? 对此,您可以在响应回调中处理错误的变量。 您应该println(data)来检查XML文档。

要解析XML数据,可以考虑使用SWXMLHash 。 Alamofire请求可能如下所示:

 Alamofire.request(.GET, "http://my-web-service-domain.com", parameters: nil) .response { (request, response, data, error) in println(data) // if you want to check XML data in debug window. var xml = SWXMLHash.parse(data!) println(xml["UserDTO"]["FilmID"].element?.text) // output the FilmID element. } 

有关XML管理的更多信息,请查看SWXMLHash 。

截至2015年9月和Xcode 7使用Alamofire 3.0当前版本。

下面的实现具有不使用诸如SWXMLHash之类的附加外部库的优点

 Alamofire.request(.GET, urlString, encoding: .PropertyList(.XMLFormat_v1_0, 0)).responsePropertyList { request, response, result in //Note that result have two properties: error and value as of Alamofire 3.0, check the migration guide for more info if let error = result.error { print("Error: \(error)") // parsing the data to an array } else if let array = result.value as? [[String: String]] { if array.isEmpty { print("No data") } else { //Do whatever you want to do with the array here } } } 

Alamofire 4.x – Swift 3.x

(请注意,在此示例中,我使用URLEncoding.default而不是URLEncoding.xml因为xml参数排除了传递参数和标头的可能性,因此default更加容易。)

 let url = "https://httpbin.org/get" let parameters: Parameters = ["foo": "bar"] let headers: HTTPHeaders = [ "Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==", "Accept": "application/json" ] Alamofire.request(url, method: .get, parameters: parameters, encoding: URLEncoding.default, headers: headers) .responseString { response in print(" - API url: \(String(describing: response.request!))") // original url request var statusCode = response.response?.statusCode switch response.result { case .success: print("status code is: \(String(describing: statusCode))") if let string = response.result.value { print("XML: \(string)") } case .failure(let error): statusCode = error._code // statusCode private print("status code is: \(String(describing: statusCode))") print(error) } } 

根据3.0.0-beta.3 README和Alamofire 3.0迁移指南 , Alamofire 2015年10月3日和Xcode 7。

对我来说,正确的语法是:

 Alamofire.request(.GET, url, parameters: params, encoding: ParameterEncoding.URL).responsePropertyList { response in if let error = response.result.error { print("Error: \(error)") // parsing the data to an array } else if let array = response.result.value as? [[String: String]] { if array.isEmpty { print("No data") } else { //Do whatever you want to do with the array here } } } 

如果您想要一个好的XML解析器,请查看SWXMLHash 。

一个例子可能是: let xml = SWXMLHash.parse(string)

如果要将XML映射到swift对象,您还可以考虑使用XMLMapper 。 (使用与ObjectMapper相同的技术)

通过实现XMLMappable协议创建模型:

 class UserDTO: XMLMappable { var nodeName: String! var extensionData: String? var canChangeDeviceConfig: BooleanAtttribute? var canChangeDriverConfig: BooleanAtttribute? var canChangeFleetConfig: BooleanAtttribute? var canChangeGeofenceConfig: BooleanAtttribute? var canSaveHistory: BooleanAtttribute? var canViewReport: BooleanAtttribute? var canWatchHistory: BooleanAtttribute? var deliverDailyReportByEmail: BooleanAtttribute? var deliverDailyReportBySms: BooleanAtttribute? var email: String? var firm: String? var firmId: Int? var firstName: String? var id: Int? var isActive: Bool? var isAdmin: Bool? var lastName: String? var phone: String? var recivesDailyReport: BooleanAtttribute? var userName: String? required init(map: XMLMap) { } func mapping(map: XMLMap) { extensionData <- map["ExtensionData"] canChangeDeviceConfig <- map["CanChangeDeviceConfig"] canChangeDriverConfig <- map["CanChangeDriverConfig"] canChangeFleetConfig <- map["CanChangeFleetConfig"] canChangeGeofenceConfig <- map["CanChangeGeofenceConfig"] canSaveHistory <- map["CanSaveHistory"] canViewReport <- map["CanViewReport"] canWatchHistory <- map["CanWatchHistory"] deliverDailyReportByEmail <- map["DeliverDailyReportByEmail"] deliverDailyReportBySms <- map["DeliverDailyReportBySms"] email <- map["Email"] firm <- map["Firm"] firmId <- map["FirmId"] firstName <- map["FirstName"] id <- map["Id"] isActive <- (map["IsActive"], BooleanTransformeType(trueValue: "true", falseValue: "false")) isAdmin <- (map["IsAdmin"], BooleanTransformeType(trueValue: "true", falseValue: "false")) lastName <- map["LastName"] phone <- map["Phone"] recivesDailyReport <- map["RecivesDailyReport"] userName <- map["UserName"] } } class BooleanAtttribute: XMLMappable { var nodeName: String! var booleanValue: Bool? required init(map: XMLMap) { } func mapping(map: XMLMap) { booleanValue <- (map.attributes["xsi:nil"], BooleanTransformeType(trueValue: "true", falseValue: "false")) } } class Firm: XMLMappable { var nodeName: String! var extensionData: String? var firmTypeId: Int? var id: Int? var name: String? var parentFirmId: Int? required init(map: XMLMap) { } func mapping(map: XMLMap) { extensionData <- map["ExtensionData"] firmTypeId <- map["FirmTypeId"] id <- map["Id"] name <- map["Name"] parentFirmId <- map["ParentFirmId"] } } class BooleanTransformeType: XMLTransformType { typealias Object = Bool typealias XML = T private var trueValue: T private var falseValue: T init(trueValue: T, falseValue: T) { self.trueValue = trueValue self.falseValue = falseValue } func transformFromXML(_ value: Any?) -> Bool? { if let value = value as? T { return value == trueValue } return nil } func transformToXML(_ value: Bool?) -> T? { if value == true { return trueValue } return falseValue } } 

并使用XMLMapper类将XML字符串映射到模型对象:

 let userDTO = XMLMapper().map(XMLString: xmlString) 

您可以使用Requests subspec和responseXMLObject(completionHandler:)函数将响应直接映射到模型对象中:

 Alamofire.request("http://my-web-service-domain.com", method: .get).responseXMLObject { (response: DataResponse) in let userDTO = response.result.value print(userDTO?.id ?? "nil") } 

我希望这很有用。

我有一个非常独特的问题,即服务器返回一个将JSON作为字符串的XML。 希望它会帮助某人。

基本上XML看起来像这样:

 {"Response":{"Status":"success","Result_Count":"1","Error_Description":"","Result":{"Login_result":{"user_id":"1","user_type":"1","user_name":"h4cked","user_locked":"False","user_locked_message":""}}}} 

正如您所看到的,实际的JSON是{"Response":....

该解决方案仅基于Alamofire 4.4。

你需要做的是:

  1. 使用.responsePropertyList
  2. 检查错误
  3. 将值转换为数据
  4. 序列化为JSON对象
  5. 转换为字典[String : Any]

这里是:

 Alamofire.request(NetworkAPIPaths.pathForLogin(), method: .get, parameters: [APIParameters.userName.rawValue : "", APIParameters.password.rawValue : ""]).responsePropertyList { (response : DataResponse) in if let error = response.result.error { // Error... } else if let jsonFullString = response.result.value as? String { if let jsonStringAsData = jsonFullString.data(using: .utf8) { do { let jsonGhost = try JSONSerialization.jsonObject(with: jsonStringAsData, options: []) if let actualJSON = jsonGhost as? [String : Any] { // actualJSON is ready to be parsed :) } } catch { print (error.localizedDescription) } } } 

tsaiid在Swift 3和Alamofire 4中的回答:

 Alamofire.request("http://my-web-service-domain.com", parameters: nil) //Alamofire defaults to GET requests .response { response in if let data = response.data { println(data) // if you want to check XML data in debug window. var xml = SWXMLHash.parse(data) println(xml["UserDTO"]["FilmID"].element?.text) // output the FilmID element. } }