Method not working on second time through: SVPullToRefresh - ios

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.

Related

How to save only time zone without GMT?

I am using this code for getting time zone
NSMutableArray *arrResult = [NSMutableArray new];
NSDateFormatter *dateFormatter = [NSDateFormatter new];
NSDate *myDate = [NSDate date];
[dateFormatter setDateStyle:NSDateFormatterLongStyle];
[dateFormatter setTimeStyle:NSDateFormatterLongStyle];
[dateFormatter setDateFormat:#"ZZZ"];
[[NSTimeZone knownTimeZoneNames] enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:obj];
[dateFormatter setTimeZone:timeZone];
NSString *dateString = [dateFormatter stringFromDate: myDate];
NSMutableString *mu = [NSMutableString stringWithString:dateString];
[mu insertString:#":" atIndex:3];
NSString *strResult = [NSString stringWithFormat:#"(GMT%#)%#",mu,obj];
[arrResult addObject:strResult];
}];
NSLog(#"%#", arrResult);
the response of this code is like this as what i want
"(GMT+01:00)Africa/Libreville",
"(GMT+00:00)Africa/Lome",
"(GMT+01:00)Africa/Luanda",
"(GMT+02:00)Africa/Lubumbashi",
"(GMT+02:00)Africa/Lusaka",
"(GMT+01:00)Africa/Malabo",
"(GMT+02:00)Africa/Maputo",
"(GMT+02:00)Africa/Maseru",
"(GMT+02:00)Africa/Mbabane",
"(GMT+03:00)Africa/Mogadishu",
"(GMT+00:00)Africa/Monrovia",
"(GMT+03:00)Africa/Nairobi",
"(GMT+01:00)Africa/Ndjamena",
"(GMT+01:00)Africa/Niamey",
"(GMT+00:00)Africa/Nouakchott",
"(GMT+00:00)Africa/Ouagadougou",
"(GMT+01:00)Africa/Porto-Novo",
"(GMT+00:00)Africa/Sao_Tome",
"(GMT+02:00)Africa/Tripoli",
"(GMT+01:00)Africa/Tunis",
i have to show this type in my label
but what i have to do is when we click on save only (Africa/Tripoli) this part in the database will be saved , i am not getting how to do this .
please help me
If you don't want (GMT+01:00) this bracket in list then you can make string like,
NSString *strResult = [NSString stringWithFormat:#"%#",obj];
[arrResult addObject:strResult];
So, that bracket part will not come.
If you want that bracket part and name both together also for different task then you can make another array called arrResult2 and make another string called strResult2 and do as i mentioned above.
So, you have two arrays. one(arrResult) have both that bracket and names and one(arrResult2) have names only.
If you want to separate string then,
NSString *str = #"(GMT+00:00)Africa/Lome";
NSString *newStr = [str substringFromIndex:11];
NSLog(#"new str : %#",newStr);
I found that every string have closing bracket at 11th index, so you can use it to get sub string from original one.
Hope this will help :)
I got the answer after many try if anyone want this then see here:-
NSString *zoneString = #"(GMT+13:00)Pacific/Tongatapu"
NSUInteger location = [zoneString rangeOfString:#")"].location+1;
NSLog(#"Trimed string:%#",[zoneString substringFromIndex:location]);
Trimed string:Pacific/Tongatapu

how to seperate '72250' in 72 hr and 250 min in objective c?

Actually I got time interval as 750, so I want split-up in hours and minutes. I was trying but still unable to get. I did following code.
NSTimeInterval interval = 750;
NSDateComponentsFormatter *componentFormatter = [[NSDateComponentsFormatter alloc] init];
componentFormatter.unitsStyle = NSDateComponentsFormatterUnitsStylePositional;
componentFormatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorDropAll;
NSString *formattedString = [componentFormatter stringFromTimeInterval:interval];
NSLog(#"%#",formattedString);
I think this will help you
- (NSString *)timeInteralToString:(NSTimeInterval)interval {
NSInteger ti = (NSInteger)interval;
NSInteger seconds = ti % 60;
NSInteger minutes = (ti / 60) % 60;
NSInteger hours = (ti / 3600);
return [NSString stringWithFormat:#"%02ld:%02ld", (long)hours, (long)minutes];
}
This Works Correctly:
NSString *value1 = #"7570"; //This is Value
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
numberFormatter.usesGroupingSeparator = YES;
[numberFormatter setLocale:[NSLocale localeWithLocaleIdentifier:#" "]];
NSString *formatted = [NSString stringWithFormat: #"%#", [value1 substringWithRange:NSMakeRange(0,2)] ];
NSString *str=[formatted stringByAppendingString:#"hr"];
NSString *formatted2 = [NSString stringWithFormat: #"%#", [value1 substringWithRange:NSMakeRange(2,2)]];
NSString *str2=[formatted2 stringByAppendingString:#"mm"];
NSLog(#"%#",[str stringByAppendingString:str2]);

Unable to get the receive messages in chat screen in xmpp

I am making an app based on chatting i am able to send the messages but unable to recieve messages in my chat screen so can any body help me out
here is my code
if ([[message elementForName:#"body"] stringValue]==nil) {
}
else
{
NSString *messageBody = [[message elementForName:#"body"] stringValue];
XMPPUserCoreDataStorageObject *user = [xmppRosterStorage userForJID:[message from]
xmppStream:xmppStream
managedObjectContext:[self managedObjectContext_roster]];
NSString *displayName = [user displayName];
BOOL isComposing = NO;
NSString *MyString;
NSDate *now = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
// [dateFormatter setDateFormat:#"yyyy-MM-dd-HH-mm-ss"];
[dateFormatter setDateFormat:#"HH:mm,yyyy/MM/dd"];
MyString = [dateFormatter stringFromDate:now];
NSLog(#"TIME AND DATE=>%#",MyString);
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
NSString *myJID=[NSString stringWithFormat:#"%##xxxx-mac-mini-2.local",[defaults valueForKey:#"userNameJID"]];
NSString *friendID=[[[message attributeForName:#"from"] stringValue] stringByDeletingLastPathComponent];
NSLog(#"---chatToUserId=>%#",friendID);
if ([message isChatMessageWithBody]){
XMPPUserCoreDataStorageObject *user = [xmppRosterStorage userForJID:[message from]
xmppStream:xmppStream
managedObjectContext:[self managedObjectContext_roster]];
NSString *body = [[message elementForName:#"body"] stringValue];
NSString *displayName = [user displayName];
NSString *msg = [[message elementForName:#"body"] stringValue];
NSString *from = [[message attributeForName:#"from"] stringValue];
// [xmppMessageArchivingStorage archiveMessage:message outgoing:NO xmppStream:xmppStream];
NSMutableDictionary *m = [[NSMutableDictionary alloc] init];
[m setObject:msg forKey:#"msg"];
[m setObject:from forKey:#"sender"];}
in xmpp delegate method that is didReceiveMessage but how can i assign to chat screen class.
You need to learn:
XMPPMessageArchiving is an example module bundled with XMPPFramework which store all incoming and outgoing messages to CoreData-backed database.
NSFetchedResultsController - standard Apple-provided class for feeding data to UITableView or UICollectionView, which you can use as core of "chat screen" class and it will automatically track new messages and update UI.
Sample iPhoneXMPP project have an example of "roster screen" which is backed by UITableView and NSFRC, the only two differences of "chat screen" are:
You need to fetch XMPPMessageArchiving_Message_CoreDataObject entities
You need to specify NSPredicate to fetch only messages related to single "chat", something like bareJid == %# and pass buddy's JID to this predicate

Handle Foursquare hours API to find out if the venue is opened or closed

I have a foursquare hours array (Foursquare API) that stores segments of hours when a specific venue is open. It looks something like this:
[{
"days":[1,2,3,4,7],
"includesToday":true,
"open":[
{"end":"+0200","start":"1000"}],
"segments":[]},
{
"days":[5,6]
,"open":[
{"end":"+0300","start":"1000"}],
"segments":[]}
]
How do I find out if the venue is opened or closed at current time?
I handle it like this: 4sq hours API gist
-(NSDictionary*)isVenueOpenDictionaryForHours:(NSArray*)hours{
// defaults and inits
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDictionary *lastSegmentYesterday = [[NSDictionary alloc] init];
NSDate *dateNow = [NSDate date];
NSString *venueOpenText = [[NSString alloc] init];
NSString *venueOpen = #"no";
// get components for today
NSDateComponents *compsNow = [gregorian components:NSWeekdayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:dateNow];
// get weekday for today and yesterday so we can lookup 4sq API
NSInteger weekday = [compsNow weekday];
NSInteger weekdayYesterday = (weekday>1)?weekday-1:7;
// look for todays' segment
NSMutableArray *venueOpenSegments = [[NSMutableArray alloc] init]; // stores all the segments when the venue is open
for (NSDictionary *segment in hours){
// get today's segment (if it exists)
if ([segment[#"days"] containsObject:[NSNumber numberWithInteger:weekday]]){
for (NSDictionary *dictOpen in segment[#"open"])
[venueOpenSegments insertObject:#{#"end": [dictOpen[#"end"] mutableCopy], #"start":[dictOpen[#"start"] mutableCopy]}.mutableCopy atIndex:venueOpenSegments.count];
}
// check the day before if the venue is open past midnight
if (([segment[#"days"] containsObject:[NSNumber numberWithInteger:weekdayYesterday]] && [segment[#"open"] count])){
// get the last segment (that should be the one passing midnight)
NSDictionary *tempSegment = [segment[#"open"] lastObject];
// if it has more than 4 characters it's after midnight ("+02:00"), also, ignore if it closes at midnight
if ([tempSegment[#"end"] length] > 4 && ![tempSegment[#"end"]isEqualToString:#"+0000"]){
// create a new segment that starts at midnight and lasts till the time it closes (early AMs usually)
lastSegmentYesterday = #{#"start":#"0000", #"end":[tempSegment[#"end"] substringFromIndex:1]};
}
}
}
// add last night segment that passes midnight as the first segment of today
if (lastSegmentYesterday.count){
[venueOpenSegments insertObject:lastSegmentYesterday atIndex:0];
}
// go through all the segments and find out if the venue is closed or open
if (venueOpenSegments.count){
NSDateComponents *comps = [[NSDateComponents alloc] init];
NSDateFormatter *timeFormatter = [[NSDateFormatter alloc]init];
timeFormatter.dateFormat = #"HH:mm"; // set time output format
int segmentNumber = 0;
for (NSMutableDictionary *segment in venueOpenSegments){
segmentNumber++;
// confing start date
[comps setDay:compsNow.day];
[comps setMonth:compsNow.month];
[comps setYear:compsNow.year];
[comps setHour:[[segment[#"start"] substringToIndex:2] intValue]];
[comps setMinute:[[segment[#"start"] substringFromIndex:2] intValue]];
NSDate *dateStart = [[[NSCalendar currentCalendar] dateFromComponents:comps] copy];
// config end date
// check if the segment goes to next day
BOOL closesTomorrow = NO;
if ( [segment[#"end"] length]==5 ){
segment[#"end"] = [segment[#"end"] substringFromIndex:1];
closesTomorrow = YES;
}
[comps setHour:[[segment[#"end"] substringToIndex:2] intValue]];
[comps setMinute:[[segment[#"end"] substringFromIndex:2] intValue]];
NSDate *dateEnd = [[[NSCalendar currentCalendar] dateFromComponents:comps] copy];
// add a day if it closes tomorrow
if (closesTomorrow){
NSDateComponents *nextDayComponent = [[NSDateComponents alloc] init];
nextDayComponent.day = 1;
dateEnd = [gregorian dateByAddingComponents:nextDayComponent toDate:dateEnd options:0];
}
// start checking if it's open or closed
// now < segment start
if ([dateNow compare:dateStart] == NSOrderedAscending){
venueOpenText = [NSString stringWithFormat:#"opens at %#",[timeFormatter stringFromDate: dateStart]];
venueOpen = #"later";
break;
}
// segment end < now
else if ([dateEnd compare:dateNow] == NSOrderedAscending){
if (segmentNumber == venueOpenSegments.count){
venueOpenText = [NSString stringWithFormat:#"closed since %#",[timeFormatter stringFromDate: dateEnd]];
break;
}
continue;
}
// segment start < now < segment end
else if ([dateStart compare:dateNow] == NSOrderedAscending && [dateNow compare:dateEnd] == NSOrderedAscending){
venueOpenText = [NSString stringWithFormat:#"open till %#",[timeFormatter stringFromDate: dateEnd]];
venueOpen = #"yes";
break;
}
// rare but possible... last minute of the venue being open (I treat it as closed)
else {
venueOpenText = #"closing right now";
}
}
}
else venueOpen = #"closed today"; // no segments for today, so it's closed for the dayæ
// return results
return #{#"open":venueOpen, #"string":venueOpenText};
}
and I update my UILabel like this:
NSDictionary *venueOpen = [self isVenueOpenDictionaryForHours:_arrayVenues[indexPath.row][#"hours"]];
label.text = venueOpen[#"string"];
if ([venueOpen[#"open"] isEqualToString:#"no"]){
label.textColor = [UIColor colorWithHexString:#"b91d47" alpha:1]; // red
} else if ([venueOpen[#"open"] isEqualToString:#"yes"]) {
label.textColor = [UIColor colorWithHexString:#"1e7145" alpha:1]; // green
} else if ([venueOpen[#"open"] isEqualToString:#"later"]) {
label.textColor = [UIColor colorWithHexString:#"e3a21a" alpha:1]; // yellow
}
BTW, I use pod 'HexColors' for colorWithHexString methods

Chronologically organize Cells in TableView

I have two UITableViewCell's that each correspond to a Twitter Tweet or a Instagram Pic. As of now I have set it so that It will alternate between the two cells and have It go from an Twitter Tweet to an Instagram Pic. However I want to organize the UITableView so that it organizes both the Twitter Tweets and Instagram Pics chronologically in the TableView. Both the date keys for the Instagram API and the Twitter API are different. The Twitter API has a time key of created_at and Instagram's key is created_time. How would I organize both these Arrays? P.S. Both the arrays which the Tweets and Pics are in are NSMutableArray's.
Here is the Code that I have tried thus far:
// Setup for Cells
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *twitterCell = [self createTwitterCell:indexPath];
UITableViewCell *instagramCell = [self createInstagramCell:indexPath];
if (indexPath.row % 2 == 0) {
return twitterCell;
}else{
return instagramCell;
}
}
// Array Updater
- (void)updateArrays {
instaPics = self.timelineResponse[#"data"];
totalFeed = [tweets arrayByAddingObjectsFromArray:instaPics];
[self sortArrayBasedOndate:totalFeed];
}
// Current flawed method to organize by date
- (void)sortArrayBasedOndate {
NSDateFormatter *fmtDate = [[NSDateFormatter alloc] init];
[fmtDate setDateFormat:#"yyyy-MM-dd"];
NSDateFormatter *fmtTime = [[NSDateFormatter alloc] init];
[fmtTime setDateFormat:#"HH:mm"];
NSComparator compareDates = ^(id string1, id string2)
{
// Instagram Date Retrieval
NSDictionary *instagram = self.instaPics;
NSString *createdAt = instagram[#"created_time"];
int createdAtN = [createdAt intValue];
NSTimeInterval timestamp = (NSTimeInterval)createdAtN;
NSDate *date1 = [NSDate dateWithTimeIntervalSince1970:timestamp];
// Twitter Date Retrieval
NSDictionary *twitter = self.tweets;
NSDate *date2 = twitter[#"created_at"];
return [date1 compare:date2];
};
NSSortDescriptor * sortDesc1 = [[NSSortDescriptor alloc] initWithKey:#"start_date" ascending:YES comparator:compareDates];
[totalFeed sortUsingDescriptors:#[sortDesc1]];
}
If you guys need any more code excerpts feel free to ask :)
It seems like you're on the right track. Why don't you also format Twitter's time to match your formatting for Instagram's time?
NSComparator compareDates = ^(id string1, id string2)
{
// Instagram Date Retrieval
NSDictionary *instagram = self.instaPics;
NSString *createdAt = instagram[#"created_time"];
int createdAtN = [createdAt intValue];
NSTimeInterval timestamp = (NSTimeInterval)createdAtN;
NSDate *date1 = [NSDate dateWithTimeIntervalSince1970:timestamp];
// Twitter Date Retrieval
NSDictionary *twitter = self.tweets;
NSString *twitterCreated = twitter[#"created_at"];
int createdAtTwitter = [twitterCreated intValue];
NSTimeInterval timestampTwitter = (NSTimeInterval)createdAtTwitter;
NSDate *date2 = [NSDate dateWithTimeIntervalSince1970:timestampTwitter];
return [date1 compare:date2];
};

Resources