How to get NSArray from json - ios

I have a JSON like this
{
accountList: [
{
acctId: "",
acctType: ""
},
{
acctId: "",
acctType: ""
}
],
tokenBack: "",
userId: "",
verificationCode: ""
}
and i want accountList array from that JSON as an array. Any one have solution?

NSDictionary *result = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingMutableContainers error:nil];
NSArray *accountList = result[#"accountList"];

Related

How to get the Current city in iOS

I want to send the city name to the server. I am getting latitude longitude using CLLocationManager. Then I use this link to do reverse geocoding.
https://maps.googleapis.com/maps/api/geocode/json?latlng=lati,longi&key=myApiKey
My problem is for different locations the number of address components are different. As an example, I am getting this array of address componeents for my current location.
"results": [
{
"address_components": [
{
"long_name": "ABC Rd",
"short_name": "ABC Rd",
"types": [
"route"
]
},
{
"long_name": "My City",
"short_name": "My City",
"types": [
"administrative_area_level_2",
"political"
]
},
{
"long_name": "My Province",
"short_name": "AB",
"types": [
"administrative_area_level_1",
"political"
]
},
{
"long_name": "My Country",
"short_name": "MC",
"types": [
"country",
"political"
]
}
],
For my client's location im getting this
results": [
{
"address_components": [
{
"long_name": "4",
"short_name": "4",
"types": [
"street_number"
]
},
{
"long_name": "some name",
"short_name": "some name",
"types": [
"route"
]
},
{
"long_name": "some name",
"short_name": "Some name",
"types": [
"political",
"sublocality",
"sublocality_level_2"
]
},
{
"long_name": "some name",
"short_name": "some name",
"types": [
"political",
"sublocality",
"sublocality_level_1"
]
},
{
"long_name": "city",
"short_name": "city",
"types": [
"locality",
"political"
]
},
{
"long_name": "some name",
"short_name": "Some name",
"types": [
"administrative_area_level_1",
"political"
]
},
{
"long_name": "Client country",
"short_name": "CC",
"types": [
"country",
"political"
]
},
{
"long_name": "12345",
"short_name": "12345",
"types": [
"postal_code"
]
}
],
How can I get the exact city name for different locations when the address components are different. First I tried to get it my component index number but since number of components are different I cant do that. Whats the correct way to do that? Please help me.
Thanks
UPDATE
[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(#"Found placemarks: %#, error: %#", placemarks, error);
if (error == nil && [placemarks count] > 0) {
placemark = [placemarks objectAtIndex:0];
NSString *address = [NSString stringWithFormat:#"%# %#\n%# %#\n%#\n%#",
placemark.subThoroughfare, placemark.thoroughfare,
placemark.postalCode, placemark.subLocality,
placemark.subAdministrativeArea,
placemark.country];
// NSString *address=[self.placemark];
NSDictionary *dictAddress = [NSDictionary dictionaryWithDictionary:placemark.addressDictionary];
NSMutableDictionary *dictTxtData = [NSMutableDictionary dictionary];
NSLog(#"----LOCATION NAME----%#",[placemark.addressDictionary valueForKey:#"Name"]);
NSLog(#"-----STREET ADDRESS---%#",[placemark.addressDictionary valueForKey:#"Thoroughfare"]);
NSLog(#"-----CITY-----%#",[placemark.addressDictionary valueForKey:#"City"]);
strCountry=placemark.country;
NSLog(#"Address------%#",address);
} else {
NSLog(#"%#", error.debugDescription);
}
} ];
Results I get
----LOCATION NAME----My Rd
-----STREET ADDRESS---My Rd
-----CITY-----(null)
Address------(null) My Rd
(null) (null)
(null)
My Country
This is how I call to location update
-(void)GetLocationData
{
if (self.locationManager == nil)
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
}
else
{
nil;
}
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[self.locationManager requestWhenInUseAuthorization];
}
else
{
nil;
}
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;//kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
}
The json responses from Google API can contain different place marks depending upon the location. Using index is not the correct approach. You can find the city name in json components where type is locality. Below is the code snippet
NSDictionary *locationData = [[json objectForKey:#"results"] objectAtIndex:0];
NSArray* addressComponents= [locationData objectForKey:#"address_components"];
//Iterate each result of address components - find locality and country
NSString *cityName;
for (NSDictionary* address in addressComponents)
{
NSArray* addressType = [address objectForKey:#"types"];
NSString* firstType = [addressType objectAtIndex:0];
if([firstType isEqualToString:#"locality"])
cityName = [address objectForKey:#"long_name"];
}
or you can also use CLGeocoder API in iOS.
CLGeocoder *ceo = [[CLGeocoder alloc]init];
CLLocation *loc = [[CLLocation alloc]initWithLatitude:lat longitude:long];
[ceo reverseGeocodeLocation: loc completionHandler:
^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSLog(#"placemark %#",placemark.locality); // Get the city name
}];
call setLocation() in viewdidload method
func setLocation()
{
// self.view.backgroundColor = UIColor.whiteColor()
self.edgesForExtendedLayout = .None
// Set bounds to inner-west Sydney Australia.
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
// print("dofo \(manager.location?.coordinate.latitude)")
// print(manager.location?.coordinate.longitude)
currentlat = (manager.location?.coordinate.latitude)!
cuurentlong = (manager.location?.coordinate.longitude)!
let geoCoder = CLGeocoder()
let location = CLLocation(latitude: currentlat,
longitude: cuurentlong)
geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in
// Place details
var placeMark: CLPlacemark!
placeMark = placemarks?[0]
// Address dictionary
print(placeMark.addressDictionary)
// Location name
if let locationName = placeMark.addressDictionary!["Name"] as? NSString {
print(locationName)
}
// Street address
if let street = placeMark.addressDictionary!["Thoroughfare"] as? NSString {
print(street)
}
// City
if let city = placeMark.addressDictionary!["City"] as? NSString {
print(city)
}
// Zip code
if let zip = placeMark.addressDictionary!["ZIP"] as? NSString {
print(zip)
}
// Country
if let country = placeMark.addressDictionary!["Country"] as? NSString {
print(country)
}
})
}

Parse JSON with Swift JSON

How to get Value Radio Name With Swift JSON
I wrote like this
let response = JSON["topradio"]["Data"]
before this i created model for values but am not able to pic values like radio_name
{
"topradio": {
"result": "success",
"Data": [
[
{
"radio_name": "Kantipur",
"rimage": "radio/1422960479145155755920731096211441695162.jpeg",
"status": "1",
"user_faverate": "false",
"popular_radio": "0",
"radio_id": "4"
}
]
[
{
"radio_name": "Kantipur",
"rimage": "radio/1422960479145155755920731096211441695162.jpeg",
"status": "1",
"user_faverate": "false",
"popular_radio": "0",
"radio_id": "4"
}
]
]
}
Thanks in Advance
You can iterate through your nested data Array this way.
let dataArray = JSON["topradio"]["Data"].array
for item in dataArray {
let itemArray = item.array
for subItem in itemArray {
if let name = subItem["radio_name"].string {
print(name)
}
}
}

IOS JSON parsing into an objectkey

I'm trying to implement the "Checking Duplicate Username" first of all, I have to get my json which stored all the record of my users. and get the object which is the username. Then matching them with the text from the UItTextField. My problem is that I can see all my json but I can't seems to parse it correctly.
-(IBAction) ChkUsername: (id) sender {
NSDictionary * userdata = [NSDictionary new];
[DIOSUser userGet: userdata success: ^ (AFHTTPRequestOperation * operation, id response) {
NSLog(#"%#", response);
DIOSSession * session = [DIOSSession sharedSession];
[session setUser: [response objectForKey: #"user"]];
NSDictionary * uname = [
[session user] objectForKey: #"name"];
if ([self.txtUsernameRegister.text isEqualToString: uname]) {
// if([uname isEqual:self.txtUsernameRegister.text]){
NSLog(#"You cannot use this Username");
} else {
NSLog(#"You can use this username");
}
}
failure: ^ (AFHTTPRequestOperation * operation, NSError * error) {
NSLog(#"%#", [error localizedDescription]);
}];
}
I also got this error NSCFArray objectForKey:]
Edit here is how my JSON looks like.
{
uid: "60",
name: "pae1344",
mail: "viper1344#gmail.com",
theme: "",
signature: "",
signature_format: "plain_text",
created: "1396189622",
access: "0",
login: "1396189622",
status: "1",
timezone: "Asia/Bangkok",
language: "",
picture: "0",
init: "viper1344#gmail.com",
data: null,
uri: "http://localhost/drupal/rest/user/60"
},

iOS parse string with multiple JSON objects?

I'm having some troubles when my app receives multiple JSON objects at the same time. I'm using a TCP socket that is open to my server which sends me messages. The reason i seem to recieve multiple messages is probably due to network lag.
This is what a server message can look like (i then put this into a NSString and try to parse the JSON):
{
"id": "156806",
"type": "message",
"userCity": "",
"userCountry": "",
"os": "",
"browser": "",
"trafficType": "",
"seKeyword": "",
"seType": "",
"currentPage": "",
"userId": "1",
"agentId": "352",
"customField1": "",
"visitorNick": "Visitor 147220060",
"msg": "asd",
"time": "16:05",
"channel": "V147220060",
"visits": "254"
} {
"type": "previewStopped",
"msg": "",
"visitorNick": "Mackan",
"customField1": "",
"visitorNick": "Visitor V147220060",
"time": "16:05",
"channel": "V147220060"
} {
"id": "156807",
"type": "message",
"userCity": "",
"userCountry": "",
"os": "",
"browser": "",
"trafficType": "",
"seKeyword": "",
"seType": "",
"currentPage": "",
"userId": "1",
"agentId": "352",
"customField1": "",
"visitorNick": "Visitor 147220060",
"msg": "as",
"time": "16:05",
"channel": "V147220060",
"visits": "254"
} {
"id": "156808",
"type": "message",
"userCity": "",
"userCountry": "",
"os": "",
"browser": "",
"trafficType": "",
"seKeyword": "",
"seType": "",
"currentPage": "",
"userId": "1",
"agentId": "352",
"customField1": "",
"visitorNick": "Visitor 147220060",
"msg": "da",
"time": "16:05",
"channel": "V147220060",
"visits": "254"
}
And here is how i currently parse the NSString, note that the above JSON is outputData in the code below:
// Parse the message from the server
NSError* error;
NSDictionary *JSON =
[NSJSONSerialization JSONObjectWithData: [outputData dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error: &error];
NSString* type = [JSON objectForKey:#"type"];
if(error) {
NSLog(#"PARSE ERROR ------------->>>>> : %#\n", error);
}
NSLog(#"SERVER TYPE --> %#\n", type);
if([type isEqualToString:#"message"]) {
[self messageReceived:outputData];
}
The above works perfectly when i only recieve one JSON in outputData but when multiple JSONs are recieved it trows an error:
PARSE ERROR ------------->>>>> : Error Domain=NSCocoaErrorDomain
Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)"
(Garbage at end.) UserInfo=0x14e9acb0 {NSDebugDescription=Garbage at
end.}
Any ideas how to handle this?
Hmm...you could wrap it yourself. Take the data you get and prepend "{ "dataarray": [" to the beginning, and "] }" to the end. This will produce an array, the elements of which will be your individual JSON entities.
Try this:
NSData *jsonData = [outputData dataUsingEncoding:NSUTF8StringEncoding];
NSArray *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&e];
NSDictionary *JSON = [dict objectAtIndex:0];
NSString* type = [JSON objectForKey:#"type"];
EDIT:
An example of JSON, because your "" can cause problems:
{
aula = "AULA M04";
cuatrimestre = "Primer quadrimestre";
dia = Dimecres;
edificio = "AULARI V";
fin = "18:00";
inicio = "15:00";
}
Hope it helps!
It's erroring out because you don't have valid JSON in your string. You'll need to do something like the following to get it into the correct format:
NSString *formattedString = [NSString stringWithFormat:#"[%#]", [outputData stringByReplacingOccurrencesOfString:#"} {" withString:#"},{"]];
NSError *error = nil;
NSArray *JSON = [NSJSONSerialization JSONObjectWithData:[formattedString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:&error];
That is assuming outputData is an NSString.
If your data stream contains multiple JSONs in sequence, it strictly isn't JSON anymore. Rather, it is a custom protocol which embeds JSON.
You need to first define your custom protocol. It can be defined as an arbitrary number of JSONs in sequence - if this fits your needs. NSJSONSerialization isn't capable to parse your custom protocol, though.
You could define your protocol differently, for example: your data is a contiguous stream of messages, where a message is a "blob" prepended by value representing the length in bytes, e.g.:
message := message_size CRLF blob
message_size := digits
data := message*
That is, your data may look as follows:
2\n\r[]4\n\r5["a"]
This is of course a pretty naive protocol, but it should be sufficient to demonstrate the basic idea.
Your blob could then be JSON UTF-8.
This "protocol" can be easily parsed with a custom parser, where the "blob" (a single JSON) will be passed through a JSON parser, possibly wrapped into a NSData object.

Get NSArray/NSDictionary for Nested JSON

I have this JSON :
{
"_id" : "class_1",
"schedule" : [
{
"date" : "1-1-2014",
"subjects" : [
{
"time_range" : "08:00-10:00",
"subject" : "Sports"
},
{
"time_range" : "10:00-12:00",
"subject" : "History"
}
]
},
{
"date" : "2-1-2014",
"subjects" : [
{
"time_range" : "08:00-10:00",
"subject" : "Physics"
},
{
"time_range" : "10:00-12:00",
"subject" : "Chemistry"
},
{
"time_range" : "10:00-12:00",
"subject" : "Biology"
}
]
},
{
"date" : "3-1-2014",
"subjects" : [
{
"time_range" : "08:00-10:00",
"subject" : "English"
},
{
"time_range" : "10:00-12:00",
"subject" : "Maths"
}
]
},
{
"date" : "4-1-2014",
"subjects" : [
{
"time_range" : "08:00-10:00",
"subject" : "Spanish"
},
{
"time_range" : "10:00-12:00",
"subject" : "Choreography"
},
{
"time_range" : "12:00-14:00",
"subject" : "Music"
},
{
"time_range" : "14:00-16:00",
"subject" : "Sports"
},
{
"time_range" : "16:30-18:30",
"subject" : "Religion"
}
]
}
]
}
What I would like to do is get an NSArray/NSMutableArray or NSDictionary/NSMutableDictionary` with the subjects for a GIVEN date. So for example if I type in the date 4-1-2014, I would like to get an array or dictionary with the 5 subjects that are contained in that date.
What I would like to do is get an NSArray/NSMutableArray or NSDictionary/NSMutableDictionary with the subjects for a GIVEN date. So for example if I type in the date 1-1-2014, I would like to get an array or dictionary with the 2 subjects that are contained in that date.
This is what I have tried:
//NSDICTIONARY CONTAINING CLASS DATA FOR CLASS ID
NSDictionary *classData =
[NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:&error];
//NSMUTABLEDICTIONARY CONTAINING SCHEDULE DATA FOR CLASS ID
NSMutableArray *scheduleDatabyClassID = [classData objectForKey:#"schedule"];
//NSMUTABLEARRAY CONTAINING SCHEDULE SUBJECTS OF CLASS ID
NSMutableArray *subjectsDatabyDate =[[NSMutableArray alloc] init] ;
for (NSMutableDictionary *subjectsData in scheduleDatabyClassID ){
NSString *subjectsData_temp = [subjectsData objectForKey:#"subjects"];
NSString *schedule_date = [subjectsData objectForKey:#"date"];
NSString *check = #"25-11-2013";
if ([schedule_date isEqualToString:check]) {
[subjectsDatabyDate addObject:subjectsData_temp];
}
}
Below is what I would like to get, but WITHOUT MANUALLY setting the index to 0. I want subjectsDataByDate : for the value (1-1-2014) for example.
NSLog(#"subjectsDatabyDate \n %# ", [subjectsDatabyDate objectAtIndex:0]);
This did the trick. As I mentioned, I needed a function that returns me an NSArray with containing the GIVEN date:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"date==%#",#"1-1-2014"];
NSArray *result_wanted = [scheduleDatabyClassID filteredArrayUsingPredicate:predicate];
NSLog(#"THE RESULT \n %# ", result_wanted);
If you do this for many different dates, and repeatedly, I would proceed somehow different.
NSDictionary is a class for key-value pairs. Your whole JSON data is actually a dictionary with keys "_id" and "schedule", and "schedule" has an array value. But looking at the data, a dictionary would have been much more appropriate, with for example "1-1-2014" as key and the rest as data. So you could turn the whole array into a dictionary, similar to your own code:
NSMutableDictionary *subjectsDatabyDate =[NSMutableDictionary dictionary] ;
for (NSDictionary *subjectsData in scheduleDatabyClassID )
{
NSString *schedule_date = [subjectsData objectForKey:#"date"];
subjectsDatabyDate [schedule_date] = subjectsData;
}
Now you can access any date very quickly:
NSDictionary* result_wanted = subjectsDatabyDate [#"1-1-2014"];
The difference is that access to an NSDictionary uses a hash table that will go directly to the item that you want, while the "filteredArray" has to iterate through the whole array, every time you look for a date.

Resources