How to append JSON data into an array in swift - arrays

Hello Guys i need help I'm trying to save json data in an array but i'm not getting it properly can anyone help me here is the complete code
let url = URL(string: "http://localhost:3000/liveData/device/20042")
URLSession.shared.dataTask(with: url!, completionHandler: {
(data, response, error) in
if(error != nil){
print("error")
}else{
do{
let json = try JSONSerialization.jsonObject(with: data!, options:[]) as! [[String: Any]]
print(json)
for item in json {
if let title = item["BV"] as? String {
self.userIdArray.append(title)
}
if let title = item["BC"] as? String {
self.userIdArray.append(title)
}
if let title = item["SV"] as? String {
self.userIdArray.append(title)
}
if let title = item["SC"] as? String {
self.userIdArray.append(title)
}
}
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}catch let error as NSError{
print(error)
}
}
}).resume()
I want to save json data in userIdArray can anyone help me, Thank you.
{
"SV" : 0,
"SC" : 0,
"BV" : 14.807,
"BC" : 0.024,
}
This is the output json

Related

Load two json files of Arrays of Dictionaries. Add missing dictionaries from the file A to file B

I need to sync two json files to add new content from File A (located in the app bundle) to File B after an app update.
Both json files are arrays of dictionaries. I need to iterate the dictionaries form File A, and based on the "id" value, if a dictionary is not present in File B I need to append those missing dictionaries and save File B back to the file system.
I have a solution below that does this, and seems to work. But it's SO ugly! Granted I put this together in about 15 minutes cringing the whole way but I'm sure there has to be a better way of handling this. Also, I don't want to further muddy the waters by converting these dictionaries to structs or models for the comparison only to convert them back to dictionaries -> json.
Any advise here would be great! I prefer clean code and this is a mess.
typealias JSON = [[String: Any]]
static private func uglySync() {
let fileName: String = "someFileName"
guard let sourceUrl = Bundle.main.url(forResource: fileName, withExtension: "json") else { return }
guard let destinationDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
let destinationUrl = destinationDirectory.appendingPathComponent("Data/" + fileName + ".json")
do {
let sourceData = try Data(contentsOf: sourceUrl)
do {
if let sourceArray = try JSONSerialization.jsonObject(with: sourceData, options: .mutableContainers) as? JSON {
do {
let destinationData = try Data(contentsOf: destinationUrl)
do {
if let destinationArray = try JSONSerialization.jsonObject(with: destinationData, options: .mutableContainers) as? JSON {
var mutableArray = destinationArray
sourceArray.forEach({ (item) in
if let itemId = item["id"] as? String {
let foundItem = destinationArray.filter { $0["id"] as! String == itemId }.first
if foundItem == nil {
mutableArray.append(item)
}
}
})
do {
let jsonData = try JSONSerialization.data(withJSONObject: mutableArray, options: .prettyPrinted)
try jsonData.write(to: destinationUrl)
} catch let error as NSError {
print("Couldn't write to file: \(error.localizedDescription)")
}
} else {
print("Cound not process json")
}
} catch {
print(error.localizedDescription)
}
} catch {
print(error.localizedDescription)
}
} else {
print("Cound not process json")
}
} catch {
print(error.localizedDescription)
}
} catch {
print(error.localizedDescription)
}
// oh wow the try catches :/
}
I've grouped converting the files to jsonArray to simplify the do...catch. Alternatively, if you don't need to print the error message, you could opt to have Optional try? as well to remove the do...catch block.
typealias JSONArray = [[String: Any]]
private func jsonArray(from fileURL: URL) -> JSONArray? {
do {
let fileData: Data = try Data(contentsOf: fileURL)
guard let jsonArray = (try JSONSerialization.jsonObject(with: fileData, options: .mutableContainers)) as? JSONArray else {
debugPrint("Failed to find JSON Array table")
return nil
}
return jsonArray
} catch {
print(error.localizedDescription)
return nil
}
}
func sync() {
let fileName: String = "someFileName"
guard
let fileURL: URL = Bundle.main.url(forResource: fileName, withExtension: "json"),
let destinationDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first,
let destinationURL: URL = destinationDirectory.appendingPathComponent("Data/" + fileName + ".json"),
let sourceArray = jsonArray(from: fileURL),
let destinationArray = jsonArray(from: destinationURL)
else {
return
}
var mutableArray = destinationArray
let destinationIDArray = destinationArray.compactMap { $0["id"] as? String }
mutableArray.forEach { (item) in
if let itemId = item["id"] as? String, !(destinationIDArray.contains { $0 == itemId }) {
mutableArray.append(item)
}
}
// Update File
do {
let jsonData = try JSONSerialization.data(withJSONObject: mutableArray, options: .prettyPrinted)
try jsonData.write(to: destinationURL)
} catch {
print("Couldn't write to file: \(error.localizedDescription)")
}
}
I think you can put the different trys in the same do block.
do {
try function1()
try function2()
} catch {
print(error.localizedDescription)
}
So afterwards your function may look like
typealias JSON = [[String: Any]]
static private func moderatelyOkSync() {
let fileName: String = "someFileName"
guard let sourceUrl = Bundle.main.url(forResource: fileName, withExtension: "json") else { return }
guard let destinationDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
let destinationUrl = destinationDirectory.appendingPathComponent("Data/" + fileName + ".json")
do {
let sourceData = try Data(contentsOf: sourceUrl)
if let sourceArray = try JSONSerialization.jsonObject(with: sourceData, options: .mutableContainers) as? JSON {
let destinationData = try Data(contentsOf: destinationUrl)
}
var mutableArray = destinationArray
sourceArray.forEach({ (item) in
if let itemId = item["id"] as? String {
let foundItem = destinationArray.filter { $0["id"] as! String == itemId }.first
if foundItem == nil {
mutableArray.append(item)
}
}
})
let jsonData = try JSONSerialization.data(withJSONObject: mutableArray, options: .prettyPrinted)
try jsonData.write(to: destinationUrl)
} catch {
print(error.localizedDescription)
}
}
The way I would do it is to Decode the json files with struct and then encode(serialization) it to the other files. Because the code to do that would be a 2 liner, but you would first have to layout all the variables in the struct. Probably still not optimal

