Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 通过Alamofire发送json数组_Swift_Alamofire - Fatal编程技术网

Swift 通过Alamofire发送json数组

Swift 通过Alamofire发送json数组,swift,alamofire,Swift,Alamofire,我想知道是否有可能在POST请求中直接发送一个数组(不封装在字典中)。显然,参数参数应该得到:[String:AnyObject]的映射? 但我希望能够发送以下示例json: [ "06786984572365", "06644857247565", "06649998782227" ] 您可以使用NSJSONSerialization对JSON进行编码,然后自己构建NSURLRequest。例如,在Swift 3中: var request = URLRequest(

我想知道是否有可能在POST请求中直接发送一个数组(不封装在字典中)。显然,
参数
参数应该得到:[String:AnyObject]的映射? 但我希望能够发送以下示例json:

[
    "06786984572365",
    "06644857247565",
    "06649998782227"
]

您可以使用
NSJSONSerialization
对JSON进行编码,然后自己构建
NSURLRequest
。例如,在Swift 3中:

var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")

let values = ["06786984572365", "06644857247565", "06649998782227"]

request.httpBody = try! JSONSerialization.data(withJSONObject: values)

Alamofire.request(request)
    .responseJSON { response in
        // do whatever you want here
        switch response.result {
        case .failure(let error):
            print(error)

            if let data = response.data, let responseString = String(data: data, encoding: .utf8) {
                print(responseString)
            }
        case .success(let responseObject):
            print(responseObject)
        }
}

有关Swift 2,请参阅此答案的第页。

我认为根据Alamofire文档,您可以编写如下代码:

let values = ["06786984572365", "06644857247565", "06649998782227"]

Alamofire.request(.POST, url, parameters: values, encoding:.JSON)
    .authenticate(user: userid, password: password)
    .responseJSON { (request, response, responseObject, error) in
        // do whatever you want here

        if responseObject == nil {
            println(error)
        } else {
            println(responseObject)
        }
}

下面是一个将Thing类型的数组编码为JSON的示例,使用路由器和Ogra进行JSON编码:

import Foundation
import Alamofire
import Orga

class Thing {
    ...
}

enum Router: URLRequestConvertible {
    static let baseURLString = "http://www.example.com"

    case UploadThings([Thing])

    private var method: Alamofire.Method {
        switch self {
        case .UploadThings:
            return .POST
        }
    }

    private var path: String {
        switch self {
        case .UploadThings:
            return "upload/things"
        }
    }

    var URLRequest: NSMutableURLRequest {
        let r = NSMutableURLRequest(URL: NSURL(string: Router.baseURLString)!.URLByAppendingPathComponent(path))
        r.HTTPMethod = method.rawValue

        switch self {
        case .UploadThings(let things):
            let custom: (URLRequestConvertible, [String:AnyObject]?) -> (NSMutableURLRequest, NSError?) = {
                (convertible, parameters) in
                var mutableRequest = convertible.URLRequest.copy() as! NSMutableURLRequest
                do {
                    let jsonObject = things.encode().JSONObject()
                    let data = try NSJSONSerialization.dataWithJSONObject(jsonObject, options: NSJSONWritingOptions.PrettyPrinted)
                    mutableRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
                    mutableRequest.HTTPBody = data
                    return (mutableRequest, nil)
                } catch let error as NSError {
                    return (mutableRequest, error)
                }
            }
            return ParameterEncoding.Custom(custom).encode(r, parameters: nil).0
        default:
            return r
        }
    }
}

Swift 2.0
此代码位于post对象数组下面。此代码在swift 2.0上测试

func POST(RequestURL: String,postData:[AnyObject]?,successHandler: (String) -> (),failureHandler: (String) -> ()) -> () {

        print("POST : \(RequestURL)")

        let request = NSMutableURLRequest(URL: NSURL(string:RequestURL)!)
        request.HTTPMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        var error: NSError?
        do {
             request.HTTPBody  = try NSJSONSerialization.dataWithJSONObject(postData!, options:[])


        } catch {
            print("JSON serialization failed:  \(error)")
        }

        Alamofire.request(request)
            .responseString{ response in
                switch response.result {
                case .Success:
                    print(response.response?.statusCode)
                    print(response.description)
                    if response.response?.statusCode == 200 {
                        successHandler(response.result.value!)
                    }else{
                        failureHandler("\(response.description)")
                    }

                case .Failure(let error):
                    failureHandler("\(error)")
                }
        }

    }

对于swift 3和Alamofire 4,我使用以下
参数SENCODING
数组
扩展:

import Foundation
import Alamofire

private let arrayParametersKey = "arrayParametersKey"

/// Extenstion that allows an array be sent as a request parameters
extension Array {
    /// Convert the receiver array to a `Parameters` object. 
    func asParameters() -> Parameters {
        return [arrayParametersKey: self]
    }
}


/// Convert the parameters into a json array, and it is added as the request body. 
/// The array must be sent as parameters using its `asParameters` method.
public struct ArrayEncoding: ParameterEncoding {

    /// The options for writing the parameters as JSON data.
    public let options: JSONSerialization.WritingOptions


    /// Creates a new instance of the encoding using the given options
    ///
    /// - parameter options: The options used to encode the json. Default is `[]`
    ///
    /// - returns: The new instance
    public init(options: JSONSerialization.WritingOptions = []) {
        self.options = options
    }

    public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
        var urlRequest = try urlRequest.asURLRequest()

        guard let parameters = parameters,
            let array = parameters[arrayParametersKey] else {
                return urlRequest
        }

        do {
            let data = try JSONSerialization.data(withJSONObject: array, options: options)

            if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
                urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
            }

            urlRequest.httpBody = data

        } catch {
            throw AFError.parameterEncodingFailed(reason: .jsonEncodingFailed(error: error))
        }

        return urlRequest
    }
}
基本上,它将数组转换为
字典
,以便被接受为
参数
参数,然后从字典中取回数组,将其转换为JSON
数据
,并将其添加为请求体

