diff --git a/.gitignore b/.gitignore index 0feaf30..e4f38e4 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ xcuserdata Icon .Spotlight-V100 .Trashes +.*.sw* # # Misc @@ -45,4 +46,4 @@ Icon # GitTower # -/Icon.png \ No newline at end of file +/Icon.png diff --git a/Classes/MWFeedInfo.h b/Classes/MWFeedInfo.h index 3473071..4b9ceed 100644 --- a/Classes/MWFeedInfo.h +++ b/Classes/MWFeedInfo.h @@ -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 diff --git a/Classes/MWFeedInfo.m b/Classes/MWFeedInfo.m index d762318..4969fc5 100644 --- a/Classes/MWFeedInfo.m +++ b/Classes/MWFeedInfo.m @@ -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 diff --git a/Classes/MWFeedItem.h b/Classes/MWFeedItem.h index 47bea85..1fc5038 100644 --- a/Classes/MWFeedItem.h +++ b/Classes/MWFeedItem.h @@ -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; @@ -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 diff --git a/Classes/MWFeedItem.m b/Classes/MWFeedItem.m index 7ccb7e4..a8f8c57 100644 --- a/Classes/MWFeedItem.m +++ b/Classes/MWFeedItem.m @@ -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 diff --git a/Classes/MWFeedParser.h b/Classes/MWFeedParser.h index d2a8a39..40be5a1 100644 --- a/Classes/MWFeedParser.h +++ b/Classes/MWFeedParser.h @@ -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 @@ -143,4 +146,4 @@ typedef enum { FeedTypeUnknown, FeedTypeRSS, FeedTypeRSS1, FeedTypeAtom } FeedTy // Returns the URL - (NSURL *)url; -@end \ No newline at end of file +@end diff --git a/Classes/MWFeedParser.m b/Classes/MWFeedParser.m index 7d900ad..3c5cfbb 100644 --- a/Classes/MWFeedParser.m +++ b/Classes/MWFeedParser.m @@ -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 @@ -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 @@ -658,6 +660,23 @@ - (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 @@ -665,8 +684,27 @@ - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 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; @@ -946,4 +984,4 @@ - (BOOL)processAtomLink:(NSDictionary *)attributes andAddToMWObject:(id)MWObject return NO; } -@end \ No newline at end of file +@end diff --git a/Classes/RootViewController.m b/Classes/RootViewController.m index f11ac8f..1b71a75 100644 --- a/Classes/RootViewController.m +++ b/Classes/RootViewController.m @@ -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 @@ -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 { diff --git a/MWFeedParser.xcodeproj/project.pbxproj b/MWFeedParser.xcodeproj/project.pbxproj index f7f461c..9ab0e00 100755 --- a/MWFeedParser.xcodeproj/project.pbxproj +++ b/MWFeedParser.xcodeproj/project.pbxproj @@ -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" */; @@ -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; @@ -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; diff --git a/README.md b/README.md index f6e67d4..a49bcd5 100644 --- a/README.md +++ b/README.md @@ -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: @@ -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. \ No newline at end of file +THE SOFTWARE.