lf_araujo
lf_araujo

Reputation: 2063

Printing valid JSON with a Swift script

I am attempting to print out in the command line the contents of a variable that holds a JSON object, like in the code:

#! /usr/bin/swift
import Glibc
import Foundation

let albert_op = ProcessInfo.processInfo.environment["ALBERT_OP"]!


if albert_op == "METADATA" {
    let metadata = [
        ["iid": "org.albert.extension.external/v2.0",
        "name": "Tomboy",
        "version": "0.1",
        "author": "Will Timpson",
        "dependencies": ["tomboy", "python-pydbus"],
        "trigger": "tb "]
    ]
    print(metadata))
}


exit(0)

However, that prints out:

[["trigger": "tb ", "name": "Tomboy", "iid": "org.albert.extension.external/v2.0", "dependencies": ["tomboy", "python-pydbus"], "version": "0.1", "author": "Will Timpson"]]

Which is not valid, I was expecting something like:

{"version": "0.1", "author": "Will Timpson", "iid": "org.albert.extension.external/v2.0", "trigger": "tb ", "dependencies": ["tomboy", "python-pydbus"], "name": "Tomboy"}

Upvotes: 16

Views: 42993

Answers (6)

Krishna Kant Kaira
Krishna Kant Kaira

Reputation: 76

I would recommend using do {} catch { () } block, and before serialization do check if its a valid JSON object.

do {
  if let result = responseObj.result, JSONSerialization.isValidJSONObject(result) {
    let jsonData = try JSONSerialization.data(withJSONObject: result)
    // Convert to a string and print
    if let JSONString = String(data: jsonData, encoding: String.Encoding.utf8) {
      print(JSONString)
    }
  }
} catch {
  ()
}

Happy coding.

Upvotes: 2

SomuYadav
SomuYadav

Reputation: 123

/*
Take Note: 
1. To print JSON, incorporate this command in the debugger Action.
2. The term "event" simply refers to an Encodable type.
*/

**Swift Script(Debugger Action):** 

po let encoder = JSONEncoder(); encoder.outputFormatting = .prettyPrinted; let data = try! encoder.encode(event); print(String(data: data, encoding: String.Encoding.utf8)!)

// or if you are using encodable entity, this JsonEncoder object will print that json.

let entity = RequestEntity(...)
do {
     if let data = try? JSONEncoder().encode(entity) {
        if let JSONString = String(data: data, encoding: String.Encoding.utf8) {
           print(JSONString)
        }
      }
   } 

/// Without slash in jsonString:
extension Encodable {
    func encodeToJSONString() -> String? {
        do {
            let encoder = JSONEncoder()
            encoder.outputFormatting = .withoutEscapingSlashes
            let data = try encoder.encode(self)
            return String(data: data, encoding: .utf8)
        } catch {
            return nil
        }
    }
}

Upvotes: 2

Al Walid Ashik
Al Walid Ashik

Reputation: 1779

I guess, I solved this in a very easy way. It shows well formatted json from object in xcode logcat.

let jsonString = object.toJSONString(prettyPrint: true)
print(jsonString as AnyObject)

Upvotes: -2

Krivvenz
Krivvenz

Reputation: 4039

Swift 4:

If you want a quick dirty one liner just for example, checking the serialised JSON Data you are about to attach to a http request body then I use the following:

let json = NSString(data: myJsonObject, encoding: String.Encoding.utf8.rawValue)
print(json)

It prints as clear JSON, no added slashes or anything!

Upvotes: 14

Freek Sanders
Freek Sanders

Reputation: 1257

Swift 4.2 Extension
Looked up @smarx solution a lot of times to print my JSON string. Eventually ended up making an extension

extension Data
{
    func printJSON()
    {
        if let JSONString = String(data: self, encoding: String.Encoding.utf8)
        {
            print(JSONString)
        }
    }
}

Upvotes: 15

user94559
user94559

Reputation: 60153

Two issues:

  1. You don't have the structure you ultimately want. You have an array with one item in it, and that item is a dictionary. Based on your expected output, you seem to just want a dictionary. You can fix this by dropping the extra square brackets.
  2. JSON is a serialization format. You don't have "a JSON object." You have data that you would like to serialize as JSON. You can do that with JSONSerialization.

Here's working code that produces the expected output:

#! /usr/bin/swift

import Foundation

// Drop the extra brackets, and use a type annotation
let metadata: [String: Any] = [
    "iid": "org.albert.extension.external/v2.0",
    "name": "Tomboy",
    "version": "0.1",
    "author": "Will Timpson",
    "dependencies": ["tomboy", "python-pydbus"],
    "trigger": "tb"
]

// Serialize to JSON
let jsonData = try JSONSerialization.data(withJSONObject: metadata)

// Convert to a string and print
if let JSONString = String(data: jsonData, encoding: String.Encoding.utf8) {
   print(JSONString)
}

// Output:
// {"iid":"org.albert.extension.external\/v2.0","name":"Tomboy","version":"0.1","dependencies":["tomboy","python-pydbus"],"author":"Will Timpson","trigger":"tb"}

Upvotes: 23

Related Questions