一旦有了请求,您可以通过以下方式创建请求:

let values = ["06786984572365", "06644857247565", "06649998782227"]
Alamofire.request(url,
                  method: .post,
                  parameters: values.asParameters(),
                  encoding: ArrayEncoding())

@manueGE的答案是正确的。根据alamofire github的指示,我有一个类似的方法: `

` 然后通过自定义请求来调用它,而不是使用带有参数的默认请求。基本上放弃该参数,因为它是一个字典

let headers = getHeaders()
    var urlRequest = URLRequest(url: URL(string: (ServerURL + Api))!)
    urlRequest.httpMethod = "post"
    urlRequest.allHTTPHeaderFields = headers
    let jsonArrayencoding = JSONDocumentArrayEncoding(array: documents)

    let jsonAryEncodedRequest = try? jsonArrayencoding.encode(urlRequest, with: nil)

    request = customAlamofireManager.request(jsonAryEncodedRequest!)
    request?.validate{request, response, data in
        return .success
        }
        .responseJSON { /*[unowned self] */(response) -> Void in
            ...
    }

另外,处理数据错误的方法非常有用。

有两种方法可以将JSON内容作为参数发送

  • 您可以将json作为字符串发送,您的web服务将在服务器上解析它

     d["completionDetail"] = "[{"YearOfCompletion":"14/03/2017","Completed":true}]"
    
  • 您可以在json中以顺序数组的形式传递每个值(
    YearOfCompletion
    Completed
    )。您的web服务将以相同的顺序插入这些数据。其语法如下所示:

    d["YearOfCompletion[0]"] = "1998"  
    d["YearOfCompletion[1]"] = "1997"  
    d["YearOfCompletion[2]"] = "1996"  
    
    d["Completed[0]"] = "true"  
    d["Completed[1]"] = "false"  
    d["Completed[2]"] = "true"  
    
  • 我一直在使用dictionary的以下web服务调用函数来触发
    Alamofire
    请求Swift3.0

    func wsDataRequest(url:String, parameters:Dictionary<String, Any>) {
        debugPrint("Request:", url, parameters as NSDictionary, separator: "\n")
    
        //check for internete collection, if not availabale, don;t move forword
        if Rechability.connectedToNetwork() == false {SVProgressHUD.showError(withStatus: NSLocalizedString("No Network available! Please check your connection and try again later.", comment: "")); return}
    
        //
        self.request = Alamofire.request(url, method: .post, parameters: parameters)
        if let request = self.request as? DataRequest {
            request.responseString { response in
                var serializedData : Any? = nil
                var message = NSLocalizedString("Success!", comment: "")//MUST BE CHANGED TO RELEVANT RESPONSES
    
                //check content availability and produce serializable response
                if response.result.isSuccess == true {
                    do {
                        serializedData = try JSONSerialization.jsonObject(with: response.data!, options: JSONSerialization.ReadingOptions.allowFragments)
                        //print(serializedData as! NSDictionary)
                        //debugPrint(message, "Response Dictionary:", serializedData ?? "Data could not be serialized", separator: "\n")
                    }catch{
                        message = NSLocalizedString("Webservice Response error!", comment: "")
                        var string = String.init(data: response.data!, encoding: .utf8) as String!
    
                        //TO check when html coms as prefix of JSON, this is hack mush be fixed on web end. 
                        do {
                            if let index = string?.characters.index(of: "{") {
                                if let s = string?.substring(from: index) {
                                    if let data = s.data(using: String.Encoding.utf8) {
                                        serializedData = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments)
                                        debugPrint(message, "Courtesy SUME:", serializedData ?? "Data could not be serialized", separator: "\n")
                                    }
                                }
                            }
                        }catch{debugPrint(message, error.localizedDescription, "Respone String:", string ?? "No respone value.", separator: "\n")}
    
                        //let index: Int = text.distance(from: text.startIndex, to: range.lowerBound)
                        debugPrint(message, error.localizedDescription, "Respone String:", string ?? "No respone value.", separator: "\n")
                    }
    
                    //call finised response in all cases
                    self.delegate?.finished(succes: response.result.isSuccess, and: serializedData, message: message)
                }else{
                    if self.retryCounter < 1 {//this happens really frequntly so in that case this fn being called again as a retry
                        self.wsDataRequest(url: url, parameters: parameters)
                    }else{
                        message = response.error?.localizedDescription ?? (NSLocalizedString("No network", comment: "")+"!")
                        SVProgressHUD.showError(withStatus: message);//this will show errror and hide Hud
                        debugPrint(message)
    
                        //call finised response in all cases
                        self.delay(2.0, closure: {self.delegate?.finished(succes: response.result.isSuccess, and: serializedData, message:message)})
                    }
                    self.retryCounter += 1
                }
            }
        }
    }
    
    func wsDataRequest(url:String,参数:Dictionary){
    debugPrint(“请求:”,url,参数为NSDictionary,分隔符:“\n”)
    //检查互联网收集,如果不可用,不要向前移动
    if Rechability.connectedtonework()==false{SVProgressHUD.bathror(状态:NSLocalizedString(“没有可用的网络!请检查您的连接,稍后再试)”,注释:);返回}
    //
    self.request=Alamofire.request(url,方法:.post,参数:parameters)
    如果let request=self.request as?DataRequest{
    request.responseString{response in
    变量序列化数据:有吗?=nil
    var message=NSLocalizedString(“成功!”,注释:)//必须更改为相关响应
    //检查内容可用性并生成可序列化的响应
    如果response.result.issucess==true{
    做{
    serializedData=尝试JSONSerialization.jsonObject(带有:response.data!,选项:JSONSerialization.ReadingOptions.allowFragments)
    //打印(将数据序列化为!NSDictionary)
    //debugPrint(消息,“响应字典:”,serializedData??“数据无法序列化”,分隔符:“\n”)
    }抓住{
    message=NSLocalizedString(“Web服务响应错误!”,注释:“”)
    var string=string.init(数据:response.data!,编码:.utf8)作为字符串!
    //要检查何时将html COM作为JSON的前缀,必须在web端修复这一问题。
    做{
    如果let index=string?.characters.index(of:“{”){
    如果让s=string?.substring(from:index){
    如果let data=s.data(使用:String.Encoding.utf8){
    serializedData=try JSONSerialization.jsonObject(with:data,options:JSONSerialization.ReadingOptions.allowFragments)
    debugPrint(消息,“礼节SUME:”,serializedData??“数据无法序列化”,分隔符:“\n”)
    }
    }
    }
    }catch{debugPrint(消息,error.localizedDescription,“响应字符串:”,字符串??“无响应值。”,分隔符:“\n”)}
    //let index:Int=text.distance(从:text.startIndex到:range.lowerBound)
    debugPrint(消息,error.localizedDescription,“响应字符串:”,字符串??“无响应值”,分隔符:“\n”)
    }
    //在所有情况下,呼叫完成响应
    self.delegate?.finished(成功:response.result.issucess和:serializedData,消息:message)
    }否则{
    如果self.retryCounter<1{//这种情况确实经常发生,那么在这种情况下,将再次调用此fn作为重试
    wsDataRequest(url:url,参数:parameters)
    }否则{
    消息=响应。错误?.localizedDescription??(NSLocalizedString(“无网络”,注释:)+“!”)
    SVProgressHUD.bathror(with status:message);//这将显示错误并隐藏Hud
    调试打印(消息)
    //在所有情况下,呼叫完成响应
    self.delay(2.0,闭包:{self.delegate?.finished(成功:response.result.issucess,和:serializedData,message:message)})
    }
    self.retryCounter+=1
    }
    }
    }
    }
    

    我在项目中上传JSON数组时所做的一些事情

    不,
    参数
    是一个
    [String:AnyObject]?
    。你不能将数组传递给它。它必须是一个字典。因此问题就来了。如果你传递一个字典对象而不是数组,这个答案将是真的。编码参数将处理其余的问题。我是
      func placeOrderApi(getUserId:String,getDateId:String,getTimeID:String,getAddressId:String,getCoupon:String)
                {
                    let data = try! JSONSerialization.data(withJSONObject: self.arrOfServices, options: [])
                    let jsonBatch : String = String(data: data, encoding: .utf8)!
                    
                    //try! JSONSerialization.data(withJSONObject: values)
                   let params = [
                       "user_id":getUserId,
                       "time_id":getTimeID,
                       "date_id":getDateId,
                       "address_id":getAddressId,
                       "services":jsonBatch,
                       "payment_mode":paymentVia,
                       "coupon":getCoupon
                    ] as [String : Any]
                   
                   print(params)
                   self.objHudShow()
                    
                    Alamofire.request(BaseViewController.API_URL + "place_order", method: .post, parameters: params, encoding: JSONEncoding.default)
                        .responseJSON { response in
                            debugPrint(response)
                   
                        
                        switch response.result {
                            
                        case .success (let data):
                            print(data)
                                    
                        self.objHudHide()
                        if response.result.value != nil
                        {
                           
                            let json : JSON = JSON(response.result.value!)
                           
                             if json["status"] == true
                             {
                               
                             }
                              else
                             {
                                self.view.makeToast(NSLocalizedString(json["msg"].string ?? "", comment: ""), duration: 3.0, position: .bottom)
                              }
                         
                                 
                        }
                                   
                            break
                                    
                        case .failure:
                                   self.objHudHide()
                                   
                                   print("Error in upload:)")
                                    break
                                }
                            }
                        }
    
    let url = try Router.baseURL.asURL()
    
    // Make Request
    var urlRequest = URLRequest(url: url.appendingPathComponent(path))
    urlRequest.httpMethod = "post"
    
    // let dictArray: [[String: Any]] = []
    urlRequest = try! JSONEncoding.default.encode(urlRequest, withJSONObject: dictArray)
    
      func placeOrderApi(getUserId:String,getDateId:String,getTimeID:String,getAddressId:String,getCoupon:String)
                {
                    let data = try! JSONSerialization.data(withJSONObject: self.arrOfServices, options: [])
                    let jsonBatch : String = String(data: data, encoding: .utf8)!
                    
                    //try! JSONSerialization.data(withJSONObject: values)
                   let params = [
                       "user_id":getUserId,
                       "time_id":getTimeID,
                       "date_id":getDateId,
                       "address_id":getAddressId,
                       "services":jsonBatch,
                       "payment_mode":paymentVia,
                       "coupon":getCoupon
                    ] as [String : Any]
                   
                   print(params)
                   self.objHudShow()
                    
                    Alamofire.request(BaseViewController.API_URL + "place_order", method: .post, parameters: params, encoding: JSONEncoding.default)
                        .responseJSON { response in
                            debugPrint(response)
                   
                        
                        switch response.result {
                            
                        case .success (let data):
                            print(data)
                                    
                        self.objHudHide()
                        if response.result.value != nil
                        {
                           
                            let json : JSON = JSON(response.result.value!)
                           
                             if json["status"] == true
                             {
                               
                             }
                              else
                             {
                                self.view.makeToast(NSLocalizedString(json["msg"].string ?? "", comment: ""), duration: 3.0, position: .bottom)
                              }
                         
                                 
                        }
                                   
                            break
                                    
                        case .failure:
                                   self.objHudHide()
                                   
                                   print("Error in upload:)")
                                    break
                                }
                            }
                        }