Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ xcuserdata
Icon
.Spotlight-V100
.Trashes
.*.sw*

#
# Misc
Expand All @@ -45,4 +46,4 @@ Icon
# GitTower
#

/Icon.png
/Icon.png
5 changes: 4 additions & 1 deletion Classes/MWFeedInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,15 @@
NSString *link; // Feed link
NSString *summary; // Feed summary / description
NSURL *url; // Feed url

NSMutableDictionary *rawTexts; // raw data
NSMutableDictionary *rawAttrs; // raw data
}

@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *link;
@property (nonatomic, copy) NSString *summary;
@property (nonatomic, copy) NSURL *url;
@property (nonatomic, copy) NSMutableDictionary *rawTexts;
@property (nonatomic, copy) NSMutableDictionary *rawAttrs;

@end
12 changes: 12 additions & 0 deletions Classes/MWFeedInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@
@implementation MWFeedInfo

@synthesize title, link, summary, url;
@synthesize rawTexts, rawAttrs;

- (id)init
{
self = [super init];
if (self)
{
rawTexts = [[NSMutableDictionary alloc] init];
rawAttrs = [[NSMutableDictionary alloc] init];
}
return self;
}

#pragma mark NSObject

Expand Down
5 changes: 4 additions & 1 deletion Classes/MWFeedItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
// length: how big it is in bytes (NSNumber)
// type: what its type is, a standard MIME type (NSString)
NSArray *enclosures;

NSMutableDictionary *rawTexts; // raw data
NSMutableDictionary *rawAttrs; // raw data
}

@property (nonatomic, copy) NSString *identifier;
Expand All @@ -58,5 +59,7 @@
@property (nonatomic, copy) NSString *content;
@property (nonatomic, copy) NSString *author;
@property (nonatomic, copy) NSArray *enclosures;
@property (nonatomic, copy) NSMutableDictionary *rawTexts;
@property (nonatomic, copy) NSMutableDictionary *rawAttrs;

@end
12 changes: 12 additions & 0 deletions Classes/MWFeedItem.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@
@implementation MWFeedItem

@synthesize identifier, title, link, date, updated, summary, content, author, enclosures;
@synthesize rawTexts, rawAttrs;

- (id)init
{
self = [super init];
if (self)
{
rawTexts = [[NSMutableDictionary alloc] init];
rawAttrs = [[NSMutableDictionary alloc] init];
}
return self;
}

#pragma mark NSObject

Expand Down
5 changes: 4 additions & 1 deletion Classes/MWFeedParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ typedef enum { FeedTypeUnknown, FeedTypeRSS, FeedTypeRSS1, FeedTypeAtom } FeedTy
// Whether parsing is in progress
@property (nonatomic, readonly, getter=isParsing) BOOL parsing;

// Allow user to access raw data for feed info and items for ATOM feeds
@property (nonatomic, readonly, getter=isParsing) BOOL enableRawAtom;

#pragma mark Public Methods

// Init MWFeedParser with a URL string
Expand All @@ -143,4 +146,4 @@ typedef enum { FeedTypeUnknown, FeedTypeRSS, FeedTypeRSS1, FeedTypeAtom } FeedTy
// Returns the URL
- (NSURL *)url;

@end
@end
44 changes: 41 additions & 3 deletions Classes/MWFeedParser.m
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ @implementation MWFeedParser
@synthesize feedParseType, feedParser, currentPath, currentText, currentElementAttributes, item, info;
@synthesize pathOfElementWithXHTMLType;
@synthesize stopped, failed, parsing;
@synthesize enableRawAtom;

#pragma mark -
#pragma mark NSObject
Expand All @@ -63,7 +64,8 @@ - (id)init {

// Defaults
feedParseType = ParseTypeFull;
connectionType = ConnectionTypeSynchronously;
connectionType = ConnectionTypeAsynchronously;
enableRawAtom = YES;

// Date Formatters
// Good info on internet dates here: http://developer.apple.com/iphone/library/qa/qa2010/qa1480.html
Expand Down Expand Up @@ -658,15 +660,51 @@ - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
else if ([currentPath isEqualToString:@"/feed/entry/dc:creator"]) { if (processedText.length > 0) item.author = processedText; processed = YES; }
else if ([currentPath isEqualToString:@"/feed/entry/published"]) { if (processedText.length > 0) item.date = [NSDate dateFromInternetDateTimeString:processedText formatHint:DateFormatHintRFC3339]; processed = YES; }
else if ([currentPath isEqualToString:@"/feed/entry/updated"]) { if (processedText.length > 0) item.updated = [NSDate dateFromInternetDateTimeString:processedText formatHint:DateFormatHintRFC3339]; processed = YES; }

if (self.enableRawAtom) {
if (currentText.length > 0) {
NSString* text = [NSString stringWithString:currentText];
item.rawTexts[currentPath] = text;
}
if (currentElementAttributes.count > 0) {
if (item.rawAttrs[currentPath] == nil) {
item.rawAttrs[currentPath] = currentElementAttributes;
} else if ([item.rawAttrs[currentPath] isKindOfClass:NSArray.class]) {
[item.rawAttrs[currentPath] addObject:currentElementAttributes];
} else {
NSDictionary* attr = item.rawAttrs[currentPath];
item.rawAttrs[currentPath] = [NSMutableArray arrayWithObjects:attr, currentElementAttributes, nil];
}
}
}
}

