diff --git a/Core/Source/NSAttributedString+HTML.h b/Core/Source/NSAttributedString+HTML.h index ce836cbf8..b7a6e799a 100644 --- a/Core/Source/NSAttributedString+HTML.h +++ b/Core/Source/NSAttributedString+HTML.h @@ -72,4 +72,23 @@ */ - (NSRange)rangeOfHTMLAttribute:(NSString *)name atIndex:(NSUInteger)index; +/** + Retrieves the NSAttributedString with NSData + + Currently only supports iOS by `___useiOS6Attributes`, if error occur return nil. + + @param data The data must generate by `convertToData` function + @return NSAttributedString from unarchiveObjectWithData, the data must generate by `convertToData` function + */ ++ (NSAttributedString *)attributedStringWithData:(NSData *)data; + +/** + Retrieves NSData with self + + Currently only supports iOS by `___useiOS6Attributes`, if error occur return nil. + + @return NSData from NSAttributedString execute archivedDataWithRootObject: + */ +- (NSData *)convertToData; + @end diff --git a/Core/Source/NSAttributedString+HTML.m b/Core/Source/NSAttributedString+HTML.m index 62691ba04..11f90fe70 100644 --- a/Core/Source/NSAttributedString+HTML.m +++ b/Core/Source/NSAttributedString+HTML.m @@ -14,6 +14,11 @@ #import "DTHTMLElement.h" #import "DTCoreTextConstants.h" #import "DTHTMLAttributedStringBuilder.h" +#import "DTTextAttachment.h" + +#if TARGET_OS_IPHONE +#import "NSAttributedStringRunDelegates.h" +#endif @implementation NSAttributedString (HTML) @@ -58,6 +63,70 @@ - (id)initWithHTMLData:(NSData *)data options:(NSDictionary *)options documentAt return string; } +#pragma mark - NSAttributedString Archiving + +- (NSData *)convertToData +{ + NSMutableAttributedString *appendString = [self mutableCopy]; +#if DTCORETEXT_SUPPORT_NS_ATTRIBUTES && TARGET_OS_IPHONE + NSUInteger length = [self length]; + if (length) + { + [self enumerateAttributesInRange:NSMakeRange(0, length-1) options:0 usingBlock:^(NSDictionary * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) { + + if (attrs[NSAttachmentAttributeName]) + { + [appendString removeAttribute:(id)kCTRunDelegateAttributeName range:range]; + } + }]; + } +#endif + + NSData *data = nil; + @try + { + data = [NSKeyedArchiver archivedDataWithRootObject:appendString]; + } + @catch (NSException *exception) + { + data = nil; + } + + return data; +} + ++ (NSAttributedString *)attributedStringWithData:(NSData *)data +{ + NSMutableAttributedString *appendString = nil; +#if DTCORETEXT_SUPPORT_NS_ATTRIBUTES && TARGET_OS_IPHONE + @try + { + appendString = (NSMutableAttributedString *)[NSKeyedUnarchiver unarchiveObjectWithData:data]; + } + @catch (NSException *exception) + { + appendString = nil; + } + + NSUInteger length = [appendString length]; + if (length) + { + [appendString enumerateAttributesInRange:NSMakeRange(0, length-1) options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(NSDictionary * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) { + + if (attrs[NSAttachmentAttributeName]) + { + DTTextAttachment *attatchment = attrs[NSAttachmentAttributeName]; + CTRunDelegateRef embeddedObjectRunDelegate = createEmbeddedObjectRunDelegate(attatchment); + + [appendString addAttribute:(id)kCTRunDelegateAttributeName value:CFBridgingRelease(embeddedObjectRunDelegate) range:range]; + } + + }]; + } +#endif + return [appendString copy]; +} + #pragma mark - Working with Custom HTML Attributes - (NSDictionary *)HTMLAttributesAtIndex:(NSUInteger)index