Json data - white console - Xcode 9

I am trying a simple app in which I want to convert some values. It worked until I tried to convert the data in a dictionary, and when I hit run, it builds successfully, but the console does not print anything. Here is the code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "http://gnb.dev.airtouchmedia.com/rates.json")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil
{
print("ERROR")
}
else {
if let content = data {
do {
//Array
let myJson = try JSONSerialization.jsonObject(with:content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
//print(myJson)
if let rate = myJson["rate"] as? NSDictionary {
if let currency = rate["AUD"] {
print(currency)
}
}
}
catch {
}
}
}
}
task.resume()
}
because you are parsing JSON wrongly
try this
let myJson = try JSONSerialization.jsonObject(with:content, options: JSONSerialization.ReadingOptions.mutableContainers) as? [[String: AnyObject]] else { return }
for rate in myJson
guard let cur = user["from"] as? String,
let curRate = user["rate"] as? Double else { break }
if let cur = "AUD" {
print(curRate)
}
Update:
You are receiving Array of Objects in response,
so first you have to treat it as Array of object,
Then you have to loop through this objects and then inside that loop you have to extract the data you were looking for and play with it.

Getting Data from JSON Swift

Can Anyone Help me with this
my data after parsing a JSON URL is
{
AREA = (
{
"area_name" = "Bhaktamadhu Nagar";
"city_id" = 4;
id = 31;
price = "100.00";
},
{
"area_name" = "Gandamunda";
"city_id" = 4;
id = 32;
price = "100.00";
}
);
}
and there is a lot more.
I want to fetch only area_name and price values in an array
my code is something like that
do {
let parsedData = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as! NSDictionary
print(parsedData)}
I am getting my Upper format in the parsedData
What is the exact code for getting my area_name and price which should store in two separate arrays as aname[] and price[]
Please don't mark it as a duplicate already searched a lot before posting this.
Your JSON data is converted into [String: AnyObject].
AREA data is [[String: AnyObject]] so create a [String: AnyObject] array. and getting a one by one value from array.
How to fetch JSON data from a url using URLSession?
try this code. it's helpfull
URLSession.shared.dataTask(with: url) { (data, response, error) in
if let jsonData = data {
do {
let parsedData = try JSONSerialization.jsonObject(with: jsonData, options: .mutableLeaves) as! [String: AnyObject]
if let area = parsedData["AREA"] as? [[String: AnyObject]] {
for a in area {
areaNameArr.append(a["area_name"])
priceArr.append(a["price"])
print(a)
}
}
}
catch let error {
debugPrint(error)
}
}
else {
debugPrint(error as Any)
}
}.resume()
Use the SwiftyJSON Lib.
It’s easy and fast.
I am using it and it’s very helpful in this way:
let session = URLSession(configuration: URLSessionConfiguration.ephemeral)
self.Task = session.dataTask(with: RequestLink as URLRequest , completionHandler: { (data,response,error) in
if error != nil {
print(error as Any)
}
let ReadJson4Rest = JSON(data: data!)
if let Rest_Details = ReadJson4Rest["Result"].array{
for Details in Rest_Details {
let Comment = Details.dictionaryValue["Comment"]!
let UserName = Details.dictionaryValue["User_ID"]!
if Comment != nil {
let FirstChar = UserName.description.characters.first
self.GetUserImage(UserName: UserName.string! ,AlphabetCat: (FirstChar?.description)!)
DispatchQueue.main.async {
self.CommentValue.append(Comment.string!)
self.UserNames.append(UserName.string!)
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "Load"), object: nil)
}
}
}
}
})
self.Task?.resume()
}

