13

Error Domain=NSCocoaErrorDomain Code=3840 "Unescaped control character
around character 981." UserInfo={NSDebugDescription=Unescaped control
character around character 981.}

I am getting the above error in response to a request.

Below are the lines of code:

Alamofire.request(.POST, urlStr, parameters: parameter, encoding: .JSON, headers: nil).validate().responseJSON {
    response in switch response.result {

        case .Success(let JSON):
            completionHandler(JSON as! NSDictionary)

        case.Failure(let Error):

            print(Error)
    }
}

It gives a JSON response in Postman.

The response which is I am getting in Postman:

{
  "orderdetails": {
    "status_code": "200",
    "status_message": "Order details",
    "billingandshipping": {
      "billing": {
        "firstname": "first",
        "lastname": "last",
        "email": "aa@bbb.com",
        "address": "dasdesfrew",
        "city": "Rajkot",
        "area": "University Road",
        "pincode": "360003",
        "phone": "1234567890",
        "mobileno": "1234567891"
      },
      "shipping": {
        "firstname": "first",
        "lastname": "last",
        "email": "aa@bbb.com",
        "address": "dasdesfrew",
        "city": "dasdesfrew",
        "area": "dcdc",
        "pincode": "360003",
        "phone": "1234567890",
        "mobileno": "1234567891"
      }
    },
    "orders": [
      {
        "order_id": "77",
        "order_date": "09-08-2016 13:05:29",
        "delivery_date": "10-08-2016",
        "order_items": [
          {
            "Sr": "1",
            "product_name": "Lemon",
            "gujtitle": "લીંબુ ",
            "product_code": "000057",
            "product_price": "108.00",
            "product_qty": "2",
            "unit": "1 kg.",
            "product_total": "216"
          }
        ],
        "final_total": "216.00",
        "shipping_cost": "0.00",
        "order_total": "216.00",
        "discount_type": "null",
        "discount_amount": "null",
        "coupon_name": "null",
        "comment": "gdhdj\nfghd.g\nghj\n\n\n\n\n\n\n\n\n\n.."
      }
    ]
  }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Payal Maniyar
  • 4,293
  • 3
  • 25
  • 51

5 Answers5

20

As per you were told, there is a problem related to "\n".

So I suggest you can add "" which will work for you, like below:

"\n"=> "\\n"

Because this is a special character called a backspace character.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ashish Gondaliya
  • 318
  • 1
  • 3
  • 7
  • 2
    What would the recommended way be for fixing this issue with JSON responses coming from a server, especially one that you might not control? Such as through an API. I'm having a similar issue and in some workings I've done this fixed my issue, but I'm not sure that I'd be able to replace these all in the response if it's still encoded. – KSigWyatt Jan 07 '18 at 05:10
  • I faced same issue for other characters '\r' and I replaced it with '\\r' – Afzaal Ahmad Jan 09 '20 at 21:49
  • @KSigWyatt (and anyone else wondering) the control characters should be escaped automatically where needed if using `URLSession` (or a wrapper such as `Alamofire`). You can see this if you print `String(data: data, encoding: .utf8)` in the completion handler. If you're mocking data, you'll need to escape characters yourself – froggomad May 22 '21 at 19:13
4

Since Swift 5, instead of manually adding another \ to your otherwise valid \n in a JSON string, you could simply declare it as a raw string literal, using this syntax:

let jsonString = #"{"comment": "gdhdj\nfghd.g\nghj\n\n\n\n\n\n\n\n\n\n.."}"#

Multiline works too:

let jsonString = #"""
{
  "comment": "gdhdj\nfghd.g\nghj\n\n\n\n\n\n\n\n\n\n.."
}
"""#

While the above would compile fine if using just """ (without the #), in runtime it would throw an error in the example below with JSONSerialization, which is fixed by #""":

do {
    guard let data = jsonString.data(using: .utf8) else { throw SomeError() }
    let obj = try JSONSerialization.jsonObject(with: data)
    print("valid!")
} catch {
    print(error)
}
Gobe
  • 2,559
  • 1
  • 25
  • 24
2

NSLog the NSData that you received and have a look what you find around byte 981. The thing with unescaped control characters is that they are invisible, so you can't see them in an NSString, but you'll see them in the NSData.

If your data has length 981 bytes or very close then there's a chance that your code processed incomplete JSON data which will almost always fail; that's something you need to fix. If there is a control character between some items (say between two array elements) then this might be a bug in the server code.

gnasher729
  • 51,477
  • 5
  • 75
  • 98
1

I spent some time to figure out what 49546 was. If your issue is Unescaped control character around character 49546, replace \t with \\\t.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ashiq Sulaiman
  • 631
  • 1
  • 6
  • 14
1

To be sure (as people make foul copy/paste...), I build my object safe:

...

private final func fillWith(
     id: Int,
     name: String?
) {

    self.id = id
    self.productName = name?.replacingOccurrences(of: "\t", with: "")
    self.productName = self.productName?.replacingOccurrences(of: "\n", with: "")

So no problem when sending up.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ingconti
  • 10,876
  • 3
  • 61
  • 48