error when convert JSON to Dictionary Swift - swift

can you help me,
I'm facing an issue if the JSON came with multilines like this
"{\"groupId\":\"58\",\"chat\":\"send 2lines\nsecondline\"}"
I'm taking the response from server and convert it with this function
let dataDic = self.convertToDictionary(text: (remoteMessage.appData["message"]! as AnyObject) as! String)
print(dataDic!)
and this is my function
func convertToDictionary(text: String) -> [String: AnyObject]? {
if let data = text.data(using: String.Encoding.utf8) {
do {
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:AnyObject]
return json
} catch {
print(error.localizedDescription)
}
}
return nil
}
but the problem came if the code have multilines because it's put \n in the return and
it gives me
The data couldn’t be read because it isn’t in the correct format
Error Domain=NSCocoaErrorDomain Code=3840 "Unescaped control character around character 145." UserInfo={NSDebugDescription=Unescaped control character around character 145.}

You should put an extra "\" before "\n", before parsing your JSON. Try using "replacingOccurencesOf" function.
That way your JSON is formatted before parsing.

Related

How to convert the email body to something readable?

Iam working on a simple Apple mailkit extension but cant get something readable out of my mails.
func allowMessageSendForSession(_ session: MEComposeSession, completion: #escaping (Error?) -> Void) {
let mailMessage = session.mailMessage;
let subject = mailMessage.subject
let sender = mailMessage.fromAddress.addressString ?? "undefined";
let data = String(data: mailMessage.rawData!, encoding: .utf8)
In data is the header and the mail body. But its filled with so many 'quoted-printable' strings.
Something like this Viele Gr=C3=BC=C3=\n=9Fe =F0=9F=A4=9D. It should be Viele Grüße 🤝.
I already tried the code in this answer https://stackoverflow.com/a/32827598/1407823 but it seems to only work with single words. I cannot get it to work with a whole text.
Is there no built in way to parse text like this?
There is no built-in way to decode the message, you need a RFC822 parser for example MimeParser on GitHub, available as Swift Package.
This is an example how to decode the body as plain text, messageData represents the raw data of the message
import MimeParser
do {
let messageString = String(data: messageData, encoding: .utf8)!
let parser = MimeParser()
let mime = try parser.parse(messageString)
switch mime.content {
case .body(let body): print(body.raw)
case .alternative(let mimes), .mixed(let mimes):
if let plainTextMime = mimes.first(where: {$0.header.contentType?.subtype == "plain"}),
let decodedBody = try plainTextMime.decodedContentString() {
print(decodedBody)
}
}
} catch {
print(error)
}
With subtype == "html" you get the HTML text, if available

How to convert String to JSON in Swift

I am receiving text from a web socket. And I want to convert the text to JSON.
Text received from the socket:
{'id': 920, 'location': {'lat': 11.0368754733495, 'lon': -47.203396772120247}}
Tried this:
func websocketDidReceiveMessage(socket: WebSocketClient, text: String) {
print("got some text: \(text)")
let data = Data(text.utf8)
do {
// make sure this JSON is in the format we expect
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
// try to read out a string array
if let id = json["id"] as? Int {
print(id)
}
}
} catch let error as NSError {
print("Failed to load: \(error.localizedDescription)")
}
But I am getting Failed to load: The data couldn’t be read because it isn’t in the correct format. error.
This is not valid JSON. The keys must be wrapped in double quotes.
You can replace the single quotes with double quotes on the fly
let data = Data(text.replacingOccurrences(of: "\'", with: "\"").utf8)
Side note:
Never print .localizedDescription in JSONSerialization/JSONDecoder catch blocks. And bridge casting to NSError is redundant
catch {
print("Failed to load:", error)
}

Decodable swift value without brackets [duplicate]

According to the JSON standard RFC 7159, this is valid json:
22
How do I decode this into an Int using swift4's decodable? This does not work
let twentyTwo = try? JSONDecoder().decode(Int.self, from: "22".data(using: .utf8)!)
It works with good ol' JSONSerialization and the .allowFragments
reading option. From the documentation:
allowFragments
Specifies that the parser should allow top-level objects that are not an instance of NSArray or NSDictionary.
Example:
let json = "22".data(using: .utf8)!
if let value = (try? JSONSerialization.jsonObject(with: json, options: .allowFragments)) as? Int {
print(value) // 22
}
However, JSONDecoder has no such option and does not accept top-level
objects which are not arrays or dictionaries. One can see in the
source code that the decode() method calls
JSONSerialization.jsonObject() without any option:
open func decode<T : Decodable>(_ type: T.Type, from data: Data) throws -> T {
let topLevel: Any
do {
topLevel = try JSONSerialization.jsonObject(with: data)
} catch {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: error))
}
// ...
return value
}
In iOS 13.1+ and macOS 10.15.1+ JSONDecoder can handle primitive types on root level.
See the latest comments (Oct 2019) in the linked article underneath Martin's answer.

Convert string to dictionary?

I have a QR code scanner which reads QR codes as a string. There are no options to detect it as a dictionary. So the only solution would be to convert it to a dictionary (i think). Keep in mind I am using swift and using AVFoundation, which is from apple.
This QR code would print out ["test": "test123"] as a string. How would I convert it to a dictionary?
Here's what I've came up with. Output is not dictionary though.
let test = "[\"test\": \"test123\"]"
let data = test.data(using: .utf8)!
do{
let output = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String:String]
print ("\(String(describing: output))")
}
catch {
print (error)
}

Convert String to NSDictionary by ignoring string literal

I'm getting dictionary value from server in form of String. Now when I try to use that String, it contains \ before ".
I get below value from my web service:
“\”{\\\”111\\\”:\\\”abc\\\”, \\\”222\\\”:\\\”xyz\\\”}\”
I'm trying to convert this string to NSDictionary. Can you please some one guide me for this. Which is the easiest way to convert this to NSDictionary. My current code is as below, but it's not working
var permValue = perm.value?.stringByReplacingOccurrencesOfString("\\", withString: "")
let data = permValue?.dataUsingEncoding(NSUTF8StringEncoding)
if let dict = try! NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary{
print("Permission Dictionary : \(dict)")
}
I'm getting an error while converting data to NSDictionary.
Please help. Any help will be appreciated