使用 POST 请求 iOS Swift 3 发送嵌套 JSON

Posted

技术标签:

【中文标题】使用 POST 请求 iOS Swift 3 发送嵌套 JSON【英文标题】:Send Nested JSON With POST Request iOS Swift 3 【发布时间】:2017-07-10 07:04:35 【问题描述】:

我想通过 POST 请求将 JSON 发送到服务器,但我不明白我是如何做到的。我从表格视图中选择朋友并在我的收藏视图中显示这些朋友。并且选定的人显示在集合视图中,他们的电子邮件以 JSON 格式发送到创建组。这是我用 Swift 编写的代码。

@IBAction func createGroupButton(_ sender: Any) 

    let groupName = groupNameTextField.text

    let adminEmail = UserDefaults.standard.value(forKey: "userEmail")


    if groupName == "" 

    alertMessage(msg: "Enter Group name")

    

    else if base64String == nil 

        alertMessage(msg: "Select Group Image")

    

    else if emailArray.isEmpty 

        alertMessage(msg: "Select atleast one person")

    


    else 


    if isNetAvailable 

        var emailData: String?

        print("email data \(emailArray)")

        for i in emailArray 


         emailData = "\"email\":\"\(i)\""

        

    let postData = "\"name\":\"\(groupName!)\",\"adminemail\":\"\(adminEmail!)\",\"image\":\"\(base64String!)\",\"emailArray\":\"\(emailData!)\""


    let postDat = "jsondata=\(postData)"

    print("Post Data \(postDat)")


    let urlString = create_group

    let url = URL(string: urlString)


    var request = URLRequest(url: url!)

    request.httpMethod = "POST"

    request.httpBody = postDat.data(using: String.Encoding.utf8)

    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    let session = URLSession.shared

    let task = session.dataTask(with: request)  (data, response, error) in

        if error != nil 

        print("Something wrong with creating Group")

        

        if data == nil 

            print("Nil Data")

        

        if response == nil 
            print("Nil Response")

        

        if response != nil 
            let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)

            print("Response String is \(responseString)")
        
    
    task.resume()

    

    else 
        alertMessage(msg: "Internet Not Available")
     

            

这是我的 API

<?php

if($_SERVER["REQUEST_METHOD"] !="POST") exit; 
require_once 'dbcon.php';
if (!empty($_POST['jsondata']))

$configjson = $_POST['jsondata'];

$config = json_decode($configjson, true);

$groupname = $config['name'];
$adminemail = $config['adminemail'];
$image = $config['image'];

$queryemailcheck = "SELECT * FROM groups_name WHERE admin =   '$adminemail' AND groupname = '$groupname'";
$selectquery = mysqli_query($connect, $queryemailcheck);
$totalemails= mysqli_num_rows($selectquery);
if($totalemails>0)

echo "Already exist";

else 
$queryinsert= "INSERT INTO groups_name(admin , groupname , pic ) VALUES('$adminemail' ,'$groupname' , '$image')";

if(mysqli_query($connect, $queryinsert))
    echo "Successfully Saved";
else
    echo "Error: " ;

$members = $config['emailArray'];
foreach($members as $row )
$email = $row['email'];

$queryinsert2= "INSERT INTO group_members(groupname , member , status    ) VALUES('$groupname' ,'$email' , '0')";

if(mysqli_query($connect, $queryinsert2))
    echo "Successfully Saved";
else
    echo "Error: " ;







else echo "post data is empty";
?>

【问题讨论】:

检查你的 json 格式,这似乎不正确,如果你传递的是 json 对象,你会使用 NSJSONSerialization 类来获取数据,然后在 http 正文中设置它 请在下方查看我的回答 【参考方案1】:

您可以使用 Alamofire 库来处理您的网络服务。喜欢

Alamofire.request(logoutUrl, method: .post, parameters: dict, encoding: JSONEncoding.default, headers:["Authorization":"Bearer \(accessToken)", "Accept":"application/json", "Content-Type":"application/json; charset=UTF-8"]).responseJSON  (response) in

            let json:JSON = JSON(response.result.value)

            let status =  json["status"].stringValue
            let statusCode = response.response?.statusCode

【讨论】:

