Printing out MongoDB Documents in JSON Format - json

I am retrieving documents from my mongoDB database, but I need to print it out in JSON format. I store all of the relevant information in an array as the MongoKitten documentation suggests. I want to print out the entire contents of each element in the array, which is remember a document from MongoDB. My code is as follows:
import Foundation
import MongoKitten
let myDatabase = try MongoKitten.Database("mongodb://taylor:starwars1#ds129374.mlab.com:29374/taylorswiftengine")
let myCollection = myDatabase["my_collection"]
Request.addHandler(forMethod: "GET", withRoute: "/:resource/:id1")
{
(routeParams:RouteParams) in
let myTopics = try! myCollection.find("topic" == "\(routeParams["id1"]!)")
let allTopics = Array(myTopics)
}

MongoKitten comes with an Extended JSON module, which you can import:
import ExtendedJSON
You can convert an array of documents ([Document]) to Extended JSON using makeExtendedJSON():
myArrayOfDocuments.makeExtendedJSON()
This returns a Cheetah.Value. Cheetah is OpenKittens JSON library. To get a JSON String, you can use the serializedString() method on Cheetah.Value.
To sum things up, use this to convert your array of BSON Documents to a JSON String:
myArrayOfDocuments.makeExtendedJSON().serializedString()

If your myTopics object a dictionary you could convert it to json like this:
let dict = ["key1": "B", "key2": "A", "key3": "C"]
let jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
Otherwise you could manually convert the myTopics object to a [String:String] dictionary and than convert it to json like above but I'm not sure if thats the way to handle with mongodb objects.

Related

How can I convert a JSON as Data Type in Swift?

I want to send data to my websocket server in swift but the websocket server write function only accepts strings or the data type. Since I did not find any JSON.stringify option for swift I used swiftyJson to create my own type of JSON, but now I need to convert it to data in order to be able to send it to the server.
var json: JSON = ["name": "Jack", "age": 25]
socket?.send(data: json <-- This needs to be Data)
I tried wrapping the JSON in Data(json) but this did not work either. Any ideas I have swiftyJson installed if there is a solution for this
The simplest way is a literal
let json = #"{"name": "Jack", "age": 25}"#
let data = Data(json.utf8)
With SwiftyJSON it's pretty simple, too, but less efficient.
let json: JSON = ["name": "Jack", "age": 25]
let data = try! json.rawData()
let data = Data(json.utf8)
By the way, I would not suggest using external libraries for such simple tasks as you become dependent on third-party's works, on which you have no control over.
Stick with the foundation model instead.

Elm: decode local JSON file into dict

I'm working on my first Elm app.
I want to use a local JSON file as a lookup table. The file matches weather conditions (a string) to suggested clothing (a list).
EDIT (clarifying the question): Based on some earlier SO questions from 2015 I've tried using Http.get to get the contents and then Decode.dict to create the Dict. It seems strange to use an Http module to ingest a local file. Is this methodology, including the Http.send I use below correct in Elm?
I am also having a hard time finding an example of a decoder that would work for a JSON file like the one I have. Any pointers would be appreciated.
JSON
{
"male,10,overcast,light wind...": ["Winter Cap", "Light Jacket"...],
"female,30,partly cloudy...": ["Winter Cap", "Sunglasses", ...]
}
CODE
type alias ClothingDict =
Dict String List
clothingUrl: String
clothingUrl =
"./clothing.json"
getClothingDict : Cmd Msg
getClothingDict =
let
url = clothingUrl
in
Http.send SetClothing (Http.get url decodeClothingResponse)
type alias ClothingResponse =
{ clothingOptions: ClothingDict }
decodeClothingResponse : Decoder ClothingResponse
decodeClothingResponse =
Decode.dict ClothingResponse
Decode.dict or dict takes a Decoder in order to handle decoding the keys of the Dict. dict automatically extracts the keys as strings.
I converted the code to:
decodeClothingResponse : Decoder (Dict String (List String))
decodeClothingResponse =
dict (list string)
(list string) is a decoder that will decoder a list of string from json in to a List String

Find values from JSON with unknown structure SWIFT

I read some questions about parsing JSON with unknown strucutre. But these questions are not in Swift and don't solve my issue.
I have a big JSON file that I obtain with a Alamofire HTTP request. Here is it: https://pastebin.com/Y7cWSWAt
In fact, the JSON could change with requests I do. It will not always be the same structure depending of the user (for example). However, there will be the same keys and values.
So I know the keys in the JSON to find the values, their will be always the same. But I don't know how to access them. Moreover, my JSON has an Any type (I can't give him a specific type because I don't know it).
My question: Is there a solution to find values with this? Can I loop throw all the JSON values to find specific keys and values? Is it better to work with JSON file or Dictionaries? I have no code yet because I have no idea. Thanks mates!
if you want to use just NSDictionary this not problem but when return array json your app will be crash because variable type not be equals.
let json = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments)
if json != nil {
let obj = json as? NSDictionary
}
//this part write all key and value
for (key, value) in obj {
print("Property: \"\(key as String)\", Value: \"\(value as String)\"")
}
input: {"test1":"value1","test2":"value2"}
output:
Property: "test1", Value: "value1"
Property: "test2", Value: "value2"

