Create Events for MBCalendarKit in iOS - ios

I imported MBCalendar Kit into my project, and I don't know how to add an event or array of events in calendar. I found this code:
NSMutableDictionary *eventsDict = [[NSMutableDictionary alloc] init];
for (int i =0; i< eventsArray.count ;i++)
{
// Create events
eventsDict = eventsArray[i];
CKCalendarEvent* aCKCalendarEvent = [[CKCalendarEvent alloc] init];
aCKCalendarEvent.title = [eventsDict objectForKey:#"email"];
aCKCalendarEvent.date = date; //[eventsArray objectForKey:#"phone"];
aCKCalendarEvent.address = [eventsDict objectForKey:#"addrLine1"];
aCKCalendarEvent.image = [eventsDict objectForKey:#"pPic"];
aCKCalendarEvent.name = [eventsDict objectForKey:#"fname"];
aCKCalendarEvent.appDate = [eventsDict objectForKey:#"apntDt"];
aCKCalendarEvent.notes = [eventsDict objectForKey:#"notes"];
aCKCalendarEvent.phone = [eventsDict objectForKey:#"phone"];
[myeventsArray addObject: aCKCalendarEvent];
}
[_data setObject:myeventsArray forKey:date];
but I don't know where to write it, or how to use it. Can anyone help me?
Thank you.

I'm working with this Framework and I've had the same issues.
What worked for me was to use the NSDate+Components category, specifically the dayWithDay:month:year method to create the dates for the events, then create as many events as you want the way you're doing it, encapsulate all the events that are on the same day in an array and lastly setting that array as an object for the NSDictionary data with the previously created as the key to that array. Here's an example:
NSDate *eventDate1 = [NSDate dateWithDay:8 month:8 year:2014];
NSDate *eventDate2 = [NSDate dateWithDay:9 month:8 year:2014];
CKCalendarEvent *event1 = [CKCalendarEvent eventWithTitle:#"Event 1" andDate:eventDate1 andInfo:nil];
CKCalendarEvent *event2 = [CKCalendarEvent eventWithTitle:#"Event 2" andDate:eventDate2 andInfo:nil];
NSArray *today = [NSArray arrayWithObjects:event1, nil];
NSArray *tomorrow = [NSArray arrayWithObjects:event2, nil];
[[self data] setObject:today forKey:eventDate1];
[[self data] setObject:tomorrow forKey:eventDate2];
Hope this helps :D
I'm working on my own framework based on this but with an iOS7 native feel, it's not finished yet but here is the repo:
https://github.com/AndoniV/CalendarBar_iOS7_Style.git

Related

How to show Single date in multiple events reload in MBCalendarKit

I am using a Calendar view in my project. I am using a MBCalendarKit. That time single date in single event show. But I want single date on multiple events show. But how it possible please help.
- (void) viewWillAppear: (BOOL)animated{
NSArray *title = [_caldevice valueForKey:#"pill"];
// NSLog(#"event name fetch %#",title);
NSArray *date =[_caldevice valueForKey:#"datetaken"];
// NSLog(#"event fetch %#",date);
NSArray*dose= [_caldevice valueForKey:#"dose"];
NSString *title1;
NSString*title2;
NSDate *date1;
NSData *imgdata;
CKCalendarEvent *releaseUpdatedCalendarKit;
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"dd-MM-yyyy";
for (int i = 0; i < [date count]; i++){
title1 = NSLocalizedString(title[i], #"");
title2 = NSLocalizedString(dose[i], #"");
NSString *combined = [NSString stringWithFormat:#"%# - %#", title1, title2];
date1 = [dateFormatter dateFromString:date[i]];
releaseUpdatedCalendarKit = [CKCalendarEvent eventWithTitle:combined andDate:date1 andInfo:Nil];
// NSLog(#"Event: %# , %#",combined,date1);
// releaseUpdatedCalendarKit = [CKCalendarEvent eventWithTitle:combined andDate:date1 andInfo:Nil andColor:[UIColor blueColor]];
self.data[date1] = #[releaseUpdatedCalendarKit];
}
}
You're looping over a bunch of events and for each event, you're *replacing the previously assigned array with a new one, containing a single element.
Replace this:
self.data[date1] = #[releaseUpdatedCalendarKit];
with something more like this:
// 1. First, get the previous events for that day.
NSMutableArray <CKCalendarEvent *> *events = self.data[date1].mutableCopy;
// 2. If events exist, append the event, otherwise create an empty array with the new event.
if (events) {
[events addObject: newEvent];
}
else {
events = #[newEvent];
}
// 3. Set the events for the date key.
self.data[date1] = events;
This way you're doing an "add or create" operation, instead of overwriting each time.
Disclosure: I wrote and maintain MBCalendarKit.

Method not working on second time through: SVPullToRefresh

So, I've made some progress on my issue described here — https://stackoverflow.com/questions/27348458/svpulltorefresh-infinite-scroll-with-an-rss-feed
Nonetheless, I have a problem. The table loads 10 YouTube videos initially. Then, the second ten will load using
__weak MasterViewController *weakSelf = self;
[self.tableView addInfiniteScrollingWithActionHandler:^{
NSLog(#"Infinite Scroll");
[weakSelf updateVideoList];
}];
-(void) updateVideoList essentially adds 10 items to the array that loads into the table view (reloadData is called on the tableview at the end after addObjectsFromArray adds items to the initial array). This works well enough. The problem is that trying to load a third 10 items does not work. I added the NSLog to see if it even goes into the method a second time, and it doesn't.
Is there any reason for the method to not work a second time?
Edit Here's updateVideoList, but I used the log to determine that the method isn't even called the second time through:
- (void) updateVideoList {
NSString *baseDomain = #"https://gdata.youtube.com/feeds/api/videos";
NSString *maxresults = #"10";
NSString *startIndex = [NSString stringWithFormat:#"%lu", (unsigned long)videoList.count+1];
NSString *orderBy = #"published";
NSString *author = #"theverge";
NSString *extension = #"v=2&alt=jsonc";
NSString *urlYoutube = [NSString stringWithFormat:#"%#?max-results=%#&start-index=%#&orderby=%#&author=%#&%#",
baseDomain,maxresults, startIndex,orderBy,author,extension];
NSDictionary *listOfVideos = [JSONParser listOfVideos:urlYoutube];
int videoListSize = [[[listOfVideos valueForKey:#"data"] valueForKey:#"totalItems"] intValue];
if (videoListSize>0) {
NSMutableArray *secondYoutubeList = [[NSMutableArray alloc] init];
NSArray *arrayVideoList = [[listOfVideos valueForKey:#"data"] valueForKey:#"items"];
for (NSDictionary *videoDictionary in arrayVideoList) {
NSString *idVideo = [videoDictionary valueForKey:#"id"];
NSString *description = [videoDictionary valueForKey:#"description"];
//NSString *updated = [videoDictionary valueForKey:#"updated"];
// NSString *departTimeDate = [videoDictionary valueForKey:#"updated"];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
//NSDate *date = [dateFormatter dateFromString:departTimeDate];
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]];
NSInteger day = [components day];
NSInteger month = [components month];
NSInteger year = [components year];
NSString *updated = [NSString stringWithFormat:#"%ld, %ld, %ld", (long)month,(long)day,(long)year];
NSString *duration = [videoDictionary valueForKey:#"duration"];
NSString *title = [videoDictionary valueForKey:#"title"];
// If we are using wifi, take hqDefault
NSString *thumbnail = [[videoDictionary valueForKey:#"thumbnail"] valueForKey:#"hqDefault"];
YoutubeVideo *video = [[YoutubeVideo alloc] initWithId:idVideo withDescription:description withUpdated:updated withDuration:duration withTitle:title withThumbnail:thumbnail];
[secondYoutubeList addObject:video];
}
[videoList addObjectsFromArray:secondYoutubeList];
[self.tableView reloadData];
}
}
You should call
[self.tableView.infiniteScrollingView stopAnimating];
Once your work of reloading is got completed.

How to create a TableView with list [NSTimeZone knownTimeZoneNames]?

My question is in the title. I just want to have the list of all the cities in the world (422 objects) and I have only examples with data written one by one with "add object".
I do hope there is another trick for my lazy fingers !
I have create this but it doesn't match.
NSArray * timeZones = [NSTimeZone knownTimeZoneNames];
maListe = [[NSMutableArray alloc] init];
// création dictionnaire
NSDictionary *tampon = [NSDictionary dictionary];
for (NSString *aLocation in timeZones)
{
NSArray *continentsCountryCity = [aLocation componentsSeparatedByString:#"/"];
if ([continentsCountryCity count] >= 2)
{
NSMutableArray *continentPickerView = [continentsCountryCity objectAtIndex:0];
NSMutableArray *villePickerView = [continentsCountryCity objectAtIndex:1];
[tampon setObject:villePickerView forKey:continentPickerView];
}
}
maListe = tampon.allKeys;
Does anybody have a solution ?
Many thanks for your help.

Why is my array returning null?

I am calling getBoardingCards once here:
BRPBoardingCards *boardingCards = [[BRPBoardingCards alloc] init];
boardingCardsArray = [boardingCards getBoardingCards];
The array is returning null though (in the NSLog shown). What am I doing wrong?
- (NSArray*)getBoardingCards
{
NSMutableArray *storedArray = [[NSMutableArray alloc] init];
Utils *utils = [[Utils alloc] init];
NSUserDefaults *properties = [utils getUserDefaults];
// check if its the first time we are running the app.
if(![[properties objectForKey:#"first_run"] isEqualToString:#"no"]){
//I decided it is for american tourists and every booking office allows payment in dollars because I dont have a euros key on my keyboard.
//Car also has lots of seats. 1337 of them to be precise.
[self setNewBoardingCardWithCardType:#"car" WithPrice:#"$1.50" AndStartLocation:#"airport" AndEndLocation:#"restaurant" WithSeat:#"1337" andExtraInformation:#"We dont like you so we are giving you the back seat by yourself."];
[self setNewBoardingCardWithCardType:#"helicopter" WithPrice:#"$500" AndStartLocation:#"restaurant" AndEndLocation:#"hospital" WithSeat:#"1" andExtraInformation:#"You are driving."];
[self setNewBoardingCardWithCardType:#"train" WithPrice:#"$100" AndStartLocation:#"restaurant" AndEndLocation:#"ditch" WithSeat:#"STANDONHEAD" andExtraInformation:#"No Seats on this train. Gotta stand on your head. Dont forget your white lightning for the ditch."];
[self setNewBoardingCardWithCardType:#"Fire Engine" WithPrice:#"$10" AndStartLocation:#"restaurant" AndEndLocation:#"burning house" WithSeat:#"HOSE" andExtraInformation:#"Take the hose to put out this fire we are heading to. "];
[self setNewBoardingCardWithCardType:#"Nimbus" WithPrice:#"$300" AndStartLocation:#"burning house" AndEndLocation:#"popo floating island" WithSeat:#"LEVITATION" andExtraInformation:#"Dont forget to turn super saiyan on your way up there. "];
[self setNewBoardingCardWithCardType:#"Sky Dive" WithPrice:#"$1020" AndStartLocation:#"popo floating island" AndEndLocation:#"home" WithSeat:#"GRAVITY" andExtraInformation:#"Ohh! that Adrenalines pumping. "];
[self setNewBoardingCardWithCardType:#"Legs" WithPrice:#"$50" AndStartLocation:#"ditch" AndEndLocation:#"park bench hotel" WithSeat:#"VODKA" andExtraInformation:#"Time to get a good nights rest and sobre up. "];
[self setNewBoardingCardWithCardType:#"Bicycle" WithPrice:#"$5" AndStartLocation:#"park bench hotel" AndEndLocation:#"home" WithSeat:#"BIKESEAT1" andExtraInformation:#"What a terrible hangover. Time to head home. "];
[self setNewBoardingCardWithCardType:#"ambulance" WithPrice:#"$40" AndStartLocation:#"hospital" AndEndLocation:#"home" WithSeat:#"LEVITATION" andExtraInformation:#"Well that was a bad idea! "];
[properties setObject:#"no" forKey:#"first_run"];
[properties synchronize];
NSLog(#"did set first run to no");
}
storedArray = [[properties objectForKey:#"cards"] mutableCopy];
NSLog(#"getBoardingCards storedArray: %#", storedArray);
return storedArray;
}
- (NSArray*)getBoardingCardsByType:(NSString*)cardType
{
// at this point i would create a for loop and iterate through the array checking if (type isEqualToString:cardType).
// But this is just an idea for later. To go by only a certain type of route.
return nil;
}
- (void)setNewBoardingCardWithCardType:(NSString*)cardType WithPrice:(NSString*)price AndStartLocation:(NSString*)startLocation AndEndLocation:(NSString*)endLocation WithSeat:(NSString*)seatCode andExtraInformation:(NSString*)extraInfo{
// populate the dictionary with data.
NSMutableDictionary *card = [[NSMutableDictionary alloc] init];
[card setObject:cardType forKey:#"type"];
[card setObject:price forKey:#"price"];
[card setObject:startLocation forKey:#"startLocation"];
[card setObject:endLocation forKey:#"endLocation"];
[card setObject:seatCode forKey:#"seat"];
[card setObject:extraInfo forKey:#"info"];
// get our stored array.
Utils *utils = [[Utils alloc] init];
NSUserDefaults *properties = [utils getUserDefaults];
NSMutableArray *storedArray = [[properties objectForKey:#"cards"] mutableCopy];
[storedArray addObject:card];
// set the stored array.
[properties setObject:storedArray forKey:#"cards"];
[properties synchronize];
}
You're not creating the cards mutable array in the NSUserDefaults.
This line (in setNewBoardingCardWithCardType:):
NSMutableArray *storedArray = [[properties objectForKey:#"cards"] mutableCopy];
is essentially
NSMutableArray *storedArray = [nil mutableCopy];
which is the same as
NSMutableArray *storedArray = nil;
Check if the object for this key exist, if not - create it and then use it.

NSDateFormatter memory leak?

I have a problem with NSDateFormatter dateFromString: method. There is an array of dictionaries with string dates and I want to convert them to NSDates. But there is a huge heap growth every time I call this method (I need to call it more than once, cause it's an "update" method). Also I call it in background thread and ARC is on. What am I doing wrong? Any help, please.
UPDATE:
Full code of the function:
- (GraphController *) initGraphWithData: (NSArray *) points forInterval: (GraphInterval) interval andFrame: (CGRect) frame gestures: (BOOL) gestures secondGraph: (NSArray *) secondPoints graphNames: (NSArray *) graphNames
{
self = [super init];
_calendar = [NSCalendar currentCalendar];
_secondPoints = secondPoints;
_graphNames = graphNames;
[self.view setFrame:frame];
_points = [[NSMutableArray alloc] init];
double minValue = HUGE_VALF, maxValue = -HUGE_VALF;
NSDate *minDate = [NSDate date], *maxDate = [NSDate dateWithTimeIntervalSince1970:0];
NSMutableDictionary *datesTable = [[NSMutableDictionary alloc] init];
int index = 0;
for(NSArray *pointArray in points){
NSDictionary *point = pointArray[0];
NSMutableDictionary *newPoint = [[NSMutableDictionary alloc] initWithDictionary:point];
// convert date
NSString *dateString = (NSString *)[point objectForKey:#"date"];
NSLog(#"dateString to convert: %#", dateString);
[_dateFormatter setDateFormat:#"MM/dd/yyyy"];
NSDate *date = [_dateFormatter dateFromString: dateString];
[newPoint setObject: date forKey:#"date"];
// convert numbers
[newPoint setObject: [NSNumber numberWithFloat:[((NSString *)[point objectForKey:#"value"]) floatValue]] forKey:#"value"];
if(secondPoints)
[newPoint setObject: [NSNumber numberWithFloat:[((NSString *)[secondPoints[index] objectForKey:#"value"]) floatValue]] forKey:#"secondValue"];
[newPoint setObject: [NSNumber numberWithInt:index] forKey:#"index"];
// min and max
if([[newPoint objectForKey:#"value"] floatValue] < minValue)
minValue = [[newPoint objectForKey:#"value"] floatValue];
if([[newPoint objectForKey:#"value"] floatValue] > maxValue)
maxValue = [[newPoint objectForKey:#"value"] floatValue];
// check second value
if(self.secondPoints){
if([[newPoint objectForKey:#"secondValue"] floatValue] < minValue)
minValue = [[newPoint objectForKey:#"secondValue"] floatValue];
if([[newPoint objectForKey:#"secondValue"] floatValue] > maxValue)
maxValue = [[newPoint objectForKey:#"secondValue"] floatValue];
}
if([[newPoint objectForKey:#"date"] timeIntervalSince1970] > [maxDate timeIntervalSince1970])
maxDate = [newPoint objectForKey:#"date"];
if([[newPoint objectForKey:#"date"] timeIntervalSince1970] < [minDate timeIntervalSince1970])
minDate = [newPoint objectForKey:#"date"];
[self.points addObject:newPoint];
[datesTable setObject:newPoint forKey: [[NSNumber numberWithDouble:[date timeIntervalSince1970]] stringValue] ];
index++;
}
// set draw parameters
_drawVars = [[NSMutableDictionary alloc] init];
NSDate *startSearchDate;
switch (interval) {
case GraphIntervalWeek:
startSearchDate = [maxDate dateByAddingTimeInterval:-7*24*3600];
break;
case GraphIntervalMonth:
startSearchDate = [maxDate dateByAddingTimeInterval: -31*24*3600];
break;
case GraphIntervalSixMonths:
startSearchDate = [maxDate dateByAddingTimeInterval:-6*31*24*3600];
break;
case GraphIntervalYear:
startSearchDate = [maxDate dateByAddingTimeInterval:-365*24*3600];
break;
case GraphIntervalAllTime:
break;
default:
break;
}
NSMutableDictionary *searchPoint;
while(searchPoint == nil && [startSearchDate timeIntervalSince1970] > [minDate timeIntervalSince1970]){
searchPoint = [datesTable objectForKey:[[NSNumber numberWithDouble:[startSearchDate timeIntervalSince1970]] stringValue]];
startSearchDate = [startSearchDate dateByAddingTimeInterval:-24*3600];
}
if(searchPoint != nil && interval != GraphIntervalAllTime)
[self.drawVars setObject:[searchPoint objectForKey:#"index"] forKey:#"startDrawIndex"];
else
[self.drawVars setObject:[NSNumber numberWithInt:0] forKey:#"startDrawIndex"];
[self.drawVars setObject:[[NSNumber numberWithFloat:minValue] copy] forKey:#"minValue"];
[self.drawVars setObject:[[NSNumber numberWithFloat:maxValue] copy] forKey:#"maxValue"];
[self.drawVars setObject:minDate forKey:#"minDate"];
[self.drawVars setObject:maxDate forKey:#"maxDate"];
[self.drawVars setObject:datesTable forKey:#"datesTable"];
// set drawImageView
_drawArea = [[UIImageView alloc] initWithFrame: frame];
[self.view addSubview:self.drawArea];
// set overlayImageView for fingerInpect
_inspectOverlay = [[UIImageView alloc] initWithFrame:frame];
[self.view addSubview:self.inspectOverlay];
// set hintUIView for fingerInspect
_hint = [[Hint alloc] initWithFrame:frame];
[self.hint initHint];
self.hint.hidden = YES;
[self.drawArea addSubview:self.hint];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(panHandler:)];
UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressHandler:)];
if(gestures)
[self.view addGestureRecognizer:panRecognizer];
[self.view addGestureRecognizer:longPressRecognizer];
return self;
}
I see you are using Heapshot analysis. Good. Here are some more details:
http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/
Now, hopefully, each one of your Heapshot iterations represents doing something in your app that should return it back to the base state. Opening and closing a document, for example.
If that is the case, your data is showing a 500K-600K growth per iteration. That is quite a bit.
Note that trying to analyze the last iteration is generally useless; many of those objects will exist because of whatever the current state of the app is. You really want to focus on that 2nd or 4th iteration.
As for why that specific date or date formatter is leaking, turn on reference count event tracking and then review the retain/release events for one of the leaked objects. There will be some number of extra retains.
Something you are doing right is init the NSDateFormatter before entering the loop. If you are expecting the same date format (MM/dd/yyyy) you can put in the same place you init it as well. It can be that you are allocating too many objects, so I could advise putting everything inside an #autoreleasepool {} (aka: the content of the loop inside the autorelease).
I am seeing you are allocating the *newPoint inside the for and then you are setting the date to that object. What do you do after?

Resources