OStack程序员社区-中国程序员成长平台

标题: php - 将方法 nsdictionary 发布到 json 对象 iOS objective-c [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-13 02:03
标题: php - 将方法 nsdictionary 发布到 json 对象 iOS objective-c

我正在尝试将字典数组发送到服务器,在此之前我正在转换为 json 格式

注意:- 服务器运行良好,我在 android 中的 friend 正在获取成功发布方法的响应和数据

下面是我的post方法代码:-

NSError *error;
NSMutableDictionary *tvarns = [[NSMutableDictionary alloc] init];
tvarns[@"order_cart"]=_order_cart;

NSData *jsonData = [NSJSONSerialization dataWithJSONObject:tvarns
                                                   options:NSJSONWritingPrettyPrinted error:&error];
NSLog(@"%@",jsonData);
NSString* order_cart;

order_cart = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(@"%@",order_cart);

NSString *post = [NSString stringWithFormat"%@",order_cart];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
//  Next up, we read the postData's length, so we can pass it along in the request.
NSString *postLength = [NSString stringWithFormat"%lu", (unsigned long)[postData length]];
// Now that we have what we'd like to post, we can create an NSMutableURLRequest, and include our postData
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString"http://test.kre8tives.com/barebon/add_cartapi.php"]];
[request setHTTPMethod"OST"];
[request setValue:postLength forHTTPHeaderField"Content-Length"];
[request setHTTPBody:postData];
NSLog(@"the data Details is %@", post);
//   And finally, we can send our request, and read the reply by creating a new NSURLSession:
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; // this is json string
    NSLog(@"Reply = %@", requestReply);
    //   NSError *error;
    NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; // you need to convert to dictionary object
    NSLog(@"requestReply: %@", jsonDict);

}] resume];

[self presentViewController:alertController animated:YES completion:nil];
}

服务器想要的值是

{"order_cart":[{"customer_id":"114","item_id":14,"_id":"591d3822f55e2270202d8ff1","item_name":"Bira White","item_quantity":"2","price":"180.0","qr_code":"table21","phone":"7008841769","customer_name":"Samanthaa"},{"customer_id":"114","item_id":15,"_id":"591d3822f55e2270202d8ff0","item_name":"Bira Blonde","item_quantity":"2","price":"200.0","qr_code":"table21","phone":"7008841769","customer_name":"Samanthaa"}]}

我的 nslog 是

2017-06-28 16:16:41.334 Barebones[3139:211622] the data Details is {
"order_cart" : [
{
  "phone" : "9047038606",
  "item_quantity" : "7",
  "qr_code" : "table21",
  "item_name" : "Bottled Water",
  "price" : "175",
  "customer_id" : "116",
  "customer_name" : "Akshay"
},
{
  "phone" : "9047038606",
  "item_quantity" : "2",
  "qr_code" : "table21",
  "item_name" : "Fresh Lime Soda(Sweet, Salt, Plain)",
  "price" : "158",
  "customer_id" : "116",
  "customer_name" : "Akshay"
},
{
  "phone" : "9047038606",
  "item_quantity" : "2",
  "qr_code" : "table21",
  "item_name" : "Bottled Water",
  "price" : "50",
  "customer_id" : "116",
  "customer_name" : "Akshay"
},
{
  "phone" : "9047038606",
  "item_quantity" : "2",
  "_id" : "591d3822f55e2270202d8ff0",
  "item_name" : "Bira Blonde",
  "price" : "86",
  "qr_code" : "table21",
  "customer_id" : "116",
  "item_id" : "3971",
  "customer_name" : "Akshay"
},
{
  "phone" : "9047038606",
  "item_quantity" : "1",
  "qr_code" : "table21",
  "item_name" : "Bottled Water",
  "price" : "25",
  "customer_id" : "116",
  "customer_name" : "Akshay"
   }
 ]
}
 2017-06-28 16:16:41.485 Barebones[3139:211669] Reply =   {"order_id":3961,"success":1}
<script type='text/javascript'    src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js'>.      </script>
<script>
var data_array='{"source":{"name":"Kre8Tives","id":"SJQ6kyA1","order_id":"3961"},"customer":{"firstname":"","mobile":""},"tabType":"table","tabId":"591d3790498782970be66302","tableNumber":"1","items":null}';
alert(data_array);
 var settings = {
'async': true,
'crossDomain': true,
'url': 'http://posistapi.com/api/v1/table_order/push?customer_key=8c982f5e9ef091e9d5c8fb142311b49a68049b102de5e0987ebce29755c454227fbc7573c7da4199f126524a3ac7a39a&tabtype=table',
'method': 'OST',
'headers': {
'postman-token': 'e200ae19-d083-a98a-6db3-53fc2f8bd73f',
'cache-control': 'no-cache',
'authorization': 'Basic [removed]',
'content-type': 'application/json'
},
'processData': false,
'data': data_array,
 'acceptUrl':'http://test.kre8tives.com/barebon/order_confirm.php',
 'rejectUrl':'http://test.kre8tives.com/barebon/order_confirm.php',
 'billPrintUrl':'http://test.kre8tives.com/barebon/order_confirm.php'

}

$.ajax(settings).done(function (response) {
 console.log(response);
});
</script>
2017-06-28 16:16:41.486 Barebones[3139:211669] requestReply: (null)

我已转换为所需的儿子格式,但仍然没有收到服务器的回复

即使我发送返回我从服务器发送的数据,我也会得到空值!!为什么会这样???提前谢谢!!

这是我的 PHP 代码

<?php
include('order-function.php');
if($_SERVER["REQUEST_METHOD"] == "OST") 
{

  $order_cart=$_POST['order_cart'];

  $items=json_decode($order_cart,true);

include('dbconfig.php');
$response = array();
try
    {
        $total_item_price=0;

        foreach ($items['order_cart'] as $item) {   //['order_cart']

        $customer_id=$item['customer_id'];
        $customer_name=$item['customer_name'];
        $phone=$item['phone'];
    $_id=$item['_id'];
        $item_name=$item['item_name'];
        $item_quantity=$item['item_quantity'];
        $price=$item['price'];
        $qr_code=$item['qr_code'];

  $products[]=array(
      "_id"=>"$_id",
      "item_name"=> $item_name,
      "item_price"=> $price,
            "item_quantity"=> $item_quantity

    );          

    $price_new+=$price;


       $item_push[]=array(
      "id"=>"$_id",
      "rate"=> $price,
            "quantity"=> $item_quantity

    );
      }


      $product_details=json_encode($products);
    $add_to_cart = "INSERT INTO order_cart (customer_id,product_details,order_amount,qr_code) VALUES ('$customer_id','$product_details','$price_new','$qr_code')";
      $result = mysqli_query($conn,$add_to_cart);
      $order_id=mysqli_insert_id($conn);

        if ($result) {

    $data['source']=array("name"=>"Kre8Tives",
                            "id"=>"SJQ6kyA1",
                  "order_id"=>"$order_id"
                );
    $data['customer']=array(
                        "firstname"=>"$customer_name",
                   "mobile"=>"$phone"
                );
     $data['tabType']= "table";
       $data['tabId']= "591d3790498782970be66302";
       $data['tableNumber']= "1";

       //items
       $data_one=json_encode($item_push,JSON_NUMERIC_CHECK);
       $data_new=json_decode($data_one);
       $data['items']=$data_new;

       $data_item=json_encode($data);


  $response["order_id"] = $order_id;
  $response["success"] = 1;

     // print_r(json_encode($data));die;


} else {
            $response["success"] = 0;
        }







 echo json_encode($response);
 push_order($data_item);

    }
catch(Exception $e)
    {
        $response["success"] = 0;
        $response["message"] = "error occured";
    }
}
?>



Best Answer-推荐答案


坦率地说,查看您的 NSLog 结果,看起来服务器代码在 JSON 结果之后错误地返回了一些额外的 HTML(从 <script> 行开始) .查看 $response 的正文,它报告成功,但看起来响应中包含了一些额外的文本,可能是 push_order 的结果,或者是一些 HTML在 %> 之后,或者插入一些额外 HTML 的一些 Web 服务错误。

关注您的客户端请求代码,它应该设置 Content-TypeAccept header ,但这并不重要。但是设计良好的请求应该这样做。关键问题是 PHP 在输出 JSON 之前或之后应该不输出任何其他内容。

对于它的值(value),如果您的 Web 服务期待一个真正的 JSON 请求,我会建议对您的客户端代码进行一系列简化(除了设置这两个额外的 header 之外)。例如,只需将 NSJSONSerialization 的输出作为 httpBody 发送;不要拿那个NSData,把它转换成一个NSString,然后再把它转换回一个NSData。只需发送 jsonData 作为 httpBody:

NSDictionary *tvarns = @{@"order_cart": _order_cart};

NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:tvarns
                                                   options:0
                                                     error:&error];

// if you want to see the JSON, you can do this, but this is not needed
//
// NSString *order_cart = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
// NSLog(@"%@",order_cart);

// none of this stuff is needed; at worst, it can introduce encoding problems; at best, it's inefficient to do all that stuff
//
// NSString *post = [NSString stringWithFormat"%@",order_cart];
// NSLog(@"the data Details is %@", post);
// NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
// //  Next up, we read the postData's length, so we can pass it along in the request.
// NSString *postLength = [NSString stringWithFormat"%lu", (unsigned long)[postData length]];

// Now that we have what we'd like to post, we can create an NSMutableURLRequest, and include our jsonData

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];

[request setURL:[NSURL URLWithString"http://test.kre8tives.com/barebon/add_cartapi.php"]];
[request setHTTPMethod"OST"];

// you don't need this, because NSURLSession sets the length for you
//
// [request setValue:postLength forHTTPHeaderField"Content-Length"];