Save JSON Response as Variable to Deserialise with SwiftyJSON

I'm going to use either SwiftyJSON or EasyFastMapping to deserialise JSON data into variables and constants but I'm not sure on how to save the whole JSON file into its own object, if it is even possible.
I will be using Alamofire to handle the GET request and pull the JSON data down, is it possible to do it like this?
How I want it to work:
1. Alamofire pulls down the JSON data
Alamofire puts the data into an object
SwiftyJSON accesses the downloaded data and allows me to put individual parts of the data into separate variables and constants.
You could take a look at the documentation for SwiftyJSON and Alamofire and you will find plenty of examples.
From Alamofire Readme:
Alamofire.request("https://httpbin.org/get").responseJSON { response in
debugPrint(response)
if let json = response.result.value {
print("JSON: \(json)")
}}
From SwiftJSON Readme:
let json = JSON(data: dataFromNetworking)
if let userName = json[0]["user"]["name"].string {
//Your implementation here
}
You can also create a separate response object and deserialize all the response JSON into the object. Also take a look at the built-in JSONSerialization API in the Foundation framework.

Swift 3 parsing values from a json file

Swift 3 , Xcode8.2.1,
I'm trying to extract specific values from a json file in the project. The name of the file is city.list.json, and the syntax of the json file is as follows:
{"_id":707860,"name":"Hurzuf","country":"UA","coord":{"lon":34.283333,"lat":44.549999}}
{"_id":519188,"name":"Novinki","country":"RU","coord":{"lon":37.666668,"lat":55.683334}}
The input I have is the country name and i need the id value or the country code relevant returned as a string.
I get an error:
"Type 'Any?' has no subscript members",
The method I wrote:
private func findCountryCodeBy(location: String)->String{
var result:String="";
let bundle = Bundle(for: type(of: self));
if let theURL = bundle.url(forResource: "city.list", withExtension: "json") {
do {
let data = try Data(contentsOf: theURL);
if let parsedData = try? JSONSerialization.jsonObject(with: data, options:[]) as! [String:Any] {
result = parsedData["_id"][location][0] as! String;
}
} catch {
print(error);
result = "error";
}
}
return result;
}
That is not valid JSON. I think the nearest valid JSON equivalent would be EITHER a JSON list like:
[
{"_id":707860,"name":"Hurzuf","country":"UA","coord":{"lon":34.283333,"lat":44.549999}},
{"_id":519188,"name":"Novinki","country":"RU","coord":{"lon":37.666668,"lat":55.683334}}
]
Ie, a list enclosed within square brackets with each item separated by a comma.
OR a JSON dictionary:
{
"707860": {"name":"Hurzuf","country":"UA","coord":{"lon":34.283333,"lat":44.549999}},
"519188": {"name":"Novinki","country":"RU","coord":{"lon":37.666668,"lat":55.683334}}
}
Ie, a dictionary enclosed within curly brackets with the key (in this case I've used your _id as the key) before the : and the value (a dictionary of all the other items" after the :.
(Newlines, tabs, whitespace are ignored, I've just included them to make it obvious what I've done).
I think that the dictionary version may suit your code better, but it depends on what else you want to do with the data. A list may suit some situations better.
I wrote a quick Python script to simply read JSON from a file (and not do anything else with it), and it produced a parsing error for the not-quite-JSON that you had, but it worked fine on both of my JSON examples, above.
NB: If you do NOT have control over the format of the file you are reading (ie, if you are receiving it from some other source which cannot produce it in any other format) then you will have to either modify the format of the file after you receiv it to make it valid JSON, OR you will have to use something other than JSONSerialization to read it. You could modify it by replacing all occurrences of }{ or }\n{ with },{ and then put [ at the beginning and ] at the end. That should do the job for converting this particular file to valid JSON for a list. Converting to a dictionary would be a little more involved.
Ideally though, you may have control over the file format yourself, in which case, just change whatever generates the file to produce correct JSON in the first place.
Once you have your valid JSON and parsed it into your parsedData variable, you'll then need to fix this line:
result = parsedData["_id"][location][0] as! String;
Assuming that location is the the equivalent of the _id string in the JSON, then you may be able to use the dictionary version of the JSON above and replace that line with something like:
result = parsedData[location]["country"];
However, if location is not the _id string in the JSON, then you'd be better off using the list version of the JSON above, and use a for loop to compare the values of each list item (or use a dictionary version of the JSON keyed on whatever location actually relates to in the JSON).