Working With Json in swift 3

I want to get long_name from this JSON file I can just access 'results' with this code:
let url = URL(string: "https://maps.googleapis.com/maps/api/geocode/json?latlng=35.7229513,51.3566039&language=fa&key=AIzaSyBXOPT1jEYizWZHOKLwv4dhacgYTcmn3I4")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!)
}
else{
if let urlcontent = data {
do{
let jsonResult = try JSONSerialization.jsonObject(with: urlcontent, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:Any]
print(jsonResult["results"]!)
if let jsonResult = jsonResult["results"] as? [String: Any] {
if let address_components = jsonResult["address_components"] as? [String: Any] {
print(address_components)
if let long_name = address_components["long_name"] as? [String: Any] {
print(long_name)
}
}
}
}
catch{
print("json failed")
}
}
}
}
task.resume()
But I'm just getting result this is my JSON file:
https://maps.googleapis.com/maps/api/geocode/json?latlng=35.7339859%2C51.3393980&sensor=true_or_false&language=fa
Your result key contains Array as value not Dictionary so simply change [String:Any] to [[String:Any]] and then access address_components from the each dictionary objects of resultsArray, now address_components is also array of dictionary and long_name is inside that dictionary. So try like this.
if let resultsArray = jsonResult["results"] as? [[String: Any]] {
for dic in resultsArray {
if let addressArray = dic["address_components"] as? [[String:Any]] {
for address in addressArray {
if let longName = address["long_name"] as? String {
print(longName)
}
}
}
}
}

apple change my JSON format after using URLSession.shared.dataTask

I am green to swift 3. In order to transfer data between mysql server and iOS, i try to connect my server and device by URLSession.Shared.dataTask.
but the format was changed.
from (the format showed in web)
[{"id":"1","names":"abc","pws_1":"password","pws_2":"pw"}]
to (the format show in Xcode)
Optional(<__NSSingleObjectArrayI 0x6200000039e0>(
{
names = abc;
id = 1;
"pws_1" = password;
"pws_2" = pw;
}
)
)
How can I receive data from this "JSONarray"?
P.S.
this is my code:
let url = URL(string: "http://")
URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in
if error != nil {
print(error)
} else {
do {
let json = try? JSONSerialization.jsonObject(with: data!, options: [])
if json != nil{
if let Jtwo = json as? [String: Any] {
if let names = Jtwo["names"] as? String {
print(names)
}else{
print(Jtwo)
}
}else{
print(json)
}
}else{
print("json nil")
}
//self.statusL.text = names
} catch let error as NSError {
print(error)
}
}
}).resume()
You can parse and access your JSON Array like this.
URLSession.shared.dataTask(with: request) {data, response, error in
if error == nil {
do {
let jsonObj = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [[String:Any]]
if let user = jsonObj.first {
print(user["names"])
print(user["id"])
print(user["pws_1"])
print(user["pws_2"])
DispatchQueue.main.async {
self.label.text = user["names"]
}
}
}
catch {
print(error)
}
}
}.resume()

Resources