php - 如何处理来自 Swift (iOS) 应用程序的 PHP 传入 JSON?

标签 php json swift

我有一个 iOS 应用程序 (Swift),它对一些数据进行编码并执行 JSONSerialization 并创建一个 JSON 对象。我的代码如下,我已尽力保持整洁,所以我希望它有意义:

struct Order: Codable {
    let idQty: [FoodIdAndQuantity]
    let collection: String
    let name: String
    let phone: Int
    let doorNum: Int
    let street: String
    let postcode: String
}

struct FoodIdAndQuantity: Codable {
    let itemId: Int
    let qty: Int
}

class CheckoutServer: NSObject, URLSessionDataDelegate {

    var inputValuesForItemAndQuantity = [Int:Int]()
    var idQty = [FoodIdAndQuantity]()
    var collection = String()
    var name = String()
    var phone = Int()
    var doorNum = Int()
    var street = String()
    var postcode = String()

    var request = URLRequest(url: NSURL(string: "http://192.168.1.100/api/AddOrder.php")! as URL)

    func sendToDatabase() {

        for(key,value) in inputValuesForItemAndQuantity {
            idQty.append(FoodIdAndQuantity(itemId: key, qty: value))
        }

        let order = Order(idQty: idQty,collection: collection,name: name,phone: phone,doorNum: doorNum,street: street,postcode: postcode)

        let encodedOrder = try? JSONEncoder().encode(order)

        var json: Any?

        request.httpMethod = "POST"

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

        if let data = encodedOrder {

            json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments)
            if var json = json {
                if JSONSerialization.isValidJSONObject(json) {
                    do {
                        json = try JSONSerialization.data(withJSONObject: json, options: .prettyPrinted)
                    } catch {
                        print("There was a problem creating the JSON object")
                    }

                } else {
                    print("not valid JSON")
                }
            }
        }

        let postParameters = "json="+String(describing: json!)

        print(String(describing: json!)) //Print JSON for debugging purposes

        request.httpBody = postParameters.data(using: .utf8)

        let defaultSession = URLSession(configuration: URLSessionConfiguration.default)

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

            if error != nil {
                print("Failed to download data at Menu Type Items")
            } else {
                print("Data uploaded")
            }
        }
        task.resume()
    }
}

所以上面的代码执行以下操作:

  • 创建一个名为“order”的可编码对象。
  • 创建对我的 API 的 POST 请求。
  • 通过 POST 参数传递编码的 JSON 对象。

我已经打印了 json 对象,该对象在 XCode 中发送回控制台,如下所示:

{
    collection = Delivery;
    doorNum = 99;
    idQty =     (
                {
            itemId = 17;
            qty = 5;
        },
                {
            itemId = 1;
            qty = 3;
        }
    );
    name = James;
    phone = 012345667;
    postcode = LXU49RT;
    street = Hope Street;
}

接下来,我将转到接受 POST 参数的服务器/API。

下面是我的 AddOrder.php 页面:

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    require_once dirname(__FILE__) . '/DbOperation.php';

    $json = $_POST["json"];

    $db = new DbOperation();

    $json = $db->addOrder($json);

}

下面是我的 DbOperation addOrder 函数:

public function addOrder($json) {
    require dirname(__FILE__) .  '/../../dbconnect.php';
    $decoded = json_decode($json);
    $collection = $decoded{"collection"};

    $stmt2 = $pdo->prepare("INSERT INTO TestTable (collection) VALUES (:collection)");
    $stmt2->bindParam(':collection',$collection);
    $stmt2->execute();
}

值得注意的是,当我尝试解决此问题时,我在数据库中创建了一个测试表,它仅存储 JSON 的集合元素。

我遇到的问题是,当我运行应用程序并发送数据时,数据库中没有存储任何内容,并且我的 apache error.log 文件显示列“集合”不能为空。所以我假设我在 PHP 的某个时刻错误地处理了 POST 参数。除非故障出在 Swift 级别,否则如果管理员提出要求,我会将 Swift 标签添加到这篇文章中。

完整的错误如下:

[Wed Feb 28 15:44:55.178184 2018] [:error] [pid 520] [client 192.168.1.46:52400] PHP Fatal error:  Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'collection' cannot be null in /var/www/api/DbOperation.php:111\nStack trace:\n#0 /var/www/api/DbOperation.php(111): PDOStatement->execute()\n#1 /var/www/api/AddOrder.php(16): DbOperation->addOrder(NULL)\n#2 {main}\n  thrown in /var/www/api/DbOperation.php on line 111

我尝试过的

我尝试将 AddOrder.php 页面更改为以下内容:

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    require_once dirname(__FILE__) . '/DbOperation.php';

    //$json = $_POST["json"];

    $json = json_decode(file_get_contents('php://input'),true);

    $db = new DbOperation();

    $json = $db->addOrder($json);

}

最佳答案

你的快速代码没有多大意义。您的代码使用 JSONEncoder 将 swift 对象编码为数据。如果成功,您可以使用 JSONSerialization 将数据转换回 Swift 对象。如果成功成功,则您可以使用JSONSerialization.data(withJSONObject:options:)将您的Swift对象转换为JSON数据,然后使用String(describing:) 将 JSON 数据疯狂地过度处理为字符串,这是非常非常错误的。

删除所有这些代码。试试这个:

func sendToDatabase() {

    for(key,value) in inputValuesForItemAndQuantity {
        idQty.append(FoodIdAndQuantity(itemId: key, qty: value))
    }

    let order = Order(idQty: idQty,collection: collection,name: name,phone: phone,doorNum: doorNum,street: street,postcode: postcode)

    guard let encodedOrder = try? JSONEncoder().encode(order) else { return }

    request.httpBody = encodedOrder

    let defaultSession = URLSession(configuration: URLSessionConfiguration.default)

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

        if error != nil {
            print("Failed to download data at Menu Type Items")
        } else {
            print("Data uploaded")
        }
    }
    task.resume()
}

关于php - 如何处理来自 Swift (iOS) 应用程序的 PHP 传入 JSON?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49034816/

相关文章:

php - 看不懂html和css,坐标输入表单

php - 在 phpmyadmin 和 mysql 控制台中工作时,查询对 php 的行为很奇怪。

java - Json 结构如此不同,无法将其更改为 Java 对象

java - BodyEditorLoader 中的 float 和 Dictionary 错误,如何修复?

ios - 将 RxSwift 链接到命令行工具的正确方法

ios - 从 VC1 向 VC2 传递值

php - 集成/迁移两个 CodeIgniter 应用程序。

php - 如何观察网络流量以进行 curl 调试

javascript - jQuery UI 自动完成与 json 文件

arrays - 如何从 Swift 3 中的结构数组生成 JSON?