how manipulate a NSDictionary generated by a json file in swift - swift

I've a NSDictionary populated by a JSON file.
JSON file content (initially)
{
"length" : 0,
"locations" : []
}
I want add some elements in "locations". The elements have the below structure:
[
"name" : "some_name",
"lat" : "4.88889",
"long" : "5.456789",
"date" : "19/01/2015"
]
In next code I read de JSON File
let contentFile = NSData(contentsOfFile: pathToTheFile)
let jsonDict = NSJSONSerialization.JSONObjectWithData(contentFile!, options: nil, error: &writeError) as NSDictionary`
like you can see jsonDict contain the JSON's info but in a NSDictionary object.
At this point I can't add the elements mentioned before, I tried insert NSData, NSArray, Strings, and nothing results for me
After do this I want convert "final" NSDictionary in JSON again to save it in a file.
The "final" NSDictionary must be like this
{
"length" : 3,
"locations" : [
{
"name" : "some_name",
"lat" : "4.88889",
"long" : "5.456789",
"date" : "19/01/2015"
},
{
"name" : "some_name_2",
"lat" : "8.88889",
"long" : "9.456789",
"date" : "19/01/2015"
},
{
"name" : "some_name_3",
"lat" : "67.88889",
"long" : "5.456789",
"date" : "19/01/2015"
}
]
}
"length" control the index for new element
I have no more ideas to do this. thanks in advance

If you want to be able to modify the dictionary, you can make it mutable:
let jsonDict = NSJSONSerialization.JSONObjectWithData(contentFile!, options: .MutableContainers, error: &writeError) as NSMutableDictionary
The resulting NSMutableDictionary can be modified. For example:
let originalJSON = "{\"length\" : 0,\"locations\" : []}"
let data = originalJSON.dataUsingEncoding(NSUTF8StringEncoding)
var parseError: NSError?
let locationDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers, error: &parseError) as NSMutableDictionary
locationDictionary["length"] = 1 // change the `length` value
let location1 = [ // create dictionary that we'll insert
"name" : "some_name",
"lat" : "4.88889",
"long" : "5.456789",
"date" : "19/01/2015"
]
if let locations = locationDictionary["locations"] as? NSMutableArray {
locations.addObject(location1) // add the location to the array of locations
}
If you now constructed JSON from the updated locationDictionary, it would look like:
{
"length" : 1,
"locations" : [
{
"long" : "5.456789",
"lat" : "4.88889",
"date" : "19/01/2015",
"name" : "some_name"
}
]
}

Related

Firebase query ordering not working properly

Basically I have played with Firebase for the past week, and I recently stumbled upon the 'queryOrderedByChild()' that as far as I know - allows you to sort data in firebase. However, I seem to not get the proper results. My Firebase data looks like this:
{
"names" : {
"-KHVUwXdVPHmrO_O5kil" : {
"id" : "0",
"name" : "Jeff"
},
"-KHVV7lCeac0cZNMi9fq" : {
"id" : "3",
"name" : "Stig"
},
"-KHVVCjXgl0XxasVOHF1" : {
"id" : "13",
"name" : "Ali"
},
"-KHVVJtyUO-yJZiompJO" : {
"id" : "7",
"name" : "Hannah"
},
"-KHVVR8tMSO1Oh7R8tR1" : {
"id" : "2",
"name" : "Amanda"
}
}
}
, and my code looks like this:
ref.childByAppendingPath("names")
.queryOrderedByChild("id")
.observeEventType(.ChildAdded) { (snapshot:FDataSnapshot!) in
if let myID = snapshot.value["id"] as? String {
print(myID)
}
The output is still in a random order, displaying: 0, 2,7,1,8,4 - Isn't this supposed to be numeric? What am I doing wrong? How can I sort it so it get's numeric either ascending or descending?
You say that you're ordering by a number, but the value of your id property is stored as a string.
Since you're storing them as a string, they will be returned in lexicographical order.
If you want them to be in numerical order, you should store them as numbers
"-KHVUwXdVPHmrO_O5kil" : {
"id" : 0,
"name" : "Jeff"
},
Alternatively, you could store the ids as zero-padded strings:
{
"names" : {
"-KHVUwXdVPHmrO_O5kil" : {
"id" : "0000",
"name" : "Jeff"
},
"-KHVV7lCeac0cZNMi9fq" : {
"id" : "0003",
"name" : "Stig"
},
"-KHVVCjXgl0XxasVOHF1" : {
"id" : "0013",
"name" : "Ali"
},
"-KHVVJtyUO-yJZiompJO" : {
"id" : "0007",
"name" : "Hannah"
},
"-KHVVR8tMSO1Oh7R8tR1" : {
"id" : "0002",
"name" : "Amanda"
}
}
}
Since the strings are all the same length, they will be sorted in the correct order. But you'll have to decide on the length of the string/maximum id value in the latter solution, so it seems worse.
If you using order by child you going to order your id you no going to touch it's value.
Then maybe you have to try something like
(FIRDatabaseQuery *) queryOrderedByValue
queryOrderedByValue: is used to generate a reference to a view of the data that's been sorted by child value.

Are there different solution how retrieve waypoints?

"-KHbCuQflKHrJiUmfpG0" : {
"waypoints" : {
"-KHbCuQflKHrJiUmfpG1" : {
"latitude" : 13.17078652595298,
"longitude" : -59.5775944578738
},
"-KHbCuQflKHrJiUmfpG2" : {
"latitude" : 13.15541190861343,
"longitude" : -59.57619643155932
},
"-KHbCuQg9W_tebl1pU66" : {
"latitude" : 13.148444967591,
"longitude" : -59.5589266947333
}
},
"subtitle" : "jamesrick",
"title" : "Highway",
"type" : "polyline"
},
I have this structure for lines in Firebase. How retrieve all data with also nested node waypoints?
ref.observeEventType(.Value, withBlock: { polylines in
if let objects = polylines.children.allObjects as? [FDataSnapshot] {
for object in objects {
polylineDictionary = object.values as? Dictionary<String, AnyObjects> {
// ? ? ?
}
}
}
})
Now I have access to title, subtitle, type but how obtain access to waypoints? When I use
`polylineDictionary["waypoints"] as? [String: [String:Double]]`
so this dictionaries are not ordered. Thanks for some advice.
This is how I would get the nested waypoints... it's basically by iterating through the keys... I would also add some error checking when grabbing the longitude and latitudes to make sure they're there, but this is the gist:
if let polylineDictionary["waypoints"] as? [String: [String:Double]] {
let waypoints = Array(polylineDictionary.keys)
for i in 0..<waypoints.count {
let waypointId = waypoints[i]
let latitude = polylineDictionary[waypointId]["latitude"]
let longitutde = polylineDictionary[waypointId]["longitude"]
}
}
It's not clear from the question about ordering; if you just want to get to the waypoints, it's pretty straight forward:
Assume your complete Firebase structure is:
root_node
"-KHbCuQflKHrJiUmfpG0" : {
"waypoints" : {
"-KHbCuQflKHrJiUmfpG1" : {
"latitude" : 13.17078652595298,
"longitude" : -59.5775944578738
},
"-KHbCuQflKHrJiUmfpG2" : {
"latitude" : 13.15541190861343,
"longitude" : -59.57619643155932
},
"-KHbCuQg9W_tebl1pU66" : {
"latitude" : 13.148444967591,
"longitude" : -59.5589266947333
}
},
"subtitle" : "jamesrick",
"title" : "Highway",
"type" : "polyline"
}
Suppose I want the data for this specific node, -KHbCuQflKHrJiUmfpG0
let nodeRef = rootRef.childByAppendingPath("-KHbCuQflKHrJiUmfpG0")
nodeRef.observeSingleEventOfType(.Value , withBlock: { snapshot in
print(snapshot.value) //prints everything in the node
let title = snapshot.value["title"] as! String //to get any element
print(title) //prints Highway
var waypoints = [String: [String:String]]() //dict to hold key:value, unordered
waypoints = snapshot.value["waypoints"] as! Dictionary
print(waypoints) //prints the 3 waypoints and their children (as a dict)
//get fancy and convert the dictionary to an array (which can be sorted)
let arr = waypoints.map {"\($0) \($1)"}
for point in arr {
print(point)
}
}

Converting Firebase data into Swift array

This is how my Firebase data looks like:
[ {
"adress" : "Högåsstigen 10 332 33 Gislaved",
"helg" : "18:00-02:00",
"latitude" : 57.2985,
"longitude" : 13.54326,
"namn" : "Restaurang Åsen",
"outlet" : 0,
"phone" : "0371-123456",
"star" : 0,
"tag" : "Restaurang",
"vardag" : "10:00-19:30"
}, {
"adress" : "Högåsstigen 12 332 33 Gislaved",
"helg" : "18:00-02:00",
"latitude" : 57.9985,
"longitude" : 13.94326,
"namn" : "Kalles ställe",
"outlet" : 0,
"phone" : "0371-123456",
"star" : 2,
"tag" : "Restaurang",
"vardag" : "10:00-19:30"
}, {
"adress" : "Högåsstigen 15 332 33 Gislaved",
"helg" : "18:00-02:00",
"latitude" : 55.603384,
"longitude" : 13.020619,
"namn" : "Olles Pub",
"outlet" : 0,
"phone" : "0371-123456",
"star" : 1,
"tag" : "Krog",
"vardag" : "10:00-19:30"
} ]
I want to grab "adress" from the database.
I'm having problem to convert the data I grab from Firebase to append into an array so I can use them later. I get the error "Value of type 'String' has no member 'generator'".
I have no idea how to proceed in my coding, any suggestions?
var adresserArray = [String]()
let ref = Firebase(url: "https://HIDINGMYURL.firebaseio.com/")
ref.observeEventType(.ChildAdded, withBlock: {snapshot in
let adresser = (snapshot.value.objectForKey("adress")) as! String!
for add in adresser{
adresserArray.append(adresser)
}
})
You are trying to iterate over String here
let adresser = (snapshot.value.objectForKey("adress")) as! String!
for add in adresser{
adresserArray.append(adresser)
}
try just replace this code with
let adresser = (snapshot.value.objectForKey("adress")) as! String
adresserArray.append(adresser)

Fetching one element of array with sibling items (Without using aggregation or putting other sibling's value 1)

"translation" : [
{
"language" : "english",
"name" : "shahid Afridi",
"desc" : "batsmen",
"player" : "capten"
},
{
"language" : "spanish",
"name" : "shhid Ofridi",
"desc" : "batsmeen",
"player" : "capteen"
},
{
"language" : "french",
"name" : "hhid afrede is best",
"desc" : "batsmin",
"player" : "captn"
}
],
"auto-publish" : "publish",
"color" : "red",
"boolean" : "true"
I have this document in mongodb
In return
i want translation[0] with auto-publish, color and boolean.
Note: Without using aggregation or putting other sibling's value 1
You can use forEach on your cursor:
db.test.find({}).forEach(function(doc){
if (doc.hasOwnProperty('translation')){
var newdoc = {};
newdoc = doc.translation[0];
newdoc['auto-publish'] = doc['auto-publish'];
newdoc['color'] = doc['color'];
newdoc['boolean'] = doc['boolean'];
print(tojson(newdoc));
}
})
I don't think there's any other way to re-organize document as you need without using aggregation.

How can i store request.responseData into NSdictionary for parsing

When i request to my web server it send me Json string in request.response.i want to store that json into NSDictionary for parsing and storing it into database.
My Json format is
{ "rowNumber" : 3,
[ { "Age" : "2 - 4 years old ",
"AndroidID" : "2",
"Category" : "Chanson",
"Description" : "fourni",
"Size" : 3447196,
"Thumbnail" : null,
"Title" : "test",
"iTunesID" : "2",
"inactive" : false,
"product_id" : 2} ],
[ { "Age" : "2 - 4 years old ",
"AndroidID" : "3",
"Category" : "Chanson",
"Description" : "Animation ",
"Size" : 3447196,
"Thumbnail" : null,
"Title" : "Escargot",
"iTunesID" : "3",
"inactive" : false,
"product_id" : 3
} ]
}
IF i use this code to print String by string to NSlog it display fine but How i can i store that into NDdictionary ??
NSString *response = [[request responseString] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
To store into dictionary i tried this code but this store my json in reverse order
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:request.responseData
options:kNilOptions
error:&error];
for(NSString *key in [json allKeys]) {
NSLog(#"%#",[json objectForKey:key]);
it store it into reverse order. Any help is appreciated.I am using ASIFormDataRequest for networking.
Your JSON is not valid.
I check at
http://jsonviewer.stack.hu/
http://jsonviewer.net/
Your array format is wrong. Read JSON syntax HERE
This is how it should be done:
{ "rowNumber" : 3,
"Data" : [ {
"Age" : "2 - 4 years old ",
"AndroidID" : "2",
"Category" : "Chanson",
"Description" : "fourni",
"Size" : 3447196,
"Thumbnail" : null,
"Title" : "test",
"iTunesID" : "2",
"inactive" : false,
"product_id" : 2
} ,
{
"Age" : "2 - 4 years old ",
"AndroidID" : "3",
"Category" : "Chanson",
"Description" : "Animation ",
"Size" : 3447196,
"Thumbnail" : null,
"Title" : "Escargot",
"iTunesID" : "3",
"inactive" : false,
"product_id" : 3
} ]
}
Then to store JSON data, I recommend you using my technique HERE. Proper way and quite a beast
Json is parsed and output is NSArray or NSDicitonary
You added wrong json.Not proper format
NSdictionary doesn't have an order as you say.It is a key-value pair mechanism.That is it stores as a value for a key using setObject:ForKey: method and gives the value back when asked with same key used to set the value using objectForKey: method