I trying to generate JSON Object and convert that to JSON String and that process is Successfully placed. But my real problem rises when I try to convert JSON String to JSON Object. When I try I get nil as result.
func generateJSONObject() {
let jsonObject = createJSONObject(firstName: firstName[0], middleName: middleName[0], lastName: lastName[0], age: age[0], weight: weight[0])
print("jsonObject : \(jsonObject)")
let jsonString = jsonObject.description // convert It to JSON String
print("jsonString : \(jsonString)")
let jsonObjectFromString = convertToDictionary(text: jsonString)
print("jsonObjectFromString : \(String(describing: jsonObjectFromString))")
}
createJSONObject func
// JSON Object creation
func createJSONObject(firstName: String, middleName: String, lastName: String, age: Int, weight: Int) -> [String: Any] {
let jsonObject: [String: Any] = [
"user1": [
"first_name": firstName,
"middle_name": middleName,
"last_name": lastName,
"age": age,
"weight": weight
]
]
return jsonObject
}
convertToDictionary func
func convertToDictionary(text: String) -> [String: Any]? {
if let data = text.data(using: .utf8) {
do {
return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
} catch {
print(error.localizedDescription)
}
}
return nil
}
Logs
When I print JSON Object I get
jsonObject : ["user1": ["age": 21, "middle_name": "Lazar", "last_name": "V", "weight": 67, "first_name": "Alwin"]]
When I print JSON String I get
jsonString : ["user1": ["age": 21, "middle_name": "Lazar", "last_name": "V", "weight": 67, "first_name": "Alwin"]]
Convert JSON String to JSON Object I get below error
The data couldn’t be read because it isn’t in the correct format.
jsonObjectFromString : nil
I don't know why this happening. I want to convert JSON String to JSON Object and I want to parse the JSON.
based on discussion
import Foundation
let firstName = "Joe"
let lastName = "Doe"
let middleName = "Mc."
let age = 100
let weight = 45
let jsonObject: [String: [String:Any]] = [
"user1": [
"first_name": firstName,
"middle_name": middleName,
"last_name": lastName,
"age": age,
"weight": weight
]
]
if let data = try? JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted),
let str = String(data: data, encoding: .utf8) {
print(str)
}
prints
{
"user1" : {
"age" : 100,
"middle_name" : "Mc.",
"last_name" : "Doe",
"weight" : 45,
"first_name" : "Joe"
}
}
Json has to be in Array or Dictionary, it can't be only string so to create a jsonstring first you need to convert to Data format and then convert to String
func generateJSONObject() {
let jsonObject = createJSONObject(firstName: "firstName", middleName: "middleName", lastName: "lastName", age: 21, weight: 82)
print("jsonObject : \(jsonObject)")
if let jsonString = convertToJsonString(json: jsonObject), let jsonObjectFromString = convertToDictionary(text: jsonString) {
print("jsonObjectFromString : \(jsonObjectFromString)")
}
}
func convertToJsonString(json: [String: Any]) -> String? {
do {
let jsonData = try JSONSerialization.data(withJSONObject: json, options: .prettyPrinted)
return String(data: jsonData, encoding: .utf8)
} catch {
print(error.localizedDescription)
}
return nil
}
Related
I want to check city name From local JSON if found then massage show "You got it". But one problem came occurred that is I fetch data from file is successfully but I'd know how to compare it.
Here is my JSON file look like:
{
"data": [
{
"zip_code": 55001,
"latitude": 44.90717,
"longitude": -92.816193,
"city": "Afton",
"state": "MN",
"county": "Washington"
},
{
"zip_code": 55002,
"latitude": 45.513447,
"longitude": -92.894239,
"city": "Almelund",
"state": "MN",
"county": "Chisago"
}
]
}
Code is here:
func FatchingInformation(){
do {
if let file = Bundle.main.url(forResource: "Zone", withExtension: "json") {
let data = try Data(contentsOf: file)
let json = try JSONSerialization.jsonObject(with: data, options: [])
if let object = json as? [String: Any] {
// This condition work and Get JSON on Debug Area
print("Obj is ::: \(object)")
} else if let object = json as? [Any] {
// json is an array
print("Object is \(object)")
} else {
print("JSON is invalid")
}
} else {
print("no file")
}
} catch {
print(error.localizedDescription)
}
}
you are in right way on your JSON is dict of array of dictionary, you need to iterate your [String: Any] first there after check it contains array or dict then you need to follow as below
if let object = json as? [String: Any], let objectArray = object["data"] as? [[String: Any]] {
// do stuff
for getDictItems in objectArray{
if let getCityCompare = getDictItems["city"] as? String, !getCityCompare.isEmpty, getCityCompare == "Almelund"{
print("city name is \(getCityCompare)")
break
}
}
}
You ca use decodable Struct to decode json
// MARK: - Address
struct Address: Codable {
let data: [Datum]
}
// MARK: - Datum
struct Datum: Codable {
let zipCode: Int
let latitude, longitude: Double
let city, state, county: String
enum CodingKeys: String, CodingKey {
case zipCode = "zip_code"
case latitude, longitude, city, state, county
}
}
let address = try? JSONDecoder().decode(Address.self, from: jsonData)
I'm trying to convert an object to NSDictionary with an extension. It works fine but if the object contains an array, then the array does not convert to NSDictionary but to Json and that is not what I want. Because I try with this Dictionary to make a request post and the body accepts [String: Any].
My code:
struct Country: Codable {
let name: String
let cities: [City]
struct City: Codable {
let name: String
}
}
extension NSDictionary {
func encode<T>(_ value: T) throws -> [String: Any]? where T: Encodable {
guard let jsonData = try? JSONEncoder().encode(value) else { return nil }
return try? JSONSerialization.jsonObject(with: jsonData, options: .allowFragments) as? [String: Any]
}
}
Using:
let country = Country(name: "France", cities: [Country.City(name: "Paris"), Country.City(name: "Marseille")])
print(try! NSDictionary().encode(country))
Output:
["name": France, "cities": <__NSArrayI 0x600002926e60>(
{
name: "Paris",
},
{
name: "Marseille",
})
]
Expected output (what I want):
["name": France, "cities": [
[
"name": Paris,
],
[
"name": Marseille,
]
]
]
The output is correct since your result is NSDictionary and the output is the string representation (aka description) of NSDictionary. <__NSArrayI 0x600002926e60> is syntactic sugar.
By the way the expected output is invalid because the city names must be in double quotes.
The extension of NSDictionary makes no sense anyway. If you want to be able to call the method from everywhere declare a struct with a static method.
This is a swiftier version of your code. No allowFragments and all errors are thrown rather than being ignored.
struct DictionaryEncoder {
static func encode<T>(_ value: T) throws -> [String: Any] where T: Encodable {
let jsonData = try JSONEncoder().encode(value)
return try JSONSerialization.jsonObject(with: jsonData) as? [String: Any] ?? [:]
}
}
Copy the method and your structs into a Playground and run
let country = Country(name: "France", cities: [Country.City(name: "Paris"), Country.City(name: "Marseille")])
try! DictionaryEncoder.encode(country)
Don't print the result, look at the result area in the Playground, the output is exactly what you want.
You need
let res = try! JSONEncoder().encode(country)
print(res.prettyPrintedJSONString!)
extension Data {
var prettyPrintedJSONString: NSString? { /// NSString gives us a nice sanitized debugDescription
guard let object = try? JSONSerialization.jsonObject(with: self, options: []),
let data = try? JSONSerialization.data(withJSONObject: object, options: [.prettyPrinted]),
let prettyPrintedString = NSString(data: data, encoding: String.Encoding.utf8.rawValue) else { return nil }
return prettyPrintedString
}
}
Result
{
"name" : "France",
"cities" : [
{
"name" : "Paris"
},
{
"name" : "Marseille"
}
]
}
Here the Dictionary
struct Person : Codable {
let name : String?
let city : String?
let age : Int?
}
let dic : [String : Any] =
["name":"Manna","city" : "Rangpur", "age": 18,
"name":"Munna","city" :"Dhaka","age":19,
"name":"Shaon","city" :"Rangpur","age":11,
"name":"Limon","city" :"Tangail","age":15,
"name":"Lalon","city" :"Rangpur","age":18,
"name":"Rakib","city" :"Dhaka","age":15,
"name":"Mum","city" :"Rangpur","age":18,
"name":"Man","city" :"Bogura","age":12,
"name":"Limon","city" :"Tangail","age":18]
// let manna = Person(name: "Manna", city: "Rangpur", age: 18)
// Here i want to use the dictionary
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
do {
let data = try encoder.encode(manna)
print(String(data: data, encoding: .utf8)!)
} catch {
print("error : \(error.localizedDescription)")
}
trying to encode this dictionary just like json file as an output using JSONEncoder
First of all your dictionary is wrong because dictionary doesn't contains same key.
You can present it as like array of dictionary
let dic : [[String : Any]] = [["name":"Manna", "city" : "Rangpur", "age": 18],
["name":"Munna","city" :"Dhaka","age":19,],
["name":"Shaon","city" :"Rangpur","age":11,],
["name":"Limon","city" :"Tangail","age":15,],
["name":"Lalon","city" :"Rangpur","age":18,],
["name":"Rakib","city" :"Dhaka","age":15,],
["name":"Mum","city" :"Rangpur","age":18,],
["name":"Man","city" :"Bogura","age":12,],
["name":"Limon","city" :"Tangail","age":18]]
Now you can convert this array of dictionary into JSON as like below
if let data = try? JSONSerialization.data(withJSONObject: dic, options: JSONSerialization.WritingOptions.prettyPrinted) {
print(data.count)
let json = String(data: data, encoding: String.Encoding.utf8)
print(json ?? "")
}
let dictionaryToJsonObject: [String: Any]
let Dictionary: [String: Any] = ["FirstName": "John", "Email": "Jo#sm.com", "Password": "john#123", "LastName": "Smith", "Organization": ["Type": 5, "Name": "IT"]]
do {
let jsonData = try JSONSerialization.data(withJSONObject: Dictionary as Any, options: .prettyPrinted)
let jsonText = String(data: jsonData,
encoding: .ascii)
print("JSON string = \(jsonText!)")
if JSONSerialization.isValidJSONObject(jsonText!) {
print("Valid")
} else {
print("Not Valid")
}
}catch {
print(error.localizedDescription)
}
Output Will be : -
JSON string = {
"FirstName" : "John",
"Email" : "Jo#sm.com",
"Password" : "john#123",
"LastName" : "Smith",
"Organization" : {
"Type" : 5,
"Name" : "IT"
}
}
expected Result :
{
FirstName:"John",
Email:"Jo#sm.com",
Password:"john#123",
LastName:"Smith",
Organization:{
Type:5,
Name:"IT"
}
}
If you want to get it in json object form then your code should be like,
let dictionaryToJsonObject: [String: Any]
let Dictionary: [String: Any] = ["FirstName": "John", "Email": "Jo#sm.com", "Password": "john#123", "LastName": "Smith", "Organization": ["Type": 5, "Name": "IT"]]
do {
let jsonData = try JSONSerialization.data(withJSONObject: Dictionary as Any, options: .prettyPrinted)
let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: .init(rawValue: 0))
print("JSON string = \(jsonObject)")
if JSONSerialization.isValidJSONObject(jsonObject) {
print("Valid")
} else {
print("Not Valid")
}
}catch {
print(error.localizedDescription)
}
and your output will be,
JSON string = {
Email = "Jo#sm.com";
FirstName = John;
LastName = Smith;
Organization = {
Name = IT;
Type = 5;
};
Password = "john#123";
}
Valid
Ultimately it is your declared dictionary itself I think!
I have a string that defines an object like so:
let object = """
{
"id": 59d75ec3eee6c20013157aca",
"upVotes": NumberLong(0),
"downVotes": NumberLong(0),
"totalVotes": NumberLong(0),
"timestamp" : "\(minutesAgo(1))",
"caption": "hello",
"username": "hi",
"commentsCount": NumberLong(0),
"lastVotingMilestone": NumberLong(0),
"type": "Text"
}
"""
I need to convert it into the format [String : Any] but I'm not sure how to do this. In the past I have put the string into a json file and loaded that like this:
let data = NSData(contentsOfFile: file)
let json = try! JSONSerialization.jsonObject(with: data! as Data, options: [])
let dict = json as! [String: Any]
Anyone know how I can do this? Thanks!
Why are you doing it the complicated way in the first place? You want a dictionary, so define a dictionary.
let dict: [String: Any] = [
"id": "59d75ec3eee6c20013157aca",
"upVotes": 0,
"downVotes": 0,
...
]
Anyway, the NumberLong(0) isn't valid JSON, so that isn't going to work anyway.
In Swift 4, you can use JSONDecoder API to decode JSON data, i.e.
let object = """
{
"id": 59d75ec3eee6c20013157aca",
"upVotes": NumberLong(0),
"downVotes": NumberLong(0),
"totalVotes": NumberLong(0),
"timestamp" : "Some Value",
"caption": "hello",
"username": "hi",
"commentsCount": NumberLong(0),
"lastVotingMilestone": NumberLong(0),
"type": "Text"
}
"""
if let data = object.data(using: .utf8)
{
if let dict = try? JSONDecoder().decode([String: Any].self, from: data)
{
}
}