// Info
if (!processed && feedParseType != ParseTypeItemsOnly) {
if ([currentPath isEqualToString:@"/feed/title"]) { if (processedText.length > 0) info.title = processedText; processed = YES; }
else if ([currentPath isEqualToString:@"/feed/description"]) { if (processedText.length > 0) info.summary = processedText; processed = YES; }
else if ([currentPath isEqualToString:@"/feed/link"]) { [self processAtomLink:currentElementAttributes andAddToMWObject:info]; processed = YES;}

if (self.enableRawAtom) {
if (currentText.length > 0) {
NSString* text = [NSString stringWithString:currentText];
info.rawTexts[currentPath] = text;
}
if (currentElementAttributes.count > 0) {
if (info.rawAttrs[currentPath] == nil) {
info.rawAttrs[currentPath] = currentElementAttributes;
} else if ([info.rawAttrs[currentPath] isKindOfClass:NSArray.class]) {
[info.rawAttrs[currentPath] addObject:currentElementAttributes];
} else {
NSDictionary* attr = info.rawAttrs[currentPath];
info.rawAttrs[currentPath] = [NSMutableArray arrayWithObjects:attr, currentElementAttributes, nil];
}
}
}
}


// NSLog(@"ATOM raw: %@\n%@\n%@", currentPath, currentText, currentElementAttributes);

break;
}
default: break;
Expand Down Expand Up @@ -946,4 +984,4 @@ - (BOOL)processAtomLink:(NSDictionary *)attributes andAddToMWObject:(id)MWObject
return NO;
}

@end
@end
9 changes: 7 additions & 2 deletions Classes/RootViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ - (void)viewDidLoad {
// Parse
// NSURL *feedURL = [NSURL URLWithString:@"http://images.apple.com/main/rss/hotnews/hotnews.rss"];
// NSURL *feedURL = [NSURL URLWithString:@"http://feeds.mashable.com/Mashable"];
NSURL *feedURL = [NSURL URLWithString:@"http://techcrunch.com/feed/"];
// NSURL *feedURL = [NSURL URLWithString:@"http://techcrunch.com/feed/"];
NSURL *feedURL = [NSURL URLWithString:@"https://gdata.youtube.com/feeds/api/playlists/PLvEIxIeBRKSjprrvlbAcbVjzHsnH9PjDX?v=2"];
feedParser = [[MWFeedParser alloc] initWithFeedURL:feedURL];
feedParser.delegate = self;
feedParser.feedParseType = ParseTypeFull; // Parse feed info and all items
Expand Down Expand Up @@ -99,12 +100,16 @@ - (void)feedParserDidStart:(MWFeedParser *)parser {

- (void)feedParser:(MWFeedParser *)parser didParseFeedInfo:(MWFeedInfo *)info {
NSLog(@"Parsed Feed Info: “%@”", info.title);
//NSLog(@"Parsed Feed Info texts: “%@”", info.rawTexts);
//NSLog(@"Parsed Feed Info attrs: “%@”", info.rawAttrs);
self.title = info.title;
}

- (void)feedParser:(MWFeedParser *)parser didParseFeedItem:(MWFeedItem *)item {
NSLog(@"Parsed Feed Item: “%@”", item.title);
if (item) [parsedItems addObject:item];
//NSLog(@"Parsed Feed Item texts: “%@”", item.rawTexts);
NSLog(@"Parsed Feed Item attrs: “%@”", item.rawAttrs);
if (item) [parsedItems addObject:item];
}

- (void)feedParserDidFinish:(MWFeedParser *)parser {
Expand Down
4 changes: 1 addition & 3 deletions MWFeedParser.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@
29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0420;
LastUpgradeCheck = 0610;
ORGANIZATIONNAME = "Michael Waterfall";
};
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "MWFeedParser" */;
Expand Down Expand Up @@ -317,7 +317,6 @@
C01FCF4F08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
CLANG_ENABLE_OBJC_ARC = NO;
CODE_SIGN_IDENTITY = "";
GCC_C_LANGUAGE_STANDARD = c99;
Expand All @@ -333,7 +332,6 @@
C01FCF5008A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
CLANG_ENABLE_OBJC_ARC = NO;
CODE_SIGN_IDENTITY = "";
GCC_C_LANGUAGE_STANDARD = c99;
Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
I'm working on YouTube feed parsing and I'd like to add support for some extra fields as rawTexts and rawAttrs.

Documents: https://developers.google.com/youtube/2.0/developers_guide_protocol_playlists
Example: https://gdata.youtube.com/feeds/api/playlists/PLvEIxIeBRKSjprrvlbAcbVjzHsnH9PjDX?v=2

For example:
- let sub = info.rawTexts["/feed/subtitle"] as String?
- let url = item.rawAttrs["/feed/entry/media:group/media:thumbnail"]?[2]?["url"] as String?

# MWFeedParser — An RSS and Atom web feed parser for iOS

MWFeedParser is an Objective-C framework for downloading and parsing RSS (1.* and 2.*) and Atom web feeds. It is a very simple and clean implementation that reads the following information from a web feed:
Expand Down Expand Up @@ -221,4 +230,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
THE SOFTWARE.