// use the original jsonData here

[request setHTTPBody:jsonData];

// you should, if you're a good web-service citizen, set the header; it's not always needed, but it's advisable

// tell the server that you're sending JSON request

[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

// tell the server that you're expecting JSON response

[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];

// Unless you need a new session for some reason, it's better to use the shared session

NSURLSession *session = [NSURLSession sharedSession];

[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    if (error) {
        NSLog(@"error: %@", error);
    }

    if (!data) {
        return;
    }

    NSError *parseError;
    NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError]; // you need to convert to dictionary object
    if (jsonDict) {
        NSLog(@"requestReply: %@", jsonDict);
    } else {
        NSLog(@"parseError: %@", parseError);
        NSLog(@"response: %@", response); // when you have failure, it's sometimes useful to see what this says
        NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; // this is json string
        NSLog(@"requestReply: %@", requestReply);
    }
}] resume];

再次,在提出这些简化建议后,我真的怀疑服务器代码中存在错误,包括 <script>... 之后的所有垃圾。我敢打赌,您的 Android 代码在响应结束时忽略了所有这些错误数据,而 NSJSONSerialization 正确指出响应在技术上不是格式正确的 JSON。 (顺便说一下,我上面的代码会正确记录 JSON 错误。)


查看您添加到修改后问题中的 PHP 代码,它正在抓取 $order_cart=$_POST['order_cart'];,这意味着您的 Web 服务需要一个 x-www-form-urlencoded 请求。然后,PHP 代码继续将 $items 定义为 json_decode($order_cart,true),然后使用 foreach 迭代到 $items[ 'order_cart']。这意味着 Web 服务期待 x-www-form-urlencoded 请求,其与 order_cart 键关联的值本身就是一个由 order_cart< 键控的 JSON 字典(再次),即请求正文将类似于 order_cart={"order_cart":[...]}

这不是一个非常优雅的设计,但如果你坚持这样做,你将不得不创建 x-www-form-urlencoded 请求,其键是 order_cart ,其值为 {"content-type":[...]} 形式的 JSON 字典的百分比编码表示。

NSDictionary *tvarns = @{@"order_cart": _order_cart};

NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:tvarns
                                                   options:0
                                                     error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSString *bodyString = [NSString stringWithFormat:@"order_cart=%@", [jsonString stringByAddingPercentEncodingQueryValue]];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://test.kre8tives.com/barebon/add_cartapi.php"]];
[request setHTTPMethod:@"OST"];
[request setHTTPBody:[bodyString dataUsingEncoding:NSUTF8StringEncoding]];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];

// Unless you need a new session for some reason, it's better to use the shared session

NSURLSession *session = [NSURLSession sharedSession];

[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    if (error) {
        NSLog(@"error: %@", error);
    }

    if (!data) {
        return;
    }

    NSError *parseError;
    NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError]; // you need to convert to dictionary object
    if (jsonDict) {
        NSLog(@"requestReply: %@", jsonDict);
    } else {
        NSLog(@"parseError: %@", parseError);
        NSLog(@"response: %@", response); // when you have failure, it's sometimes useful to see what this says
        NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; // this is json string
        NSLog(@"requestReply: %@", requestReply);
    }
}] resume];

地点:

@interface NSCharacterSet (URLQueryValue)

/**
 Character set of characters allowed within value (or a key) in a application/x-www-form-urlencode key/value pair.

 @return NSCharacterSet of allowed characters.
 */
+ (NSCharacterSet *) URLQueryValueAllowedCharacterSet;

@end

@implementation NSCharacterSet (URLQueryValue)

+ (NSCharacterSet *) URLQueryValueAllowedCharacterSet {
    static NSString * const generalDelimitersToEncode = @":#[]@"; // does not include "?" or "/" due to RFC 3986 - Section 3.4
    static NSString * const subDelimitersToEncode = @"!$&'()*+,;=";

    NSString * const characterToEncode = [generalDelimitersToEncode stringByAppendingString:subDelimitersToEncode];

    NSMutableCharacterSet *cs = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
    [cs removeCharactersInString:characterToEncode];
    return cs;
}

@end

@interface NSString (URLQueryValue)
/**
 String percent encoding for key or value in key/value pair within an application/x-www-form-urlencoded request.

 @return Percent encoded string.
 */
- (NSString *)stringByAddingPercentEncodingQueryValue;
@end

@implementation NSString (URLQueryValue)
- (NSString *)stringByAddingPercentEncodingQueryValue {
    return [self stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
}
@end

坦率地说,我建议更改 Web 服务以处理真正的 JSON 请求,而不是 x-www-form-urlencoded 请求中的 JSON。如果你这样做了,客户端代码看起来更像我上面的原始答案。但是对于您现有的 Web 服务代码,您需要创建类似于我的第二个代码示例的内容。

关于php - 将方法 nsdictionary 发布到 json 对象 iOS objective-c ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44800588/






欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) Powered by Discuz! X3.4