I try to convert JSON string to a JSON object but after JSONSerialization the output is nil in JSON.
Response String:
[{\"form_id\":3465,\"canonical_name\":\"df_SAWERQ\",\"form_name\":\"Activity 4 with Images\",\"form_desc\":null}]
I try to convert this string with my code below:
let jsonString = response.result.value
let data: Data? = jsonString?.data(using: .utf8)
let json = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String:AnyObject]
print(json ?? "Empty Data")
The problem is that you thought your jsonString is a dictionary. It's not.
It's an array of dictionaries.
In raw json strings, arrays begin with [ and dictionaries begin with {.
I used your json string with below code :
let string = "[{\"form_id\":3465,\"canonical_name\":\"df_SAWERQ\",\"form_name\":\"Activity 4 with Images\",\"form_desc\":null}]"
let data = string.data(using: .utf8)!
do {
if let jsonArray = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? [Dictionary<String,Any>]
{
print(jsonArray) // use the json here
} else {
print("bad json")
}
} catch let error as NSError {
print(error)
}
and I am getting the output :
[["form_desc": <null>, "form_name": Activity 4 with Images, "canonical_name": df_SAWERQ, "form_id": 3465]]
Using JSONSerialization always felt unSwifty and unwieldy, but it is even more so with the arrival of Codable in Swift 4. If you wield a [String:Any] in front of a simple struct it will ... hurt. Check out this in a Playground:
import Cocoa
let data = "[{\"form_id\":3465,\"canonical_name\":\"df_SAWERQ\",\"form_name\":\"Activity 4 with Images\",\"form_desc\":null}]".data(using: .utf8)!
struct Form: Codable {
let id: Int
let name: String
let description: String?
private enum CodingKeys: String, CodingKey {
case id = "form_id"
case name = "form_name"
case description = "form_desc"
}
}
do {
let f = try JSONDecoder().decode([Form].self, from: data)
print(f)
print(f[0])
} catch {
print(error)
}
With minimal effort handling this will feel a whole lot more comfortable. And you are given a lot more information if your JSON does not parse properly.
I tried the solutions here, and as? [String:AnyObject] worked for me:
do{
if let json = stringToParse.data(using: String.Encoding.utf8){
if let jsonData = try JSONSerialization.jsonObject(with: json, options: .allowFragments) as? [String:AnyObject]{
let id = jsonData["id"] as! String
...
}
}
}catch {
print(error.localizedDescription)
}
I used below code and it's working fine for me. :
let jsonText = "{\"userName\":\"Bhavsang\"}"
var dictonary:NSDictionary?
if let data = jsonText.dataUsingEncoding(NSUTF8StringEncoding) {
do {
dictonary = try NSJSONSerialization.JSONObjectWithData(data, options: [.allowFragments]) as? [String:AnyObject]
if let myDictionary = dictonary
{
print(" User name is: \(myDictionary["userName"]!)")
}
} catch let error as NSError {
print(error)
}
}
static func getJSONStringFromObject(object: Any?) -> String? {
do {
let jsonData = try JSONSerialization.data(withJSONObject: object ?? DUMMY_STRING, options: [])
return String(data: jsonData, encoding: .utf8) ?? DUMMY_STRING
} catch {
print(error.localizedDescription)
}
return DUMMY_STRING
}
Related
I use alamofire for requests. Here on a simple response, I'm getting this JSON string from alamofire
Optional("[{\"nl2br\":\"2019-05-02 19:52:10\",\"nl3br\":\"\",\"nl4br\":\"#lxr\",\"nl5br\":\"1\",\"nl6br\":\"nein\",\"nl7br\":\"bARxrdw9c7WS1RN9c\\/\\/MrA==822b5dd20cb73611:35cab43d0c7e82e73c62818d9f90cfe8\",\"nl8br\":\"tBDSzkQ7eCNERwldgZiwKg==a7590d9d8affdbe5:63b9a9bf6421ea7db2a55f8773990b08\",\"nl9br\":\"fpd17pxVUzcJWNskVWyBeA==cf21783de8334248:a93e8b8a92ef9b238b75ad87a315ce3e\"},{\"nl2br\":\"2019-04-26 21:36:32\",\"nl3br\":\"old\",\"nl4br\":\"\",\"nl5br\":null,\"nl6br\":\"ja\",\"nl7br\":\"emjUIzK92fWwHNLv\\/4xv2Q==8fca202c9a816c7b:655ef8aaaa0212bb9e77a9c35a56c3a7\",\"nl8br\":\"1C5Hy\\/ZhMk3b6SZY8c08lw==cb3b0f4fdd6b5957:034e72d400598fedc43b3111d841a31b\",\"nl9br\":\"KUfLHbih9612dhNCYPOrTg==48da9c3362430e01:3a80ba9fb516e4172aa39b017abcd96e\"},{\"nl2br\":\"2019-04-26 21:20:24\",\"nl3br\":\"holder\",\"nl4br\":\"\",\"nl5br\":null,\"nl6br\":\"ja\",\"nl7br\":\"J59nMBWUMyU9PzdbwQqd0g==f7d3c6c561c33f0b:3465e9131a2577c39cddcc606d0785b0\",\"nl8br\":\"G4rRevk951ZBJJQKzBeJZg==45c0ebcdc1e000e8:dc770c3849fef8b058f85cad42c73e1d\",\"nl9br\":\"338Ud9CIDgnyBV96F2Fx\\/w==d0f825064e0ecf81:0ca00ff27e977ef5f8123d38c643a8b3\"},{\"nl2br\":\"2019-04-10 23:57:17\",\"nl3br\":\"\",\"nl4br\":\"Wasmes, here\'s a video and do ya need?\",\"nl5br\":\"1\",\"nl6br\":\"ja\",\"nl7br\":\"fw17O1L9SuO9FS3qu6U7QQ==706bd09ee3b5ec55:6667d9020a0edcacbd217f631d2305c0\",\"nl8br\":\"2tTE9+0Kr6cVSuEOsq8h0w==3e0e46352da323be:941710bd881546dfa08d3afb6aea2831\",\"nl9br\":\"NAkMx0OsKwXVGndYXbAFmA==1234c0b2992502bf:666f8efd3bdf8ee8b0a2ee4e7222c2ef\"},{\"nl2br\":\"2019-02-22 21:38:16\",\"nl3br\":\"i\'m giving up on you, but don\'t \",\"nl4br\":\"\",\"nl5br\":null,\"nl6br\":\"nein\",\"nl7br\":\"gOv13Dsxf1N2UG46KT3tvQ==dd02a83b1837bb24:4f7c7ab95e873d35685ab7b738626f44\",\"nl8br\":\"40+GOpcNU6M4F688DJyxFA==70bc177842f3f6cf:232b065423bd2683d75ca177775fd352\",\"nl9br\":\"mBc3pEHKBiiPeAEpZRskug==71b353fed6403b99:c58099676beacc146c14867645e29783\"}]")
I get my data like this and convert it like this
if let responseData = response.data {
let responseDataString = String(data: responseData, encoding:String.Encoding(rawValue: String.Encoding.utf8.rawValue))
print(responseDataString) // gives the whole string above
if let obj = responseDataString?.toJSON() as? [String:AnyObject] {
print(obj["nl2br"] as! String) // gives nothing, just nil
}
}
My string extension is like this.
extension String {
func toJSON() -> Any? {
guard let data = self.data(using: .utf8, allowLossyConversion: false) else { return nil }
return try? JSONSerialization.jsonObject(with: data, options: .mutableContainers)
}
}
Any idea why this behaviour is expected? I tried printing obj that gives nothing too.
Your root is an array not a dictionary Change responseDataString?.toJSON() as? [[String:Any]]
extension String {
func toJSON() -> Any? {
return try? JSONSerialization.jsonObject(with: Data(self.utf8))
}
}
let responseDataString:String? = """[{\"nl2br\":\"2019-05-02 19:52:10\",\"nl3br\":\"\",\"nl4br\":\"#lxr\",\"nl5br\":\"1\",\"nl6br\":\"nein\",\"nl7br\":\"bARxrdw9c7WS1RN9c\\/\\/MrA==822b5dd20cb73611:35cab43d0c7e82e73c62818d9f90cfe8\",\"nl8br\":\"tBDSzkQ7eCNERwldgZiwKg==a7590d9d8affdbe5:63b9a9bf6421ea7db2a55f8773990b08\",\"nl9br\":\"fpd17pxVUzcJWNskVWyBeA==cf21783de8334248:a93e8b8a92ef9b238b75ad87a315ce3e\"},{\"nl2br\":\"2019-04-26 21:36:32\",\"nl3br\":\"old\",\"nl4br\":\"\",\"nl5br\":null,\"nl6br\":\"ja\",\"nl7br\":\"emjUIzK92fWwHNLv\\/4xv2Q==8fca202c9a816c7b:655ef8aaaa0212bb9e77a9c35a56c3a7\",\"nl8br\":\"1C5Hy\\/ZhMk3b6SZY8c08lw==cb3b0f4fdd6b5957:034e72d400598fedc43b3111d841a31b\",\"nl9br\":\"KUfLHbih9612dhNCYPOrTg==48da9c3362430e01:3a80ba9fb516e4172aa39b017abcd96e\"},{\"nl2br\":\"2019-04-26 21:20:24\",\"nl3br\":\"holder\",\"nl4br\":\"\",\"nl5br\":null,\"nl6br\":\"ja\",\"nl7br\":\"J59nMBWUMyU9PzdbwQqd0g==f7d3c6c561c33f0b:3465e9131a2577c39cddcc606d0785b0\",\"nl8br\":\"G4rRevk951ZBJJQKzBeJZg==45c0ebcdc1e000e8:dc770c3849fef8b058f85cad42c73e1d\",\"nl9br\":\"338Ud9CIDgnyBV96F2Fx\\/w==d0f825064e0ecf81:0ca00ff27e977ef5f8123d38c643a8b3\"},{\"nl2br\":\"2019-04-10 23:57:17\",\"nl3br\":\"\",\"nl4br\":\"Wasmes, here\'s a video and do ya need?\",\"nl5br\":\"1\",\"nl6br\":\"ja\",\"nl7br\":\"fw17O1L9SuO9FS3qu6U7QQ==706bd09ee3b5ec55:6667d9020a0edcacbd217f631d2305c0\",\"nl8br\":\"2tTE9+0Kr6cVSuEOsq8h0w==3e0e46352da323be:941710bd881546dfa08d3afb6aea2831\",\"nl9br\":\"NAkMx0OsKwXVGndYXbAFmA==1234c0b2992502bf:666f8efd3bdf8ee8b0a2ee4e7222c2ef\"},{\"nl2br\":\"2019-02-22 21:38:16\",\"nl3br\":\"i\'m giving up on you, but don\'t \",\"nl4br\":\"\",\"nl5br\":null,\"nl6br\":\"nein\",\"nl7br\":\"gOv13Dsxf1N2UG46KT3tvQ==dd02a83b1837bb24:4f7c7ab95e873d35685ab7b738626f44\",\"nl8br\":\"40+GOpcNU6M4F688DJyxFA==70bc177842f3f6cf:232b065423bd2683d75ca177775fd352\",\"nl9br\":\"mBc3pEHKBiiPeAEpZRskug==71b353fed6403b99:c58099676beacc146c14867645e29783\"}]"""
if let obj = responseDataString?.toJSON() as? [[String:Any]] {
obj.forEach {
print($0["nl2br"])
}
}
Result
Optional(2019-05-02 19:52:10)
Optional(2019-04-26 21:36:32)
Optional(2019-04-26 21:20:24)
Optional(2019-04-10 23:57:17)
Optional(2019-02-22 21:38:16)
Edit: In json this
[{
"name":"ppp"
}]
is an array of dictionaries to be [[String:Any]] notice nested [[]] , while this
{
"name":"ppp"
}
is a dictionary represented by [String:Any] notice only []
After decrypting my response from API i am getting a string "name:DM100, profile:[1,2,4,5]".
How can i convert this to a json object where name is string and profile is an array
i have tried using but getting nil
if let data = testString.data(using: .utf8) {
do {
return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
} catch {
print("JSON Serialization Error :-> \(error.localizedDescription)")
}
}
return nil
}
Your JSON String is not valid. It should look like this:
let testString = "{\"name\":\"DM100\", \"profile\":[1,2,4,5]}"
if let data = testString.data(using: .utf8) {
do {
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
print(json["name"])
}
}
catch {
print(error.localizedDescription)
}
}
Start and end with curly braces {} and have double quotations around string keys and values.
You can use following code to get the output:
But String must have and valid JSON format first as follows:
let string = "{\"name\":\"DM100\", \"profile\":[1,2,4,5]}"
let data = string.data(using: .utf8)!
do {
if let jsonObj = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? Dictionary<String,Any> {
print(jsonObj)
} else {
print("JSON Error")
}
} catch let error as NSError {
print(error)
}
I am trying to convert jsonString.rawString() to JSON object, but it returns nil.
let jsonData = newsfeedData.rawString()?.data(using: .utf8)
let object = try? JSONSerialization.jsonObject(with: jsonData!, options: .mutableContainers)
print(object) //it returns nil
This is the jsonString:
Printing description of newsfeedData.rawString:
"Data:[{\"UserID\":1,\"post\":[{\"PostId\":1,\"UserId\":1,\"UserName\":\"party Patel\",\"ImagePath\":\"/Files/User/user_20180606_040913967_Hydrangeas.jpg\",\"FileId\":2108,\"FileName\":\"Business Category.png\",\"Email\":\"parth.patel#shaligraminfotech.com\",\"Location\":\"Ahmedabad\",\"PostDescription\":\"P7800\",\"PostPath\":\"/Files/NewsFeed/Photo/fd1c7fcf-e1d0-4ffe-afb4-42bb3fea4fa4.PNG\",\"UserRole\":\"Business\",\"BusinessName\":\"Shaligram infotech\",\"PostType\":false,\"Type\":\"Photo\",\"AdminUserId\":0,\"DisplayText\":null,\"PostCreatedDate\":\"06/08/2018\",\"LikeCount\":4,\"CommentCount\":4,\"ViewCount\":3},{\"PostId\":3,\"UserId\":1,\"UserName\":\"party Patel\",\"ImagePath\":\"/Files/User/user_20180606_040913967_Hydrangeas.jpg\",\"FileId\":2110,\"FileName\":\"DiscovrUS.mov\",\"Email\":\"parth.patel#shaligraminfotech.com\",\"Location\":\"Ahmedabad\",\"PostDescription\":\"P7800\",\"PostPath\":\"/Files/NewsFeed/Video/ab48c228-d7b5-4dff-af56-31a0ac159a35.MOV\",\"UserRole\":\"Business\",\"BusinessName\":\"Shaligram infotech\",\"PostType\":true,\"Type\":\"Video\",\"AdminUserId\":0,\"DisplayText\":null,\"PostCreatedDate\":\"06/08/2018\",\"LikeCount\":1,\"CommentCount\":0,\"ViewCount\":1}]},{\"UserID\":2,\"post\":[{\"PostId\":2,\"UserId\":2,\"UserName\":\"tejas Padia\",\"ImagePath\":\"/Files/User/user_20180606_062946997_Tulips.jpg\",\"FileId\":2109,\"FileName\":\"DiscovrUS.mov\",\"Email\":\"tejaspadia#gmail.com\",\"Location\":\"India\",\"PostDescription\":\"P7800\",\"PostPath\":\"/Files/NewsFeed/Video/2d892eaf-b6dc-433d-985b-2a4588ffd307.MOV\",\"UserRole\":\"Individual\",\"BusinessName\":\"\",\"PostType\":true,\"Type\":\"Video\",\"AdminUserId\":0,\"DisplayText\":null,\"PostCreatedDate\":\"06/08/2018\",\"LikeCount\":3,\"CommentCount\":0,\"ViewCount\":0}]}]"
Make sure json format your value invalid format
just try replace Data: to empty string "" , Your code it's working
do{
var json = "Data:[{\"UserID\":1,\"post\":[{\"PostId\":1,\"UserId\":1,\"UserName\":\"party Patel\",\"ImagePath\":\"/Files/User/user_20180606_040913967_Hydrangeas.jpg\",\"FileId\":2108,\"FileName\":\"Business Category.png\",\"Email\":\"parth.patel#shaligraminfotech.com\",\"Location\":\"Ahmedabad\",\"PostDescription\":\"P7800\",\"PostPath\":\"/Files/NewsFeed/Photo/fd1c7fcf-e1d0-4ffe-afb4-42bb3fea4fa4.PNG\",\"UserRole\":\"Business\",\"BusinessName\":\"Shaligram infotech\",\"PostType\":false,\"Type\":\"Photo\",\"AdminUserId\":0,\"DisplayText\":null,\"PostCreatedDate\":\"06/08/2018\",\"LikeCount\":4,\"CommentCount\":4,\"ViewCount\":3},{\"PostId\":3,\"UserId\":1,\"UserName\":\"party Patel\",\"ImagePath\":\"/Files/User/user_20180606_040913967_Hydrangeas.jpg\",\"FileId\":2110,\"FileName\":\"DiscovrUS.mov\",\"Email\":\"parth.patel#shaligraminfotech.com\",\"Location\":\"Ahmedabad\",\"PostDescription\":\"P7800\",\"PostPath\":\"/Files/NewsFeed/Video/ab48c228-d7b5-4dff-af56-31a0ac159a35.MOV\",\"UserRole\":\"Business\",\"BusinessName\":\"Shaligram infotech\",\"PostType\":true,\"Type\":\"Video\",\"AdminUserId\":0,\"DisplayText\":null,\"PostCreatedDate\":\"06/08/2018\",\"LikeCount\":1,\"CommentCount\":0,\"ViewCount\":1}]},{\"UserID\":2,\"post\":[{\"PostId\":2,\"UserId\":2,\"UserName\":\"tejas Padia\",\"ImagePath\":\"/Files/User/user_20180606_062946997_Tulips.jpg\",\"FileId\":2109,\"FileName\":\"DiscovrUS.mov\",\"Email\":\"tejaspadia#gmail.com\",\"Location\":\"India\",\"PostDescription\":\"P7800\",\"PostPath\":\"/Files/NewsFeed/Video/2d892eaf-b6dc-433d-985b-2a4588ffd307.MOV\",\"UserRole\":\"Individual\",\"BusinessName\":\"\",\"PostType\":true,\"Type\":\"Video\",\"AdminUserId\":0,\"DisplayText\":null,\"PostCreatedDate\":\"06/08/2018\",\"LikeCount\":3,\"CommentCount\":0,\"ViewCount\":0}]}]"
json = json.replacingOccurrences(of: "Data:", with: "")
if let data = json.data(using: .utf8) {
do {
let jsonResult = try JSONSerialization.jsonObject(with: data, options: []) as? [[String: Any]]
print(jsonResult)
} catch {
print(error.localizedDescription)
}
}
I try to deseralize my JSON that look like this :
{
"access_token": "This_is_my_token"
"item01": "blabla"
"item02": "blabla"
...
}
and I want to save only access_token into a variable. Not a big deal.
For exemple, with PHP it is something really simple like:
<?php
$jsonObj = json_decode($jsonString);
$access_token = $jsonObj["access_token"];
?>
But it doesn't look this easy with Swift. I try many things but nothing works for me.
Here is the code I have:
dataString = String(data: data, encoding: .utf8)!
do {
let anyObj: AnyObject? = try JSONSerialization.jsonObject(with: dataString, options: JSONSerialization.ReadingOptions([])) as AnyObject
guard let access_token = anyObj?.firstItem as? [String: AnyObject]
else {return}
print(access_token)
} catch {
print("JSON Deserial. Error")
}
with this code, I can't manipulate anyObj like I do with $jsonObj in PHP, there is no way to do something like anyObj["access_token"]
How can I access to this item in the object ?
Thanks
You can simply call this function by passing your data here and it will return a dictionary. From that dictionary you can pick access_token value.
class func parseJsonToDictionary(data: Data) -> ([String:AnyObject]?,Error?) {
let _ = NSString(data: data, encoding:String.Encoding.utf8.rawValue)
do {
let JSONObject = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
return (JSONObject as? [String:AnyObject],nil)
} catch let error as NSError {
return (nil,error)
}
}
If you are having json string and not json data then you can use this method to convert it to dictionary.
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
}
let str = "{\"name\":\"James\"}"
let dict = convertToDictionary(text: str)
Later you can get value of access_token from dictionary.
Instead of casting anyObj to AnyObject try casting it to a dictionary of strings like
let anyObj: AnyObject? = try JSONSerialization.jsonObject(with: dataString, options: JSONSerialization.ReadingOptions([])) as [String:String]
Then you can get accessToken by using anyObj["access_token"]
How do you convert an array to a JSON string in swift?
Basically I have a textfield with a button embedded in it.
When button is pressed, the textfield text is added unto the testArray.
Furthermore, I want to convert this array to a JSON string.
This is what I have tried:
func addButtonPressed() {
if goalsTextField.text == "" {
// Do nothing
} else {
testArray.append(goalsTextField.text)
goalsTableView.reloadData()
saveDatatoDictionary()
}
}
func saveDatatoDictionary() {
data = NSKeyedArchiver.archivedDataWithRootObject(testArray)
newData = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions(), error: nil) as? NSData
string = NSString(data: newData!, encoding: NSUTF8StringEncoding)
println(string)
}
I would also like to return the JSON string using my savetoDictionart() method.
As it stands you're converting it to data, then attempting to convert the data to to an object as JSON (which fails, it's not JSON) and converting that to a string, basically you have a bunch of meaningless transformations.
As long as the array contains only JSON encodable values (string, number, dictionary, array, nil) you can just use NSJSONSerialization to do it.
Instead just do the array->data->string parts:
Swift 3/4
let array = [ "one", "two" ]
func json(from object:Any) -> String? {
guard let data = try? JSONSerialization.data(withJSONObject: object, options: []) else {
return nil
}
return String(data: data, encoding: String.Encoding.utf8)
}
print("\(json(from:array as Any))")
Original Answer
let array = [ "one", "two" ]
let data = NSJSONSerialization.dataWithJSONObject(array, options: nil, error: nil)
let string = NSString(data: data!, encoding: NSUTF8StringEncoding)
although you should probably not use forced unwrapping, it gives you the right starting point.
Swift 3.0 - 4.0 version
do {
//Convert to Data
let jsonData = try JSONSerialization.data(withJSONObject: dictionaryOrArray, options: JSONSerialization.WritingOptions.prettyPrinted)
//Convert back to string. Usually only do this for debugging
if let JSONString = String(data: jsonData, encoding: String.Encoding.utf8) {
print(JSONString)
}
//In production, you usually want to try and cast as the root data structure. Here we are casting as a dictionary. If the root object is an array cast as [Any].
var json = try JSONSerialization.jsonObject(with: jsonData, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String: Any]
} catch {
print(error.description)
}
The JSONSerialization.WritingOptions.prettyPrinted option gives it to the eventual consumer in an easier to read format if they were to print it out in the debugger.
Reference: Apple Documentation
The JSONSerialization.ReadingOptions.mutableContainers option lets you mutate the returned array's and/or dictionaries.
Reference for all ReadingOptions: Apple Documentation
NOTE: Swift 4 has the ability to encode and decode your objects using a new protocol. Here is Apples Documentation, and a quick tutorial for a starting example.
If you're already using SwiftyJSON:
https://github.com/SwiftyJSON/SwiftyJSON
You can do this:
// this works with dictionaries too
let paramsDictionary = [
"title": "foo",
"description": "bar"
]
let paramsArray = [ "one", "two" ]
let paramsJSON = JSON(paramsArray)
let paramsString = paramsJSON.rawString(encoding: NSUTF8StringEncoding, options: nil)
SWIFT 3 UPDATE
let paramsJSON = JSON(paramsArray)
let paramsString = paramsJSON.rawString(String.Encoding.utf8, options: JSONSerialization.WritingOptions.prettyPrinted)!
JSON strings, which are good for transport, don't come up often because you can JSON encode an HTTP body. But one potential use-case for JSON stringify is Multipart Post, which AlamoFire nows supports.
How to convert array to json String in swift 2.3
var yourString : String = ""
do
{
if let postData : NSData = try NSJSONSerialization.dataWithJSONObject(yourArray, options: NSJSONWritingOptions.PrettyPrinted)
{
yourString = NSString(data: postData, encoding: NSUTF8StringEncoding)! as String
}
}
catch
{
print(error)
}
And now you can use yourSting as JSON string..
Swift 5
This generic extension will convert an array of objects to a JSON string from which it can either be:
saved to the App's Documents Directory (iOS/MacOS)
output directly to a file on the Desktop (MacOS)
.
extension JSONEncoder {
static func encode<T: Encodable>(from data: T) {
do {
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .prettyPrinted
let json = try jsonEncoder.encode(data)
let jsonString = String(data: json, encoding: .utf8)
// iOS/Mac: Save to the App's documents directory
saveToDocumentDirectory(jsonString)
// Mac: Output to file on the user's Desktop
saveToDesktop(jsonString)
} catch {
print(error.localizedDescription)
}
}
static private func saveToDocumentDirectory(_ jsonString: String?) {
guard let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
let fileURL = path.appendingPathComponent("Output.json")
do {
try jsonString?.write(to: fileURL, atomically: true, encoding: .utf8)
} catch {
print(error.localizedDescription)
}
}
static private func saveToDesktop(_ jsonString: String?) {
let homeURL = FileManager.default.homeDirectoryForCurrentUser
let desktopURL = homeURL.appendingPathComponent("Desktop")
let fileURL = desktopURL.appendingPathComponent("Output.json")
do {
try jsonString?.write(to: fileURL, atomically: true, encoding: .utf8)
} catch {
print(error.localizedDescription)
}
}
}
Example:
struct Person: Codable {
var name: String
var pets: [Pet]
}
struct Pet: Codable {
var type: String
}
extension Person {
static func sampleData() -> [Person] {
[
Person(name: "Adam", pets: []),
Person(name: "Jane", pets: [
Pet(type: "Cat")
]),
Person(name: "Robert", pets: [
Pet(type: "Cat"),
Pet(type: "Rabbit")
])
]
}
}
Usage:
JSONEncoder.encode(from: Person.sampleData())
Output:
This will create the following correctly formatted Output.json file:
[
{
"name" : "Adam",
"pets" : [
]
},
{
"name" : "Jane",
"pets" : [
{
"type" : "Cat"
}
]
},
{
"name" : "Robert",
"pets" : [
{
"type" : "Cat"
},
{
"type" : "Rabbit"
}
]
}
]
SWIFT 2.0
var tempJson : NSString = ""
do {
let arrJson = try NSJSONSerialization.dataWithJSONObject(arrInvitationList, options: NSJSONWritingOptions.PrettyPrinted)
let string = NSString(data: arrJson, encoding: NSUTF8StringEncoding)
tempJson = string! as NSString
}catch let error as NSError{
print(error.description)
}
NOTE:- use tempJson variable when you want to use.
extension Array where Element: Encodable {
func asArrayDictionary() throws -> [[String: Any]] {
var data: [[String: Any]] = []
for element in self {
data.append(try element.asDictionary())
}
return data
}
}
extension Encodable {
func asDictionary() throws -> [String: Any] {
let data = try JSONEncoder().encode(self)
guard let dictionary = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any] else {
throw NSError()
}
return dictionary
}
}
If you're using Codable protocols in your models these extensions might be helpful for getting dictionary representation (Swift 4)
Hint: To convert an NSArray containing JSON compatible objects to an NSData object containing a JSON document, use the appropriate method of NSJSONSerialization. JSONObjectWithData is not it.
Hint 2: You rarely want that data as a string; only for debugging purposes.
For Swift 4.2, that code still works fine
var mnemonic: [String] = ["abandon", "amount", "liar", "buyer"]
var myJsonString = ""
do {
let data = try JSONSerialization.data(withJSONObject:mnemonic, options: .prettyPrinted)
myJsonString = NSString(data: data, encoding: String.Encoding.utf8.rawValue) as! String
} catch {
print(error.localizedDescription)
}
return myJsonString
Swift 5
Make sure your object confirm Codable.
Swift's default variable types like Int, String, Double and ..., all are Codable that means we can convert theme to Data and vice versa.
For example, let's convert array of Int to String Base64
let array = [1, 2, 3]
let data = try? JSONEncoder().encode(array)
nsManagedObject.array = data?.base64EncodedString()
Make sure your NSManaged variable type is String in core data schema editor and custom class if your using custom class for core data objects.
let's convert back base64 string to array:
var getArray: [Int] {
guard let array = array else { return [] }
guard let data = Data(base64Encoded: array) else { return [] }
guard let val = try? JSONDecoder().decode([Int].self, from: data) else { return [] }
return val
}
Do not convert your own object to Base64 and store as String in CoreData and vice versa because we have something that named Relation in CoreData (databases).
For Swift 3.0 you have to use this:
var postString = ""
do {
let data = try JSONSerialization.data(withJSONObject: self.arrayNParcel, options: .prettyPrinted)
let string1:String = NSString(data: data, encoding: String.Encoding.utf8.rawValue) as! String
postString = "arrayData=\(string1)&user_id=\(userId)&markupSrcReport=\(markup)"
} catch {
print(error.localizedDescription)
}
request.httpBody = postString.data(using: .utf8)
100% working TESTED
You can try this.
func convertToJSONString(value: AnyObject) -> String? {
if JSONSerialization.isValidJSONObject(value) {
do{
let data = try JSONSerialization.data(withJSONObject: value, options: [])
if let string = NSString(data: data, encoding: String.Encoding.utf8.rawValue) {
return string as String
}
}catch{
}
}
return nil
}