Q - iOS - Search and use specific part of parsed JSON array - ios

This is my first time using JSON. In my app I am fetching some data from "Open Weather API". I get back some array, with way to many entries, and I need to search ones that are on specific day and return temp.day and weather.icon from them. So far I managed to fetch data propely. As far I know i should use some FOR loop with IF inside it, but I am pulling my hairs out how to do it in Objective C.
There is my fetch method:
- (void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData //1
options:kNilOptions
error:&error];
NSArray* weatherList = [json objectForKey:#"list"];
NSLog(#"everything %#", weatherList ); //3
}
And part array from NSLog:
{
clouds = 92;
deg = 265;
dt = 1456221600;
humidity = 100;
pressure = "1007.96";
rain = "0.24";
speed = "5.12";
temp = {
day = "4.11";
eve = "4.62";
max = "4.87";
min = "2.78";
morn = "4.11";
night = "2.78";
};
weather = (
{
description = "light rain";
icon = 10d;
id = 500;
main = Rain;
}
);
},
{
clouds = 88;
deg = 268;
dt = 1456308000;
humidity = 98;
pressure = "1012.04";
rain = "1.31";
speed = "6.35";
temp = {
day = "3.57";
eve = "3.74";
max = "3.74";
min = "2.38";
morn = "2.53";
night = "2.38";
};
weather = (
{
description = "light rain";
icon = 10d;
id = 500;
main = Rain;
}
);
},
{
clouds = 20;
deg = 243;
dt = 1456394400;
humidity = 100;
pressure = "1015.42";
snow = "0.25";
speed = "5.08";
temp = {
day = "2.95";
eve = "4.09";
max = "4.54";
min = "-0.65";
morn = "1.74";
night = "-0.65";
};
weather = (
{
description = "light snow";
icon = 13d;
id = 600;
main = Snow;
}
);
},
{
clouds = 80;
deg = 273;
dt = 1456480800;
humidity = 100;
pressure = "1016.63";
snow = "0.04";
speed = "2.79";
temp = {
day = "0.2";
eve = "2.79";
max = "2.79";
min = "-3.33";
morn = "-2.7";
night = "-2.42";
};
weather = (
{
description = "light snow";
icon = 13d;
id = 600;
main = Snow;
}
);
},
{
clouds = 87;
deg = 132;
dt = 1456567200;
humidity = 0;
pressure = "1007.07";
rain = "0.22";
snow = "0.03";
speed = 5;
temp = {
day = "3.96";
eve = "1.48";
max = "3.96";
min = "-3.12";
morn = "-3.12";
night = "-1.59";
};
weather = (
{
description = "clear sky";
icon = 01d;
id = 800;
main = Clear;
}
);
}
What are good practices? Do I fetch proper enough big part of JSON?
Should I use dome NSDictionary too? Any ideas are welcome!
Thanks

1) As per documentation given the time is in GMT format so you need to convert the time in IST to compare
here is code to convert the time . I dont know your time zone I converted it in Indian Standard Time
for ( NSDictionary *obj in weatherList) {
NSDateFormatter *inDateFormatter = [[NSDateFormatter alloc] init];
inDateFormatter.dateFormat = #"dd-MM-yyyy";
inDateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:#"IST"];
NSDate *inDate = [inDateFormatter dateFromString:[obj objectForKey:#"dt"]];
if ([self isItToday:inDate]) {
NSDictionary * tempDict = [obj objectForKey:#"temp"];
NSDictionary * weatherDict = [[obj objectForKey:#"weather"]objectForKey:0];
NSString * dayTemp = [tempDict objectForKey:#"day"];//only storing for time being you can use where you needed
NSString * icon = [weatherDict objectForKey:#"icon"];//only storing for time being you can use where you needed
}
}
2) Now you need to compare it with todays date
+ (BOOL)isItToday:(NSDate *)date {
if (date != nil) {
NSString *givenDateString = [self stringFromDate:date inDateFormat:#"dd-MM-yyyy"];
NSString *toDayString = [self stringFromDate:[NSDate date] inDateFormat:#"dd-MM-yyyy"];
NSDate *givenDate = [self dateFromString:givenDateString inDateFormat:#"dd-MM-yyyy"];
NSDate *toDay = [self dateFromString:toDayString inDateFormat:#"dd-MM-yyyy"];
if ([givenDate isEqualToDate:toDay]) {
return YES;
} else {
return NO;
}
} else {
return NO;
}
}
+ (NSString *)stringFromDate:(NSDate *)date inDateFormat:(NSString *)inDateformat
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:kLocaleIdentifierEN_US_POSIX];
[dateFormatter setDateFormat:inDateformat];//#"dd/MM/yyyy"
return [dateFormatter stringFromDate:date];
}
+ (NSDate *)dateFromString:(NSString *)stringDate inDateFormat:(NSString *)inDateformat
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:kLocaleIdentifierEN_US_POSIX];
[dateFormatter setDateFormat:inDateformat];//#"dd/MM/yyyy"
return [dateFormatter dateFromString:stringDate];
}
also add this line
#define kLocaleIdentifierEN_US_POSIX [NSLocale localeWithLocaleIdentifier:#"en_US_POSIX"]

Use following code,
double comparingdt = 1456308000;
__block NSString *tempday, *weathericon;
[weatherList enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSDictionary *weather, NSUInteger idx, BOOL * _Nonnull stop) {
*stop = ([weather[#"dt"] doubleValue] == comparingdt);
if (*stop)
{
tempday = weather[#"temp"][#"day"];
weathericon = [weather[#"weather"] firstObject][#"icon"];
}
}];

Related

Reset value by UITableView sections

I am building a personal budget app that tracks my purchases. I have an NSDictionary of NSArray that looks like this:
{
46 = (
{
DATE = "11/14/2019";
ID = 21;
PLACE = Kroger;
PRICE = "23.32";
},
{
DATE = "11/14/2019";
ID = 22;
PLACE = Walmart;
PRICE = "12.54";
}
);
47 = (
{
DATE = "11/18/2019";
ID = 23;
PLACE = Cinco;
PRICE = "65.32";
}
);
}
The keys in the NSDictionary are determined by strftime using %W. Basically I have a set limit I can spend per week (i.e. 190) and I want in each titleForHeaderInSection: to have a total value that is determined by each field's PRICE in each key.
I currently have the following on the app:
The following calculate the NSDictionary listed above along with the total value:
Note: arrFoodInfo is a NSDictionary of just the entries without the week numbers
for (NSDictionary *dict in self.arrFoodInfo) {
NSString *date = [dict objectForKey:#"DATE"];
[totalPrices addObject:[dict objectForKey:#"PRICE"]];
for (NSString *price in totalPrices) {
if ([totalPrices containsObject:price]) {
_sumPrices += [price floatValue]; // Calculates total value
[totalPrices removeObject:price];
}
}
NSDateFormatter *SDF = [[NSDateFormatter alloc]
init];
[SDF setDateStyle:NSDateFormatterMediumStyle];
[SDF setDateFormat:#"MM/dd/yyyy"];
NSDate *convertedDate = [SDF dateFromString:date];
NSDateComponents *dateComponents = [calendar components:NSCalendarUnitYear | NSCalendarUnitWeekOfYear fromDate:convertedDate];
NSInteger week = dateComponents.weekOfYear;
NSInteger index = week;
NSNumber *key = #(index);
NSMutableArray *weekArray = weeksDictionary[key];
if (!weekArray) {
weekArray = [NSMutableArray array];
weeksDictionary[key] = weekArray;
}
[weekArray addObject:dict];
}
At the moment, I am getting the total of each PRICE but the total value should be different per section. What is the best option to determine this?

Group and sum values of NSDictionary by month where key is NSDate

I have a dictionary with the following structure,
arrayOne = {
"2015-11-09T00:00:00.000Z" = 1;
"2015-11-16T00:00:00.000Z" = 2;
"2015-11-23T00:00:00.000Z" = 3;
"2015-11-30T00:00:00.000Z" = 4;
"2015-12-07T00:00:00.000Z" = 5;
"2015-12-14T00:00:00.000Z" = 6;
"2015-12-21T00:00:00.000Z" = 7;
"2015-12-28T00:00:00.000Z" = 8;
"2016-01-04T00:00:00.000Z" = 9;
"2016-01-11T00:00:00.000Z" = 1;
"2016-01-18T00:00:00.000Z" = 2;
"2016-01-25T00:00:00.000Z" = 3;
}
I'd like to create another dictionary with values like,
arrayTWo = {
"November" = 10;
"December" = 26;
"January" = 15;
}
I tried by getting month values of dates in a separate array and values in a separate array and then tried to get those in a nsmutabledictionary, but it does not assign value for duplicate keys and got a solution like
arrayTWo = {
"November" = 4;
"December" = 8;
"January" = 3;
}
I couldn't find a better way, Any options are appreciated. Thanks.
Try this, it uses NSDateFormatter to get the month name from the date, it's localized depending on the current locale. If your locale is not english and you need to get the english month names uncomment the line to set the locale explicitly.
The logic is simple:
Enumerate the dictionary, If the key (month) exists, add the value, if it doesn't create the key
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"MMMM";
// formatter.locale = [NSLocale localeWithLocaleIdentifier:#"en_US_POSIX"];
NSMutableDictionary *result = [NSMutableDictionary dictionary];
for (NSDate *key in arrayOne.allKeys) {
NSString *month = [formatter stringFromDate:key];
if (result[month] == nil) {
result[month] = arrayOne[key];
} else {
NSInteger value = [result[month] integerValue];
result[month] = #(value + [arrayOne[key] integerValue]);
}
}
NSLog(#"%#", result);

how to get array response from json in string?

I am getting the response from json like this
parcel = (
{
datetime = "2015-08-31 21:48:45";
height = 2;
id = 21;
invoice = NO;
length = 2;
mtype = IN;
"num_item" = 2;
"parcel_number" = 1;
pname = "Parcel number - 1";
"pro_number" = tanu;
status = 1;
type = Exact;
uid = 185;
weight = 2;
width = 2;
wtype = KG;
}
);
I want to get the height,date time,invoice in a string.. How can this be done? AnyOne can help me for this...
NSArray * arr_Parcel = [[NSArray alloc]initWithArray:data];
NSMutableDictionary * temp_Dict = [[NSMutableDictionary alloc]init];
for (int i = 0 ; i < arr_Parcel.count; i++)
{
temp_Dict = [arr_Parcel objectAtIndex:i];
NSString * strHeight = [temp_Dict objectForKey:"height"];
NSString * strdate = [temp_Dict objectForKey:"datetime"];
}
If you are using Swift, use SwiftJSON to work with JSON.
It's easy to use. For example:
var jsonData = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
let json = JSON(data: jsonData)
print(json["height"].double) // 2
print(json["datatime"].string) // "2015-08-31 21:48:45"
...
Create a NSObject Class and pass the NSDictionary the make a model class.
In your ViewController Class:
" parcel" is your Array
ModelClass * modelClass = [ModelClass alloc] initWithNewsDictionary: parcel[0]];
Create needed variables in ModelClass.h Class.
-(id)initWithNewsDictionary:(NSDictionary *)dictionary
{
self = [super init];
if (self) {
self.height = dictionary[#"height"];
self.datetime = dictionary[#"datetime"];
self.invoice = dictionary[#"invoice"];
self.weight = dictionary[#"weight"];
}
return self;
}
Try this :-
NSString *height=[NSString stringWithFormat:#"%#",[[[YourJson valueForKey:#"parcel"] objectAtIndex:0] objectForKey:#"height"]];
NSString *dateTime=[NSString stringWithFormat:#"%#",[[[YourJson valueForKey:#"parcel"] objectAtIndex:0] objectForKey:#"datetime"]];
NSString *invoice=[NSString stringWithFormat:#"%#",[[[YourJson valueForKey:#"parcel"] objectAtIndex:0] objectForKey:#"invoice"]];
NSLog(#"height : %# , date=%# ,invoice=%#",height,dateTime,invoice);

Downloading calendar data in Objective-C

I am trying to download google calendar data.
I am following a tutorial this link according to which implementing some of the GoogleOAuth delegate methods will let me get my desired data.
First I converted the response JSON data into an NSDictionary object and after that, I, NSLog this dictionary, to see the way the returned data is formed which is as shown below.
calendarInfoDict is {
etag = "\"1436255371893000\"";
items = (
{
accessRole = owner;
backgroundColor = "#9a9cff";
colorId = 17;
defaultReminders = (
{
method = popup;
minutes = 30;
}
);
etag = "\"1436255371893000\"";
foregroundColor = "#000000";
id = "sabiranthapa#gmail.com";
kind = "calendar#calendarListEntry";
notificationSettings = {
notifications = (
{
method = email;
type = eventCreation;
},
{
method = email;
type = eventChange;
},
{
method = email;
type = eventCancellation;
},
{
method = email;
type = eventResponse;
}
);
};
primary = 1;
selected = 1;
summary = "sabiranthapa#gmail.com";
timeZone = "Asia/Calcutta";
},
{
accessRole = reader;
backgroundColor = "#92e1c0";
colorId = 13;
defaultReminders = (
);
description = "Displays birthdays of people in Google Contacts and optionally \"Your Circles\" from Google+. Also displays anniversary and other event dates from Google Contacts, if applicable.";
etag = "\"1436255358367000\"";
foregroundColor = "#000000";
id = "#contacts#group.v.calendar.google.com";
kind = "calendar#calendarListEntry";
summary = Birthdays;
timeZone = "Asia/Calcutta";
}
);
kind = "calendar#calendarList";
nextSyncToken = 00001436255371893000;
}
According to tutorial there is a block containing a bunch of information regarding every calendar I have created in Google Calendars inside curly bracket. But I am not getting any events that I have saved which can be seen in Google Calendar after signing in gmail but not in my apps where I need to work with it.
My code is
-(void)responseFromServiceWasReceived:(NSString *)responseJSONAsString andResponseJSONAsData:(NSData *)responseJSONAsData{
NSError *error;
if ([responseJSONAsString rangeOfString:#"calendarList"].location != NSNotFound) {
NSDictionary *calendarInfoDict = [NSJSONSerialization JSONObjectWithData:responseJSONAsData options:NSJSONReadingMutableContainers error:&error];
NSLog(#"calendarInfoDict is %#", calendarInfoDict);
if (error) {
NSLog(#"%#", [error localizedDescription]);
}
else{
NSArray *calendarsInfo = [calendarInfoDict objectForKey:#"items"];
if (_arrGoogleCalendars == nil) {
_arrGoogleCalendars = [[NSMutableArray alloc] init];
}
for (int i=0; i<[calendarsInfo count]; i++) {
NSDictionary *currentCalDict = [calendarsInfo objectAtIndex:i];
NSArray *values = [NSArray arrayWithObjects:[currentCalDict objectForKey:#"id"],
[currentCalDict objectForKey:#"summary"],
nil]; NSArray *keys = [NSArray arrayWithObjects:#"id", #"summary", nil];
[_arrGoogleCalendars addObject:
[[NSMutableDictionary alloc] initWithObjects:values forKeys:keys]];
}
_dictCurrentCalendar = [[NSDictionary alloc] initWithDictionary:[_arrGoogleCalendars objectAtIndex:0]];
[_barItemPost setEnabled:YES];
[_barItemRevokeAccess setEnabled:YES];
[self showOrHideActivityIndicatorView];
But I always end up with condition
if (_arrGoogleCalendars == nil) {
_arrGoogleCalendars = [[NSMutableArray alloc] init];
}
without able to access my events.
How can I download (or access) my Events from google calendar?

Determine which time is next from a list of times

I have a JSON request which gives prayer times. How can I use Objective-C to work out which is next? The JSON looks like this:
{
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;
};
}
My code so far is:
-(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 asr: %#", [element objectForKey:#"asr"]);
}
}
}
How can I get the current time and determine which prayer comes next?
Thank you!
You need to get the 'items' dictionary using [result objectForKey:#"items"]. Then convert the string values to NSDate's using an NSDateFormatter. Then, iterate through the new dictionary and find the time with the smallest time interval to now using [currentDate timeIntervalSinceNow]. This is your next prayer.
Get a list of the dates, then use an NSPredicate to filter that list to dates >= [NSDate date], then sort it ascending. Then the first item in the filtered, sorted array will be the next date.
Read Apple's Date and Time Programming Guide. You will find methods to convert you string times ("2:15am" etc.) into NSDate objects, methods to get the current date and time (e.g. [NSDate new] return the current date and time), and methods for comparing date/times so you can find the next one.

Resources