0

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:

Alexander
  • 59,041
  • 12
  • 98
  • 151
Glenn Posadas
  • 12,555
  • 6
  • 54
  • 95
  • I guess you printed a `NSDictionary`. To transform it into JSON, you can use `(NS)JSONSerialization`. See https://stackoverflow.com/questions/29625133/convert-dictionary-to-json-in-swift/29628000 – Larme Sep 20 '21 at 16:47
  • If it's a `String` with that format then it's just a `String` that hasn't been parsed into an object. If you want to create a string with that format based on your objects, you could use `Codable`. – EmilioPelaez Sep 20 '21 at 16:58
  • Thanks both! Please see my edit. – Glenn Posadas Sep 20 '21 at 17:30
  • "First off, what do we call a dictionary with a format like this in iOS?" It's nothing particular, just a human readable print out. It's not a standardized serialization format, so don't try to use it as such. – Alexander Sep 20 '21 at 17:39
  • Thanks @Alexander. So if there's no way to go back to that weird format, then that only means I've gotta try other ways. But iOS can go from that format to standardized json format, why can't we format it back? :/ – Glenn Posadas Sep 20 '21 at 17:44
  • @GlennPosadas What exactly do you mean by " iOS can go from that format to standardized json format"? The string blob you showed isn't what iOS has stored. It's a presentation generated from the underlying representation of the data in memory. JSON is another presentation generated from the same underlying representation. – Alexander Sep 20 '21 at 17:49
  • @Alexander Take the first format in my question. That's literally the string sent from a server to the iOS, and directly stored to local through coredata. And then, you have the string now, right? See the first screenshot. You could easily generate a dictionary out of that string with that weird format using String's `propertyList()`. What I mean is that it seems there is no way to bring a dictionary that is generated by `propertyList()` back to its weird format with lots of "=" instead of ":". – Glenn Posadas Sep 20 '21 at 18:06
  • 1
    "That's literally the string sent from a server" That's the first problem. Your server is using a debug description of a dictionary as a serialization format for communicating data to its clients. This isn't a standardized data serialization format. Don't use it for that. "You could easily generate a dictionary out of that string with that weird format using String's propertyList()" Can you? What is this `propertyList()` method? Can you link me to the docs – Alexander Sep 20 '21 at 18:10
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/237295/discussion-between-alexander-and-glenn-posadas). – Alexander Sep 20 '21 at 18:10

2 Answers2

2

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)
Alexander
  • 59,041
  • 12
  • 98
  • 151
  • Wait, wait wait. Are you saying that I was always using `PropertyListSerialization` when I could have user `propertyList()` directly? Also, I know that they are supposed to be the same (for the `assert`) but a equality assert might fail here... with all the spaces, order, etc. – Larme Sep 20 '21 at 18:54
  • @Larme it does fail. Not sure why but Apple and Banana are printed without quotes – Leo Dabus Sep 20 '21 at 19:03
  • 2
    I would expect them to be printed without quotes. There is a related question on SO (maybe I'll find it again) about when they are quotes or no in the `OpenStep` print (because after all, that's its name), It was something like if the text was only [a-zA-Z], not quotes, if there was spaces, etc double quotes, and for numbers, I don't remember... – Larme Sep 20 '21 at 19:06
  • @LeoDabus https://stackoverflow.com/questions/36447246/nsstring-logged-to-console-with-quotation-marks-sometimes https://stackoverflow.com/questions/10520486/why-does-string-show-up-in-nsdictionary-with-quotes-but-others-dont Also https://github.com/gnustep/libs-base/blob/master/Source/NSDictionary.m#L1208 & https://github.com/gnustep/libs-base/blob/master/Source/NSPropertyList.m but that's some digging that might not be much necessary (since related question are often about reverse back a `description` which isn't recommended). – Larme Sep 20 '21 at 19:12
  • 1
    And after going on the chat of the question https://chat.stackoverflow.com/rooms/237295/discussion-between-alexander-and-glenn-posadas that's what's happening... => I'd recommend to use JSON (or XML, etc., but JSON being quite "popular")... – Larme Sep 20 '21 at 19:19
1

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.)

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • I appreciate this. This is what I've been using but I still get the usual json string format. Please see my edited question. – Glenn Posadas Sep 20 '21 at 17:31
  • 1
    "The first format you show is JSON in "pretty print" format (with lots of newlines and indentation to make it easier to read.)" No it's not. Notice it's using `( )` for arrays instead of `[ ]`, `=` instead of `:`, `;` instead of `,` (with a trailing one, as well), and the keys are unquoted. It's definitely not JSON. It's a "a text representation of a property list", as phrased by [`NSString.propertyList()`](https://developer.apple.com/documentation/foundation/nsstring/1413115-propertylist) – Alexander Sep 20 '21 at 18:19
  • Oh, you're right. Ugh. – Duncan C Sep 20 '21 at 18:34