我没有使用 Alamofire。我正在使用 URL Session,我想以这种方式完成这项任务。【参考方案2】:

创建网络处理程序类,您可以在其中访问所有应用程序中的 Web 服务。

func makeHttpPostRequest(uri:String, postBody:Dictionary<String, Any>  ,Completion:@escaping (_ response: AnyObject, _ success: Bool) -> Void) 
    let networkCheck = self.getNetworkStatus()
    if networkCheck == false 
        Completion("NO internet connection." as AnyObject,false)
        return
    //end network check block
    var urlRequest = self.makeHttpRequestWithUrl(url: uri)
    urlRequest.httpMethod = "POST"
    urlRequest.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
    urlRequest.setValue("application/json", forHTTPHeaderField: "Accept")
    //check and set authorization header
    if (UserDefaults.standard.object(forKey: AppConstant.KAppAuthenticationToken) != nil) 
        let authToken = UserDefaults.standard.object(forKey: AppConstant.KAppAuthenticationToken) as! String
        urlRequest.setValue("Token token="+authToken, forHTTPHeaderField: "Authorization")
    
    //let postData = [self.addDefultParameters(detailDict: postBody)]
    let jsonData = try? JSONSerialization.data(withJSONObject: postBody)
    urlRequest.httpBody = jsonData

    //create connection
    self.httpConnectionWithRequest(request: urlRequest, Completion: Completion)


func makeHttpRequestWithUrl(url: String) -> URLRequest 
    let urlString = AppConstant.baseUrl+url
    let networkUrlRequest = URLRequest.init(url: URL.init(string: urlString)!, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: 50)
    return networkUrlRequest


func httpConnectionWithRequest(request: URLRequest, Completion:@escaping (_ response: AnyObject, _ success: Bool) -> Void) 
    let session = URLSession.shared
    // make the request
    let task = session.dataTask(with: request) 
        (data, response, error) in
        // check for any errors
        guard error == nil else 
            print("error is: " + String.init(format: "%@", error?.localizedDescription as! CVarArg))
            Completion(error!.localizedDescription as String as AnyObject, false)
            return
        
        // make sure we got data
        guard let responseData = data else 
            print("Error: did not receive data")
            Completion("didn't get response data" as String as AnyObject, false)
            return
        

        let responseString =  String.init(data: responseData, encoding: .utf8)
        // parse the result as JSON, since that's what the API provides

        if let resp = response as? HTTPURLResponse

            if (UserDefaults.standard.object(forKey: AppConstant.KAppAuthenticationToken) != nil) 
                if resp.statusCode == 401
                    //auth token expired

                    self.makeRequestWithNewToken(request: request, Completion: Completion)
                
            
            //check if response is Array or dictionary
            var jsonArray:[Any]?
            var jsonDict:[String:Any]?


            // response is in array
            do
                jsonArray = try JSONSerialization.jsonObject(with: responseData, options: [])as? [Any]
            catch
                print("response doesn't contain array")
            
            //response is in dictionary
            do
                jsonDict  = try JSONSerialization.jsonObject(with: responseData, options: [])as? [String:Any]
            catch
                print("response doesn't contain dict")
            
            //=====
          //  if resp.statusCode == 200

                if jsonArray != nil
                    Completion(jsonArray! as AnyObject, true)
                    return
                

                if jsonDict != nil
                    Completion(jsonDict! as AnyObject, true)
                    return
                

                Completion("didn't get response data" as String as AnyObject, false)
                return
        

    
    task.resume()
        

通过完成处理程序,您将获得获取的数据。

【讨论】:

以上是关于使用 POST 请求 iOS Swift 3 发送嵌套 JSON的主要内容,如果未能解决你的问题,请参考以下文章

从 iOS 9 / Swift 2.0 发送 HTTP POST 请求时,PHP 服务器没有收到正确的数据

使用 Alamofire 3.0+ 在 swift 2.2 中使用 JSON 对象发送 POST 请求

如何在 Swift 3 中使用 Alamofire 在 POST 请求中将给定的 JSON 作为参数发送?

如何在 Swift 3 的 POST 请求中发送表单数据

如何在 iOS swift 中使用 AVPlayer 请求发送参数?

Swift 3 URLSession 发送空请求