From 631ddc906405e3421fbe45177087c5cc3d8163b6 Mon Sep 17 00:00:00 2001 From: relikd Date: Sat, 14 Sep 2019 14:58:11 +0200 Subject: [PATCH] v2.0.0 release; move all docref to header + optional NSXML --- RSXML.xcodeproj/project.pbxproj | 14 ++------------ RSXML/Info.plist | 2 +- RSXML/RSAtomParser.h | 1 + RSXML/RSFeedParser.h | 3 +++ RSXML/RSFeedParser.m | 4 ++-- RSXML/RSHTMLLinkParser.h | 1 + RSXML/RSHTMLMetadata.h | 2 ++ RSXML/RSHTMLMetadata.m | 1 + RSXML/RSHTMLMetadataParser.h | 1 + RSXML/RSOPMLItem.h | 32 ++++++++++++++++++++++---------- RSXML/RSOPMLItem.m | 14 +++++++------- RSXML/RSOPMLParser.h | 1 + RSXML/RSParsedArticle.h | 12 ++++++------ RSXML/RSParsedArticle.m | 8 ++------ RSXML/RSParsedFeed.h | 2 ++ RSXML/RSParsedFeed.m | 4 +--- RSXML/RSRSSParser.h | 1 + RSXML/RSSAXParser.h | 9 +++++++++ RSXML/RSSAXParser.m | 20 +++++--------------- RSXML/RSXMLData.h | 3 +++ RSXML/RSXMLData.m | 4 ++-- RSXML/RSXMLParser.h | 23 +++++++++++++++++++++++ RSXML/RSXMLParser.m | 18 ++++-------------- RSXMLTests/RSOPMLTests.m | 9 +++++---- RSXMLiOS/Info.plist | 2 +- 25 files changed, 108 insertions(+), 83 deletions(-) diff --git a/RSXML.xcodeproj/project.pbxproj b/RSXML.xcodeproj/project.pbxproj index be1e182..56e2f4f 100644 --- a/RSXML.xcodeproj/project.pbxproj +++ b/RSXML.xcodeproj/project.pbxproj @@ -560,7 +560,7 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; GCC_PREPROCESSOR_DEFINITIONS = ( - TARGET_IOS, + "TARGET_IOS=1", "$(inherited)", ); HEADER_SEARCH_PATHS = "${SDKROOT}/usr/include/libxml2"; @@ -586,7 +586,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREPROCESSOR_DEFINITIONS = TARGET_IOS; + GCC_PREPROCESSOR_DEFINITIONS = "TARGET_IOS=1"; HEADER_SEARCH_PATHS = "${SDKROOT}/usr/include/libxml2"; INFOPLIST_FILE = RSXMLiOS/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -743,10 +743,6 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_VERSION = A; - GCC_PREPROCESSOR_DEFINITIONS = ( - TARGET_MAC, - "$(inherited)", - ); HEADER_SEARCH_PATHS = "${SDKROOT}/usr/include/libxml2"; INFOPLIST_FILE = RSXML/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -770,7 +766,6 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_VERSION = A; - GCC_PREPROCESSOR_DEFINITIONS = TARGET_MAC; HEADER_SEARCH_PATHS = "${SDKROOT}/usr/include/libxml2"; INFOPLIST_FILE = RSXML/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -787,10 +782,6 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; COMBINE_HIDPI_IMAGES = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - TARGET_MAC, - "$(inherited)", - ); HEADER_SEARCH_PATHS = "${SDKROOT}/usr/include/libxml2"; INFOPLIST_FILE = RSXMLTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; @@ -805,7 +796,6 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; COMBINE_HIDPI_IMAGES = YES; - GCC_PREPROCESSOR_DEFINITIONS = TARGET_MAC; HEADER_SEARCH_PATHS = "${SDKROOT}/usr/include/libxml2"; INFOPLIST_FILE = RSXMLTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; diff --git a/RSXML/Info.plist b/RSXML/Info.plist index 87b0175..bd129b8 100644 --- a/RSXML/Info.plist +++ b/RSXML/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.0 + 2.0.0 CFBundleSignature ???? CFBundleVersion diff --git a/RSXML/RSAtomParser.h b/RSXML/RSAtomParser.h index 40f0c6c..7c01dd1 100644 --- a/RSXML/RSAtomParser.h +++ b/RSXML/RSAtomParser.h @@ -27,6 +27,7 @@ // // https://validator.w3.org/feed/docs/rfc4287.html +/// Feed parser for Atom xml feeds. Expects the tags @c and @c to be existent. @interface RSAtomParser : RSFeedParser @end diff --git a/RSXML/RSFeedParser.h b/RSXML/RSFeedParser.h index 80640f3..80b6f56 100644 --- a/RSXML/RSFeedParser.h +++ b/RSXML/RSFeedParser.h @@ -26,10 +26,13 @@ @class RSParsedFeed, RSParsedArticle; +/// Generic feed parser. Used for atom, RSS, and RDF feeds. @interface RSFeedParser : RSXMLParser @property (nonatomic, readonly) RSParsedFeed *parsedFeed; @property (nonatomic, weak) RSParsedArticle *currentArticle; +/// @return @c NSDate by parsing RFC 822 and 8601 date strings. - (NSDate *)dateFromCharacters:(NSData *)data; +/// @return currentString by removing HTML encoded entities. - (NSString *)decodeHTMLEntities:(NSString *)str; @end diff --git a/RSXML/RSFeedParser.m b/RSXML/RSFeedParser.m index 5f453de..7b15bbf 100644 --- a/RSXML/RSFeedParser.m +++ b/RSXML/RSFeedParser.m @@ -45,12 +45,12 @@ return _parsedFeed; } -/// @return @c NSDate by parsing RFC 822 and 8601 date strings. +// docref in header - (NSDate *)dateFromCharacters:(NSData *)data { return RSDateWithBytes(data.bytes, data.length); } -/// @return currentString by removing HTML encoded entities. +// docref in header - (NSString *)decodeHTMLEntities:(NSString *)str { return [str rsxml_stringByDecodingHTMLEntities]; } diff --git a/RSXML/RSHTMLLinkParser.h b/RSXML/RSHTMLLinkParser.h index 1b3db44..2454a29 100644 --- a/RSXML/RSHTMLLinkParser.h +++ b/RSXML/RSHTMLLinkParser.h @@ -27,5 +27,6 @@ @class RSHTMLMetadataAnchor; +/// HTML parser for html header metadata. Used to extract generic anchor tags. @interface RSHTMLLinkParser : RSXMLParser*> @end diff --git a/RSXML/RSHTMLMetadata.h b/RSXML/RSHTMLMetadata.h index 68a5231..74ef06c 100644 --- a/RSXML/RSHTMLMetadata.h +++ b/RSXML/RSHTMLMetadata.h @@ -36,6 +36,7 @@ RSFeedType RSFeedTypeFromLinkTypeAttribute(NSString * typeStr); @class RSHTMLMetadataIconLink, RSHTMLMetadataFeedLink; +/// Parsed result type for HTML metadata. @interface RSHTMLMetadata : NSObject @property (nonatomic, copy, nullable) NSString *faviconLink; @property (nonatomic, nonnull) NSArray *iconLinks; @@ -51,6 +52,7 @@ RSFeedType RSFeedTypeFromLinkTypeAttribute(NSString * typeStr); @interface RSHTMLMetadataIconLink : RSHTMLMetadataLink @property (nonatomic, copy, nullable) NSString *sizes; +/// Parses size on the fly. Expects the following format: @c "{int}x{int}" . Returns @c CGSizeZero otherwise. - (CGSize)getSize; @end diff --git a/RSXML/RSHTMLMetadata.m b/RSXML/RSHTMLMetadata.m index 40737cf..0368479 100644 --- a/RSXML/RSHTMLMetadata.m +++ b/RSXML/RSHTMLMetadata.m @@ -44,6 +44,7 @@ RSFeedType RSFeedTypeFromLinkTypeAttribute(NSString * typeStr) { @implementation RSHTMLMetadataIconLink +// docref in header - (CGSize)getSize { if (self.sizes && self.sizes.length > 0) { NSArray *parts = [self.sizes componentsSeparatedByString:@"x"]; diff --git a/RSXML/RSHTMLMetadataParser.h b/RSXML/RSHTMLMetadataParser.h index 35e05df..911c983 100644 --- a/RSXML/RSHTMLMetadataParser.h +++ b/RSXML/RSHTMLMetadataParser.h @@ -27,6 +27,7 @@ @class RSHTMLMetadata; +/// HTML parser for html header metadata. Used to extract feed and favicon URLs. @interface RSHTMLMetadataParser : RSXMLParser @end diff --git a/RSXML/RSOPMLItem.h b/RSXML/RSOPMLItem.h index aec46c6..0d9a62b 100644 --- a/RSXML/RSOPMLItem.h +++ b/RSXML/RSOPMLItem.h @@ -23,32 +23,44 @@ @import Foundation; +#ifndef TARGET_IOS +#define OPML_EXPORT 0 +#endif + // OPML allows for arbitrary attributes. // These are the common attributes in OPML files used as RSS subscription lists. -extern NSString *OPMLTextKey; //text -extern NSString *OPMLTitleKey; //title -extern NSString *OPMLDescriptionKey; //description -extern NSString *OPMLTypeKey; //type -extern NSString *OPMLVersionKey; //version -extern NSString *OPMLHMTLURLKey; //htmlUrl -extern NSString *OPMLXMLURLKey; //xmlUrl +/** Constant: @c \@"text" */ extern NSString *OPMLTextKey; +/** Constant: @c \@"title" */ extern NSString *OPMLTitleKey; +/** Constant: @c \@"description" */ extern NSString *OPMLDescriptionKey; +/** Constant: @c \@"type" */ extern NSString *OPMLTypeKey; +/** Constant: @c \@"version" */ extern NSString *OPMLVersionKey; +/** Constant: @c \@"htmlUrl" */ extern NSString *OPMLHMTLURLKey; +/** Constant: @c \@"xmlUrl" */ extern NSString *OPMLXMLURLKey; +/// Parsed result type for opml files. @c children can be arbitrary nested. @interface RSOPMLItem : NSObject +/// Can be arbitrary nested. @property (nonatomic) NSArray *children; @property (nonatomic) NSDictionary *attributes; -@property (nonatomic, readonly) BOOL isFolder; // true if children.count > 0 -@property (nonatomic, readonly) NSString *displayName; //May be nil. +/// Returns @c YES if @c children.count @c > @c 0 +@property (nonatomic, readonly) BOOL isFolder; +@property (nonatomic, readonly, nullable) NSString *displayName; + (instancetype)itemWithAttributes:(NSDictionary *)attribs; +/// Appends one child to the internal children array (creates new empty array if necessary). - (void)addChild:(RSOPMLItem *)child; +/// Sets a value in the internal dictionary (creates new empty dictionary if necessary). - (void)setAttribute:(id)value forKey:(NSString *)key; +/// @return Value for key (case-independent). - (id)attributeForKey:(NSString *)key; +/// Print object description for debugging purposes. - (NSString *)recursiveDescription; -#ifdef TARGET_MAC +#if OPML_EXPORT +/// Can be used to export directly to @c .opml file. - (NSXMLDocument *)exportXML; #endif @end diff --git a/RSXML/RSOPMLItem.m b/RSXML/RSOPMLItem.m index 025659a..696b6e7 100644 --- a/RSXML/RSOPMLItem.m +++ b/RSXML/RSOPMLItem.m @@ -74,7 +74,7 @@ NSString *OPMLXMLURLKey = @"xmlUrl"; } /// @return Value for @c OPMLTitleKey. If not set, use @c OPMLTextKey, else return @c nil. -- (NSString *)displayName { +- (nullable NSString *)displayName { NSString *title = [self attributeForKey:OPMLTitleKey]; if (!title) { title = [self attributeForKey:OPMLTextKey]; @@ -82,7 +82,7 @@ NSString *OPMLXMLURLKey = @"xmlUrl"; return title; } -/// Appends one child to the internal children array (creates new empty array if necessary). +// docref in header - (void)addChild:(RSOPMLItem *)child { if (!self.mutableChildren) { self.mutableChildren = [NSMutableArray new]; @@ -90,7 +90,7 @@ NSString *OPMLXMLURLKey = @"xmlUrl"; [self.mutableChildren addObject:child]; } -/// Sets a value in the internal dictionary (creates new empty dictionary if necessary). +// docref in header - (void)setAttribute:(id)value forKey:(NSString *)key { if (!self.mutableAttributes) { self.mutableAttributes = [NSMutableDictionary new]; @@ -98,7 +98,7 @@ NSString *OPMLXMLURLKey = @"xmlUrl"; [self.mutableAttributes setValue:value forKey:key]; } -/// @return Value for key (case-independent). +// docref in header - (id)attributeForKey:(NSString *)key { if (self.mutableAttributes.count > 0 && key && key.length > 0) { return [self.mutableAttributes rsxml_objectForCaseInsensitiveKey:key]; @@ -128,16 +128,16 @@ NSString *OPMLXMLURLKey = @"xmlUrl"; } } -/// Print object description for debugging purposes. +// docref in header - (NSString *)recursiveDescription { NSMutableString *mStr = [NSMutableString new]; [self appendStringRecursive:mStr indent:@""]; return mStr; } -#ifdef TARGET_MAC +#if OPML_EXPORT -/// Can be used to export directly to @c .opml file. +// docref in header - (NSXMLDocument *)exportXML { NSXMLElement *head = [NSXMLElement elementWithName:@"head"]; for (NSString *key in _mutableAttributes) { diff --git a/RSXML/RSOPMLParser.h b/RSXML/RSOPMLParser.h index e28925c..6cd0b36 100644 --- a/RSXML/RSOPMLParser.h +++ b/RSXML/RSOPMLParser.h @@ -29,6 +29,7 @@ @class RSOPMLItem; +/// OPML parser for structured opml files. Expects the tags @c and @c to be existent. @interface RSOPMLParser: RSXMLParser @end diff --git a/RSXML/RSParsedArticle.h b/RSXML/RSParsedArticle.h index 79673f2..13a69df 100755 --- a/RSXML/RSParsedArticle.h +++ b/RSXML/RSParsedArticle.h @@ -24,14 +24,12 @@ @import Foundation; - +/// Parsed result type for articles. Does contain article specific attributes like abstract and content. @interface RSParsedArticle : NSObject - -- (nonnull instancetype)initWithFeedURL:(NSURL * _Nonnull)feedURL dateParsed:(NSDate*)parsed; - @property (nonatomic, readonly, nonnull) NSURL *feedURL; @property (nonatomic, readonly, nonnull) NSDate *dateParsed; -@property (nonatomic, readonly, nonnull) NSString *articleID; //Calculated. Don't get until other properties have been set. +/// Calculated. Don't get until other properties have been set. +@property (nonatomic, readonly, nonnull) NSString *articleID; @property (nonatomic, nullable) NSString *guid; @property (nonatomic, nullable) NSString *title; @@ -43,7 +41,9 @@ @property (nonatomic, nullable) NSDate *datePublished; @property (nonatomic, nullable) NSDate *dateModified; -- (void)calculateArticleID; // Optimization. Call after all properties have been set. Call on a background thread. +- (nonnull instancetype)initWithFeedURL:(NSURL * _Nonnull)feedURL dateParsed:(NSDate*)parsed; +///Initiate calculation of article id. For optimization, call on a background thread after all properties have been set. +- (void)calculateArticleID; @end diff --git a/RSXML/RSParsedArticle.m b/RSXML/RSParsedArticle.m index 2edaa80..f017665 100755 --- a/RSXML/RSParsedArticle.m +++ b/RSXML/RSParsedArticle.m @@ -46,9 +46,7 @@ #pragma mark - Unique Article ID -/** - Article ID will be generated on the first access. - */ +// docref in header - (NSString *)articleID { if (!_internalArticleID) { _internalArticleID = self.calculatedUniqueID; @@ -56,9 +54,7 @@ return _internalArticleID; } -/** - Initiate calculation of article id. - */ +// docref in header - (void)calculateArticleID { (void)self.articleID; } diff --git a/RSXML/RSParsedFeed.h b/RSXML/RSParsedFeed.h index 802df21..a1df2d6 100755 --- a/RSXML/RSParsedFeed.h +++ b/RSXML/RSParsedFeed.h @@ -26,6 +26,7 @@ @class RSParsedArticle; +/// Parsed result type for feeds. Does contain feed specific attributes and a sorted list or articles. @interface RSParsedFeed : NSObject @property (nonatomic, readonly, nonnull) NSURL *url; @property (nonatomic, readonly, nonnull) NSDate *dateParsed; @@ -36,6 +37,7 @@ @property (nonatomic, nullable) NSString *subtitle; - (nonnull instancetype)initWithURL:(NSURL * _Nonnull)url; +/// Append new @c RSParsedArticle object to @c .articles and return newly inserted instance. - (RSParsedArticle *)appendNewArticle; @end diff --git a/RSXML/RSParsedFeed.m b/RSXML/RSParsedFeed.m index ea95769..1d0073f 100755 --- a/RSXML/RSParsedFeed.m +++ b/RSXML/RSParsedFeed.m @@ -46,9 +46,7 @@ return _mutableArticles; } -/** - Append new @c RSParsedArticle object to @c .articles and return newly inserted instance. - */ +// docref in header - (RSParsedArticle *)appendNewArticle { RSParsedArticle *article = [[RSParsedArticle alloc] initWithFeedURL:self.url dateParsed:_dateParsed]; [_mutableArticles addObject:article]; diff --git a/RSXML/RSRSSParser.h b/RSXML/RSRSSParser.h index 5c1e9eb..cc8cc70 100644 --- a/RSXML/RSRSSParser.h +++ b/RSXML/RSRSSParser.h @@ -27,6 +27,7 @@ // // https://cyber.harvard.edu/rss/rss.html +/// Feed parser for RSS xml and RDF xml feeds. Expects the tags @c and @c to be existent. @interface RSRSSParser : RSFeedParser @end diff --git a/RSXML/RSSAXParser.h b/RSXML/RSSAXParser.h index 28b52a4..fb2e97b 100644 --- a/RSXML/RSSAXParser.h +++ b/RSXML/RSSAXParser.h @@ -68,11 +68,20 @@ - (instancetype)initWithDelegate:(id)delegate; +/// Initialize new xml or html parser context and start processing of data. - (void)parseBytes:(const void *)bytes numberOfBytes:(NSUInteger)numberOfBytes; +/// Will stop the sax parser from processing any further. @c saxParserDidReachEndOfDocument: will not be called. - (void)cancel; +/** + Delegate can call from @c XMLStartElement. + Characters will be available in @c XMLEndElement as @c currentCharacters property. + Storing characters is stopped after each @c XMLEndElement. + */ - (void)beginStoringCharacters; +/// Delegate can call from within @c XMLStartElement. Returns @c nil if @c numberOfAttributes @c < @c 1 . - (NSDictionary *)attributesDictionary:(const unsigned char **)attributes numberOfAttributes:(NSInteger)numberOfAttributes; +/// Delegate can call from within @c XMLStartElement. Returns @c nil if @c attributes is @c nil . - (NSDictionary *)attributesDictionaryHTML:(const unsigned char **)attributes; @end diff --git a/RSXML/RSSAXParser.m b/RSXML/RSSAXParser.m index a647c2a..4064730 100644 --- a/RSXML/RSSAXParser.m +++ b/RSXML/RSSAXParser.m @@ -94,9 +94,7 @@ const NSErrorDomain kLIBXMLParserErrorDomain = @"LIBXMLParserErrorDomain"; static xmlSAXHandler saxHandlerStruct; -/** - Initialize new xml or html parser context and start processing of data. - */ +// docref in header - (void)parseBytes:(const void *)bytes numberOfBytes:(NSUInteger)numberOfBytes { _parsingError = nil; @@ -145,18 +143,14 @@ static xmlSAXHandler saxHandlerStruct; } } -/// Will stop the sax parser from processing any further. @c saxParserDidReachEndOfDocument: will not be called. +// docref in header - (void)cancel { @autoreleasepool { xmlStopParser(self.context); } } -/** - Delegate can call from @c XMLStartElement. - Characters will be available in @c XMLEndElement as @c currentCharacters property. - Storing characters is stopped after each @c XMLEndElement. - */ +// docref in header - (void)beginStoringCharacters { self.storingCharacters = YES; self.characters = [NSMutableData new]; @@ -194,9 +188,7 @@ static xmlSAXHandler saxHandlerStruct; #pragma mark - Attributes Dictionary -/** - Delegate can call from within @c XMLStartElement. Returns @c nil if @c numberOfAttributes @c < @c 1. - */ +// docref in header - (NSDictionary *)attributesDictionary:(const xmlChar **)attributes numberOfAttributes:(NSInteger)numberOfAttributes { if (numberOfAttributes < 1 || !attributes) { @@ -240,9 +232,7 @@ static xmlSAXHandler saxHandlerStruct; return d; } -/** - Delegate can call from within @c XMLStartElement. Returns @c nil if @c numberOfAttributes @c < @c 1. - */ +// docref in header - (NSDictionary *)attributesDictionaryHTML:(const xmlChar **)attributes { if (!attributes) { diff --git a/RSXML/RSXMLData.h b/RSXML/RSXMLData.h index 2089c87..95c6464 100644 --- a/RSXML/RSXMLData.h +++ b/RSXML/RSXMLData.h @@ -27,6 +27,7 @@ @class RSXMLParser; +/// Wrapper class for xml data. Returns the designated parser for any given xml data. @interface RSXMLData <__covariant T : RSXMLParser *> : NSObject @property (nonatomic, readonly, nonnull) NSURL *url; @property (nonatomic, readonly, nullable) NSData *data; @@ -35,7 +36,9 @@ - (instancetype)initWithData:(NSData * _Nonnull)data url:(NSURL * _Nonnull)url; +/// @return Kind of @c RSXMLParser or @c nil if no suitable parser found. - (T _Nullable)getParser; +/// @return @c YES if any parser, regardless of type, is suitable. - (BOOL)canParseData; @end diff --git a/RSXML/RSXMLData.m b/RSXML/RSXMLData.m index 77729d6..c0c4dd0 100644 --- a/RSXML/RSXMLData.m +++ b/RSXML/RSXMLData.m @@ -195,12 +195,12 @@ static const NSUInteger numberOfCharactersToSearch = 4096; #pragma mark - Check Methods to Determine Parser Type -/// @return Kind of @c RSXMLParser or @c nil if no suitable parser found. +// docref in header - (id)getParser { return [_parserClass parserWithXMLData:self]; } -/// @return @c YES if any parser, regardless of type, is suitable. +// docref in header - (BOOL)canParseData { return (_parserClass != nil && _parserError == nil); } diff --git a/RSXML/RSXMLParser.h b/RSXML/RSXMLParser.h index 80ad727..846304f 100644 --- a/RSXML/RSXMLParser.h +++ b/RSXML/RSXMLParser.h @@ -29,6 +29,9 @@ @class RSXMLData; +// --------------------------------------------------------------- +// | MARK: - Parser Delegate +// --------------------------------------------------------------- @protocol RSXMLParserDelegate @optional @@ -56,14 +59,34 @@ @end +// --------------------------------------------------------------- +// | MARK: - Parser +// --------------------------------------------------------------- + +/** + Generic wrapper class for @c libxml parsing. + Could be one of @c RSRSSParser, @c RSAtomParser, @c RSOPMLParser, @c RSHTMLMetadataParser, and @c RSHTMLLinkParser + */ @interface RSXMLParser<__covariant T> : NSObject @property (nonatomic, readonly, nonnull, copy) NSURL *documentURI; @property (nonatomic, assign) BOOL dontStopOnLowerAsciiBytes; +/** + Designated initializer. Runs a check whether it matches the detected parser in @c RSXMLData. + Keeps an internal pointer to the @c RSXMLData and initializes a new @c RSSAXParser. + */ + (instancetype)parserWithXMLData:(RSXMLData * _Nonnull)xmlData; +/** + Parse the XML data on whatever thread this method is called. + + @param error Sets @c error if parser gets unrecognized data or @c libxml runs into a parsing error. + @return The parsed object. The object type depends on the underlying data. @c RSParsedFeed, @c RSOPMLItem or @c RSHTMLMetadata. + */ - (T _Nullable)parseSync:(NSError ** _Nullable)error; +/// Dispatch new background thread, parse the data synchroniously on the background thread and exec callback on the main thread. - (void)parseAsync:(void(^)(T _Nullable parsedDocument, NSError * _Nullable error))block; +/// @return @c YES if @c .xmlInputError is @c nil. - (BOOL)canParse; @end diff --git a/RSXML/RSXMLParser.m b/RSXML/RSXMLParser.m index bbc11fc..4ba446d 100644 --- a/RSXML/RSXMLParser.m +++ b/RSXML/RSXMLParser.m @@ -39,10 +39,7 @@ + (BOOL)isHTMLParser { return NO; } // override - (id)xmlParserWillReturnDocument { return nil; } // override -/** - Designated initializer. Runs a check whether it matches the detected parser in @c RSXMLData. - Keeps an internal pointer to the @c RSXMLData and initializes a new @c RSSAXParser. - */ +// docref in header + (instancetype)parserWithXMLData:(nonnull RSXMLData *)xmlData { if ([xmlData.parserClass isSubclassOfClass:[super class]]) { return [[xmlData.parserClass alloc] initWithXMLData:xmlData]; @@ -85,12 +82,7 @@ }]; } -/** - Parse the XML data on whatever thread this method is called. - - @param error Sets @c error if parser gets unrecognized data or libxml runs into a parsing error. - @return The parsed object. The object type depends on the underlying data. @c RSParsedFeed, @c RSOPMLItem or @c RSHTMLMetadata. - */ +// docref in header - (id _Nullable)parseSync:(NSError **)error { if (_xmlInputError) { if (error) *error = _xmlInputError; @@ -109,9 +101,7 @@ return [self xmlParserWillReturnDocument]; } -/** - Dispatch new background thread, parse the data synchroniously on the background thread and exec callback on the main thread. - */ +// docref in header - (void)parseAsync:(void(^)(id parsedDocument, NSError *error))block { dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{ // QOS_CLASS_DEFAULT @autoreleasepool { @@ -124,7 +114,7 @@ }); } -/// @return @c YES if @c .xmlInputError is @c nil. +// docref in header - (BOOL)canParse { return (self.xmlInputError == nil); } diff --git a/RSXMLTests/RSOPMLTests.m b/RSXMLTests/RSOPMLTests.m index 268aa1e..133b28b 100644 --- a/RSXMLTests/RSOPMLTests.m +++ b/RSXMLTests/RSOPMLTests.m @@ -42,9 +42,8 @@ return [[RSXMLData alloc] initWithData:d url:[NSURL fileURLWithPath:s]]; } -#ifdef TARGET_MAC - - (void)testOPMLExport { +#if OPML_EXPORT RSOPMLItem *doc = [RSOPMLItem itemWithAttributes:@{OPMLTitleKey : @"Greetings from CCC", @"dateCreated" : @"2018-12-27 23:12:04 +0100", @"ownerName" : @"RSXML Parser"}]; @@ -76,9 +75,11 @@ XCTAssertEqualObjects([document.children.lastObject attributeForKey:OPMLXMLURLKey], @"http://www.feed2.com/feed.atom"); NSLog(@"%@", [document recursiveDescription]); -} - +#else + NSLog(@"OPML export is disabled for this framework!"); + XCTAssertNil(nil); #endif +} - (void)testNotOPML { diff --git a/RSXMLiOS/Info.plist b/RSXMLiOS/Info.plist index ffdcd1b..ac8746e 100644 --- a/RSXMLiOS/Info.plist +++ b/RSXMLiOS/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.0 + 2.0.0 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass