I got a string with a particular format which have a Entity Name:#"Entry". I can't modify the string. How to access the string? I can access array objects but not inside. How to use initWithEntityName?
Here is the string
<__NSArrayI 0x7fe093f87160>(
<Entry: 0x600000498c90> (entity: Entry; id: 30506398-1852-433D-B536-DC57F484F754> ; data: {
cumulativeTime = 0000;
latitude = “12.972442”
longitude = "77.580643";
type = enrty;
entryName = Bangalore;
}),
<Entry: 0x600000498c90> (entity: Entry; id: 30506398-1852-433D-B536- DC57F484F754> ; data: {
cumulativeTime = 0000;
latitude = “13.067439”
longitude = "80.237617";
type = enrty;
entryName = Chennai;
})
This is how I got the array.
+(NSArray*) routePlan
{
NSString* jsonString = [NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:#"Documents/DataJson" withExtension:nil]
encoding:NSUTF8StringEncoding error:nil];
NSArray* array = [jsonString componentsSeparatedByString:#","];
}
Do I need to use predicate?
I need the value of latitude and logtude. I can do "po array[0]", but can't go inside of array[0].
Get the below error if I try to access latitude.
error: Execution was interrupted, reason: Attempted to dereference an invalid ObjC Object or send it an unrecognized selector.
The process has been returned to the state before expression evaluation.
If I do po array[0], I got the below.
<__NSArrayI 0x7fe093f87160>(
<Entry: 0x600000498c90> (entity: Entry; id: 30506398-1852-433D-B536-DC57F484F754> ; data: {
cumulativeTime = 0000;
latitude = “12.972442”
longitude = "77.580643";
type = enrty;
entryName = Bangalore;
})
First of all, your file is not in json format.
Now, when you do this :
NSString* aircraftJSONString = [NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:#"Documents/AircraftDataJson" withExtension:nil]
encoding:NSUTF8StringEncoding error:nil];
NSArray* aircraftJsonFplWaypoints = [aircraftJSONString componentsSeparatedByString:#","];
You are actually splitting your text at the comma, that's why your aircraftJsonFplWaypoints contains 2 object :
Fist a string with value :
<__NSArrayI 0x7fe093f87160>( (entity: Entry;
id: 30506398-1852-433D-B536-DC57F484F754> ; data: { cumulativeTime =
0000; latitude = “12.972442” longitude = "77.580643"; type = enrty;
entryName = Bangalore; })
then a string with value
(entity: Entry; id: 30506398-1852-433D-B536-
DC57F484F754> ; data: { cumulativeTime = 0000; latitude = “13.067439”
longitude = "80.237617"; type = enrty; entryName = Chennai; })
What you have in aircraftJsonFplWaypoints are strings, not dictionary nor array. This will lead you nowhere.
What you need to do is to use regular expression to get what's in the {} . This should work:
{[^}]*}
So I'll do something like :
NSError * error;
NSString * pattern = #"\\{[^\\}]*\\}";
NSRegularExpression * regex = [[NSRegularExpression alloc] initWithPattern:pattern
options:0
error:&error];
NSArray<NSTextCheckingResult *> * matches = [regex matchesInString:aircraftJSONString options:NSMatchingReportCompletion range:NSMakeRange(0, aircraftJSONString.length)];
for(NSTextCheckingResult * match in matches)
{
NSString * substring = [aircraftJSONString substringWithRange:match.range];
// Remove the bracket
substring = [substring substringWithRange:NSMakeRange(1, substring.length - 2)];
// split around the ";" => get the llat/long
NSArray<NSString *>* parts = [substring componentsSeparatedByString:#";"];
NSString * latLong = parts[1];
/* continue to get the longitude and latitude */
}
}
but I would recommend to use a standard for input, for example instead of copy/paste the po output, you can serialize your objects to json with the NSJSONSerialisation API with would make storing/retrieving much easier.
It seems to be the data you are fetching from bundle file is not a valid JSON, it is something else. If it is the JSON data then the below will be the approach to get that.
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"DataJson" ofType:#"json"];
NSLog(#"%#",filePath);
NSURL *url = [NSURL fileURLWithPath:filePath];
NSData *jsonData = [NSData dataWithContentsOfURL:url];
NSError *error = nil;
id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:&error];
if (error == nil){
NSLog(#"#### JSON object #### %#",jsonObject);
}else{
NSLog(#"#### JSON parsing error #### %#",error);
}
But as you mentioned you have an Entry as ManagedObject, which means you are trying to fetch the data from core data. So that please confirm me how you are saving and fetching data from coredata. (provide me sample code).
If you feel that you are correct with your approach, then please try to print the Entry object properties.
+(NSArray*) routePlan
{
NSString* jsonString = [NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:#"Documents/DataJson" withExtension:nil]
encoding:NSUTF8StringEncoding error:nil];
NSArray* array = [jsonString componentsSeparatedByString:#","];
[array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger index, BOOL * _Nonnull stop)
{
Entry* entry = (Entry*)obj;
NSLog(#"id is :: %#",entry.id);
NSLog(#"id is :: %#",entry.data);
}];
return nil;
}
Related
This is my "po array" looks like.
<__NSArrayI 0x7fe093f87160>(
<Entry: 0x600000498c90> (entity: Entry; id: 30506398-1852-433D-B536-
DC57F484F754> ; data: {
cumulativeTime = 0000;
latitude = “12.972442”
longitude = "77.580643";
type = enrty;
entryName = Bangalore;
}),
<Entry: 0x600000498c90> (entity: Entry; id: 30506398-1852-433D-B536-
DC57F484F754> ; data: {
cumulativeTime = 0000;
latitude = “13.067439”
longitude = "80.237617";
type = enrty;
entryName = Chennai;
})
The above JSON is stored in and I'm retrieving using the below code.
+(NSArray*) routePlan
{
NSString* aircraftJSONString = [NSString stringWithContentsOfURL [[NSBundle mainBundle] URLForResource:#"Documents/DataJson" withExtension:nil]
encoding:NSUTF8StringEncoding error:nil];
NSArray* aircraftJsonFplWaypoints = [aircraftJSONString componentsSeparatedByString:#","];
}
I can access the array[0] but not the objects in array[0]. I need the latitude and longitude. Any idea how to strip down to the inside dictionary values.
The dictionaries seem to be instances of an NSManagedObject subclass named Entry.
Just use a loop to iterate over the entries
for (Entry *entry in array) {
NSLog(#"lat: %# - long: %#", entry.latitude, entry.longitude);
}
You have an array of dictionaries and you need to parse through it.
I haven't tried running this code but this should work. Later on you can add some safety checks for nil values.
NSDictionary *dict = array[0];
NSString *latitude = dict["latitude"];
NSString *longitude = dict["longitude"];
You can use key value coding :
[array[0] valueForKey:#"latitude"];
Simply use objective c fast enumeration for getting data from ArrayList.
for (NSDictionary *dic in array) {
NSLog(#"dic values %#",[dic objectForKey:#"data"]);
NSDictionary *data = [dic objectForKey:#"data"];
NSString *lat = [data objectForKey:#"latitude"];
}
Below is my code to access the JSON API from Edmunds.com, this works perfectly to access the information I am just having trouble with accessing the key, value pairs.
NSURL *equipmentURL = [NSURL URLWithString: [NSString stringWithFormat:#"https://api.edmunds.com/api/vehicle/v2/styles/%#/equipment?fmt=json&api_key=%#", self.carID, apiKey]];
NSData *jsonData = [NSData dataWithContentsOfURL:equipmentURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
self.engineArray = [NSMutableArray array];
NSArray *equipmentArray = [dataDictionary objectForKey:#"equipment"];
for (NSDictionary *carInfoDictionary in equipmentArray) {
NSArray *attributes = [carInfoDictionary objectForKey:#"attributes"];
NSLog(#"%#", attributes);
}
In the NSLog from the above code shows this:
2016-11-03 10:21:26.029 CarWise[25766:1896339] (
{
name = "Engine Immobilizer";
value = "engine immobilizer";
},
{
name = "Power Door Locks";
value = "hands-free entry";
},
{
name = "Anti Theft Alarm System";
value = "remote anti-theft alarm system";
}
)
My main question is how can I access the name and value for each array? Let's say I want to create a UILabel that will have the string of one of the values?
Probably this will help
// Array as per the post
NSArray *attributes = (NSArray *)[carInfoDictionary objectForKey:#"attributes"];
// Loop to iterate over the array of objects(Dictionary)
for (int i = 0; i < attributes.count; i++) {
NSDictionary * dataObject = [NSDictionary dictionaryWithDictionary:(NSDictionary *)attributes[i]];
// This is the value for key "Name"
NSString *nameData = [NSString stringWithString:[dataObject valueForKey:#"name"]];
NSLog(#"Value of key : (name) : %#", nameData);
}
I am using this method to show the string of location using current location latitude and longitude but it is showing differently
NSString *urlString = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&sensor=false",location.coordinate.latitude, location.coordinate.longitude];
NSError* error;
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString] encoding:NSASCIIStringEncoding error:&error];
NSData *data = [locationString dataUsingEncoding:NSUTF8StringEncoding];
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSDictionary *dic = [[json objectForKey:#"results"] objectAtIndex:0];
NSArray* arr = [dic objectForKey:#"address_components"];
//Iterate each result of address components - find locality and country
NSString *cityName;
NSString *countryName;
for (NSDictionary* d in arr)
{
NSArray* typesArr = [d objectForKey:#"types"];
NSString* firstType = [typesArr objectAtIndex:0];
if([firstType isEqualToString:#"locality"])
cityName = [d objectForKey:#"long_name"];
if([firstType isEqualToString:#"country"])
countryName = [d objectForKey:#"long_name"];
}
NSString* locationFinal = [NSString stringWithFormat:#"%#,%#",cityName,countryName];
NSLog(#"Final Location %# ",locationFinal);
but final location is showing this type :-
Final Location नठदिलà¥à¤²à¥,India
Why it is showing this type? Can anyone know about this.
Please supply the language with the API params. If language is not supplied, the geocoder attempts to use the preferred language as specified in the Accept-Language header, or the native language of the domain from which the request is sent.
So please replace the code as with the language parameter as like this.
NSString *urlString = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&sensor=false&language=en",location.coordinate.latitude, location.coordinate.longitude];
and try again.
I believe that is an uninitialzed variable which is pointing into random memory.
Try:
NSString *cityName = nil;
NSString *countryName = nil;
Short-circuit your for loop:
for (NSDictionary* d in arr)
{
// Add this after the existing code:
if (cityName && countryName)
break;
}
and check for errors before presenting the results:
if (cityName && countryName) {
NSString* locationFinal = [NSString stringWithFormat:#"%#,%#",cityName,countryName];
NSLog(#"Final Location %# ",locationFinal);
} else {
NSLog(#"Failed to find location");
}
Finally your JSON-processing code does no error-checking at all. That's a mistake.
When attempting to save a PFObject, I was receiving the error "Error: object not found for update (Code: 101, Version: 1.2.15)" (logged automatically), and the localized description was logging: The operation couldn’t be completed. (Parse error 101.)
I eventually isolated the problem: the NSDictionary I was assigning to one of the fields on the PFObject had quotation marks around key names; turns out these are added automatically by the NSDictionary class when a key name contains nonalphanumeric characters.
Here's an example of a (logged) PFObject whose save was giving an error:
"<PlaybackPositionTracker:MKXTjOXg07:(null)> {\n ACL = \"<PFACL: 0xc1e80f0>\";\n aclRead = (\n \"\"\n );\n aclWrite = (\n \"\"\n );\n deletedAt = \"<null>\";\n nowPlaying = \"<null>\";\n playbackPositionDictionary = {\n \"http://podcastdownload.npr.org/anon.npr-podcasts/podcast/35/290491304/npr_290491304.mp3\" = 0;\n };\n}"
I suppose Parse interprets quotation marks to indicate a link to another Parse object or something (or else I'm at a loss to explain why this gives the "object not found" error).
How can I use a url string as a key in a dictionary that is assigned to a field on a PFObject? I could remove all nonalphanumeric characters from the string, but that would be a messy solution. What other options might there be? Thank you.
Is there a reason you can't store and retrieve them separately?
NSString * url = #"http://podcastdownload.npr.org/anon.npr-podcasts/podcast/35/290491304/npr_290491304.mp3";
CGFloat currentPlaybackPosition = 0.0; // position in seconds
NSMutableDictionary * playbackPositionDictionary = [NSMutableDictionary new];
playbackPositionDictionary[#"URL"] = url;
playbackPositionDictionary[#"Seconds"] = [NSNumber numberWithFloat:currentPlaybackPosition];
PFObject * ob = [PFObject objectWithClassName:#"TrialClass"];
ob[#"playbackPositionDictionary"] = playbackPositionDictionary;
[ob saveInBackground];
// Retrieve
NSDictionary * retrievedPlaybackPositionDictionary = ob[#"playbackPositionDictionary"];
NSString * urlForPlaybackPosition = retrievedPlaybackPositionDictionary[#"URL"];
CGFloat playbackPositionInSeconds = [retrievedPlaybackPositionDictionary[#"Seconds"]floatValue];
NSLog(#"Start playing: %# starting at: %#", urlForPlaybackPosition, playbackPositionInSeconds);
The only solutions I can think of involve converting the URL to a more accessible key. Would this work as an alternative solution?
I'm not sure if this is improved, but if you want to store these dictionaries on Parse, perhaps converting them to data strings is another work around:
Declare Methods:
- (NSString *) hexStringFromDictionary:(NSDictionary *)dict {
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict
options:0
error:&error];
return [jsonData description];
}
- (NSDictionary *) dictionaryFromHexString:(NSString *)string {
string = [string lowercaseString];
NSMutableData *data= [NSMutableData new];
unsigned char whole_byte;
char byte_chars[3] = {'\0','\0','\0'};
int i = 0;
int length = string.length;
while (i < length-1) {
char c = [string characterAtIndex:i++];
if (c < '0' || (c > '9' && c < 'a') || c > 'f')
continue;
byte_chars[0] = c;
byte_chars[1] = [string characterAtIndex:i++];
whole_byte = strtol(byte_chars, NULL, 16);
[data appendBytes:&whole_byte length:1];
}
return [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
}
Conversion From HexString Modified From HERE!
Create Your Dictionary:
NSString * url = #"http://podcastdownload.npr.org/anon.npr-podcasts/podcast/35/290491304/npr_290491304.mp3";
CGFloat currentPlaybackPosition = 0.0; // position in seconds
NSMutableDictionary * playbackPositionDictionary = [NSMutableDictionary new];
playbackPositionDictionary[url] = [NSNumber numberWithFloat:currentPlaybackPosition];
Save To PFObject:
PFObject * ob = [PFObject objectWithClassName:#"ParseClass"];
NSString * dictString = [self hexStringFromDictionary:playbackPositionDictionary];
ob[#"playbackPositionDictionaryString"] = dictString;
Retrieve From PFObject:
NSString * hexString = ob[#"playbackPositionDictionaryString"];
NSDictionary * playbackPositionDictionary = [self dictionaryFromHexString:hexString];
I have some JSON data which is pulled from a URL. The code I have written works fine to download the JSON and parse it, but I cannot seem to access it how I need too, especially where the data is contained as a sub-element of another one.
Here is the JSON format:
{
address = "<null>";
city = "<null>";
country = UK;
"country_code" = GB;
daylight = 1;
for = daily;
items = (
{
asr = "5:22 pm";
"date_for" = "2013-7-1";
dhuhr = "1:01 pm";
fajr = "2:15 am";
isha = "11:47 pm";
maghrib = "9:24 pm";
shurooq = "4:39 am";
}
);
latitude = "50.9994081";
link = "http://muslimsalat.com/UK";
longitude = "0.5039011";
"map_image" = "http://maps.google.com/maps/api/staticmap?center=50.9994081,0.5039011&sensor=false&zoom=13&size=300x300";
"postal_code" = "<null>";
"prayer_method_name" = "Muslim World League";
"qibla_direction" = "119.26";
query = "51.000000,0.500000";
state = "<null>";
timezone = 0;
title = UK;
"today_weather" = {
pressure = 1020;
temperature = 14;
};
}
(These are Islamic prayer times.)
My Objective-C so far is this:
-(CLLocationCoordinate2D) getLocation{
CLLocationManager *locationManager = [[[CLLocationManager alloc] init] autorelease];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
CLLocation *location = [locationManager location];
CLLocationCoordinate2D coordinate = [location coordinate];
return coordinate;
}
//class to convert JSON to NSData
- (IBAction)getDataFromJson:(id)sender {
//get the coords:
CLLocationCoordinate2D coordinate = [self getLocation];
NSString *latitude = [NSString stringWithFormat:#"%f", coordinate.latitude];
NSString *longitude = [NSString stringWithFormat:#"%f", coordinate.longitude];
NSLog(#"*dLatitude : %#", latitude);
NSLog(#"*dLongitude : %#",longitude);
//load in the times from the json
NSString *myURLString = [NSString stringWithFormat:#"http://muslimsalat.com/%#,%#/daily/5.json", latitude, longitude];
NSURL *url = [NSURL URLWithString:myURLString];
NSData *jsonData = [NSData dataWithContentsOfURL:url];
if(jsonData != nil)
{
NSError *error = nil;
id result = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
NSArray *jsonArray = (NSArray *)result; //convert to an array
if (error == nil)
NSLog(#"%#", result);
NSLog(#"%#", jsonArray);
for (id element in jsonArray) {
NSLog(#"Element: %#", [element description]);
}
}
}
When running this code, the only output I get is a list of element names (address, city, country, so on). items is given, but not its child elements. I understand that this is what I am asking the code for with:
for (id element in jsonArray) {
NSLog(#"Element: %#", [element description]);
}
but I do not know how to move onto the next step.
The only data values which I require are in fact the times themselves (so, items>asr, items>dhuhr, etc).
How can I get these values themselves and then save them as values I can work with?
Thank you!
(...); - is Array
{...}; - is Dictionary
so your "element" is Dictionary
use objectForKey:
example:
for (id element in jsonArray) {
NSLog(#"Element asr: %#", [element objectForKey:#"asr"]); // or element[#"asr"]
}
NSArray *jsonArray = (NSArray *)result; //convert to an array
This doesn't 'convert', it's just you promising the compiler that result is really an NSArray. And in this case it's a lie.
Your code is currently just printing a list of the keys in the dictionary that is returned in the JSON. Try this to get to the list of items (it's an array so you need to deal with there possibly being multiple entries):
NSDictionary *result = [NSJSONSerialization ...
for (NSDictionary *itemDict in result[#"items"]) {
NSLog(#"item: %#", itemDict);
}
Then you can extract the times.
You can extract info by following:
NSError* error = nil;
NSDictionary *userInfo; //your main data
if([NSJSONSerialization class])
userInfo = [NSJSONSerialization JSONObjectWithData:[request responseData] options:kNilOptions error:&error];
//to extract items
NSDictionary *items = [[[userInfo objectForKey:#"items"] JSONValue] objectAtIndex:0];