v2.0.0 release; move all docref to header + optional NSXML
This commit is contained in:
@@ -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";
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<string>2.0.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
// <feed> <entry>
|
||||
// https://validator.w3.org/feed/docs/rfc4287.html
|
||||
|
||||
/// Feed parser for Atom xml feeds. Expects the tags @c <feed> and @c <entry> to be existent.
|
||||
@interface RSAtomParser : RSFeedParser
|
||||
|
||||
@end
|
||||
|
||||
@@ -26,10 +26,13 @@
|
||||
|
||||
@class RSParsedFeed, RSParsedArticle;
|
||||
|
||||
/// Generic feed parser. Used for atom, RSS, and RDF feeds.
|
||||
@interface RSFeedParser : RSXMLParser<RSParsedFeed*>
|
||||
@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
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -27,5 +27,6 @@
|
||||
|
||||
@class RSHTMLMetadataAnchor;
|
||||
|
||||
/// HTML parser for html header metadata. Used to extract generic anchor tags.
|
||||
@interface RSHTMLLinkParser : RSXMLParser<NSArray<RSHTMLMetadataAnchor*>*>
|
||||
@end
|
||||
|
||||
@@ -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 <RSHTMLMetadataIconLink *> *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
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ RSFeedType RSFeedTypeFromLinkTypeAttribute(NSString * typeStr) {
|
||||
|
||||
@implementation RSHTMLMetadataIconLink
|
||||
|
||||
// docref in header
|
||||
- (CGSize)getSize {
|
||||
if (self.sizes && self.sizes.length > 0) {
|
||||
NSArray<NSString*> *parts = [self.sizes componentsSeparatedByString:@"x"];
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
@class RSHTMLMetadata;
|
||||
|
||||
/// HTML parser for html header metadata. Used to extract feed and favicon URLs.
|
||||
@interface RSHTMLMetadataParser : RSXMLParser<RSHTMLMetadata*>
|
||||
|
||||
@end
|
||||
|
||||
@@ -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<RSOPMLItem*> *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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
@class RSOPMLItem;
|
||||
|
||||
/// OPML parser for structured opml files. Expects the tags @c <opml> and @c <outline> to be existent.
|
||||
@interface RSOPMLParser: RSXMLParser<RSOPMLItem*>
|
||||
|
||||
@end
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
// <channel> <item>
|
||||
// https://cyber.harvard.edu/rss/rss.html
|
||||
|
||||
/// Feed parser for RSS xml and RDF xml feeds. Expects the tags @c <channel> and @c <item> to be existent.
|
||||
@interface RSRSSParser : RSFeedParser
|
||||
|
||||
@end
|
||||
|
||||
@@ -68,11 +68,20 @@
|
||||
|
||||
- (instancetype)initWithDelegate:(id<RSSAXParserDelegate>)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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
|
||||
@class RSXMLData;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// | MARK: - Parser Delegate
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
@protocol RSXMLParserDelegate <NSObject>
|
||||
@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 <RSXMLParserDelegate, RSSAXParserDelegate>
|
||||
@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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<string>2.0.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
||||
Reference in New Issue
Block a user