Splitting Up Nerdfeed - not working


#1

xxx


#2

Do you mean the book example does not work? Or are you having difficulty with the bronze challenge?

One issue I discovered with the example is that the RSS item title nodes are not always formatted as explained in the book:

<::><::>

So using the Regular expression /.* :: (.) :: ./ does not always split the title as expected and some of the items’ titles on the listview are not correct. The issue is that some of the titles are truncated. There seems to be a character limit on the RSS item title field and some of the entries that have long titles are formatted like this:

<::><…>

These entries do not return a match from running the regular expression on the title and you end up with the whole original title entry as the RSSItem.title value. To alleviate this I came up with the following solution which I post here in whole as the solution for the bronze challenge:

First off, add a subforum property to the RSSItem header and synthesize it in the implementation file:

@property (nonatomic, strong) NSString *subforum;
...
@synthesize subforum;

Then in the RSSChannel implementation file modify trimTitles as follows:

-(void)trimItemTitles {
	// MOST RSS Item titles follow this pattern:
	NSRegularExpression *normalTitleReg = [[NSRegularExpression alloc] initWithPattern:@"(.*) :: (.*) :: .*" options:0 error:nil];
	// Some are truncated and follow this pattern:
	NSRegularExpression *truncatedTitleReg = [[NSRegularExpression alloc] initWithPattern:@"(.*) :: (.*)" options:0 error:nil];
	
	// This will hold the item title, matches, result and range:
	NSString				*itemTitle;
	NSArray					*matches;
	NSTextCheckingResult	*result;
	NSRange					range;
	
	for(RSSItem *i in [self items]) {
		// Grab a copy of the title string:
		itemTitle = [i title];

		// Try to match the normal title expression
		matches = [normalTitleReg matchesInString:itemTitle options:0 range:NSMakeRange(0, [itemTitle length])];
		
		// If there are matches:
		if([matches count] > 0) {
			// Grab the first match:
			result = [matches objectAtIndex:0];
			// There must be 3 ranges, one for the total 
			// pattern and one for each parenthesis group:
			if([result numberOfRanges] == 3) {
				// We want the third match for the title:
				range = [result rangeAtIndex:2];
				[i setTitle:[itemTitle substringWithRange:range]];
				
				// And the second match for the subforum:
				range = [result rangeAtIndex:1];
				[i setSubforum:[itemTitle substringWithRange:range]];
			}
		} else if([matches count] == 0) { // If there were no matches, then we got a truncated title...
			// Try to match the truncated expression: 
			matches = [truncatedTitleReg matchesInString:itemTitle options:0 range:NSMakeRange(0, [itemTitle length])];
			// If there are matches, repeat as above...
			if([matches count] > 0) {
				// Grab the first match:
				result = [matches objectAtIndex:0];
				// There must be 3 ranges, one for the total 
				// pattern and one for each parenthesis group:
				if([result numberOfRanges] == 3) {
					// We want the third match for the title:
					range = [result rangeAtIndex:2];
					[i setTitle:[itemTitle substringWithRange:range]];
					
					// And the second match for the subforum:
					range = [result rangeAtIndex:1];
					[i setSubforum:[itemTitle substringWithRange:range]];
				}
			}
		}
	}
}

Finally, in the implementation file of ListViewController, set the item’s subforum by modifying tableView:cellForRowAtIndexPath:

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
	
	UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
	
	if(cell == nil) {
		cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"UITableViewCell"];
	}
	
	RSSItem *item = [[channel items] objectAtIndex:[indexPath row]];
	
	[[cell textLabel] setText:[item title]];
	[[cell detailTextLabel] setText:[item subforum]];
	
	return cell;
}

That takes care of the weird splitting issues in the example / challenge.