Home > Software design >  Format JSON string to iOS Dictionary string with =
Format JSON string to iOS Dictionary string with =

Time:09-21

First off, what do we call a dictionary with a format like this in iOS?

(
        {
        name = "Apple";
        value = "fruit-1";
    },
        {
        name = "Banana";
        value = "fruit-2";
    }
)

And for my main question. I somehow need to format a string of JSON, like this:

[{"name":"Apple","value":"fruit-1"},{"name":"Banana","value":"fruit-2"}]

into whatever that format is called (of the string above).

For context, the existing approach of my project uses CoreData where the Server response (which uses the mystery format above) gets saved locally as a String, and I want to follow that format.


EDIT: for more context, I really need to just get the first format into the database because a module of a project was built to read the data with that format (e.g. make use of NSString.propertyList()).

Using a library called ios hierarchy viewer, I can see the saved object in the device.

Original format, server json to db (core data) in Objective-C:

What I've been trying to do in Swift, server json to local using JSONSerialization:

CodePudding user response:

First off, what do we call a dictionary with a format like this in iOS?

According to the documentation of NSString.propertyList(), that's a "text representation of a property list".

It's a wonky, non-standard pretty-printing obtained by calling NSArray.description or NSDictionary.description.

Here's an example that shows a round-trip of data:

// The opening `{` indentation is fucky, but that's how it's generated.
let inputPropertyList = """
(
        {
        name = "Apple";
        value = "fruit-1";
    },
        {
        name = "Banana";
        value = "fruit-2";
    }
)
"""

// The result is an `Any` because we don't know if the root structure
// of the property list is an array or a dictionary
let deserialized: Any = inputPropertyList.propertyList()

// If you want the description in the same format, you need to cast to
// Foundation.NSArray or Foundation.NSDictionary.
// Swift.Array and Swift.Dictionary have a different description format.
let nsDict = deserialized as! NSArray

let roundTrippedPropertyList = nsDict.description
print(roundTrippedPropertyList)
assert(roundTrippedPropertyList == inputPropertyList)

CodePudding user response:

The second format you show is what you get when you display an object in the debug console. That's the output of the object's description property. It isn't a "JSON string", exactly.

If you want to convert your objets to a true JSON string, see below.

As Alexander pointed out, the first string in your question is the output from NSString's propertyList() function. The format looks quite similar to "pretty-printed" JSON, but it's different enough that it it won't work that way.

The `propertyList() function is a debugging-only function, and I don't know of an existing way to parse that back into objects. If that is the string that's being sent by your server, your server is broken. If that's what you see in core data when you log the contents of a field, it's probably a misunderstanding on your part.

To convert an object to pretty JSON, see this answer, where I created an extension to the Encodable format that implements a property "prettyJSON":

extension Encodable {
    var prettyJSON: String {
        let encoder = JSONEncoder()
        encoder.outputFormatting = .prettyPrinted
        guard let data = try? encoder.encode(self),
            let output = String(data: data, encoding: .utf8)
            else { return "Error converting \(self) to JSON string" }
        return output
    }
}

That should work for any object that supports the Encodable protocol. (And your object should.)

  • Related