@@ -47,7 +47,29 @@ public class NSAttributedString : NSObject, NSCopying, NSMutableCopying, NSSecur
47
47
return _string
48
48
}
49
49
50
- public func attributesAtIndex( _ location: Int , effectiveRange range: NSRangePointer ) -> [ String : AnyObject ] { NSUnimplemented ( ) }
50
+ public func attributesAtIndex( _ location: Int , effectiveRange range: NSRangePointer ) -> [ String : AnyObject ] {
51
+ var cfRange = CFRange ( location: NSNotFound, length: 0 )
52
+ return withUnsafeMutablePointer ( & cfRange) { ( rangePointer: UnsafeMutablePointer < CFRange > ) -> [ String : AnyObject ] in
53
+ // Get attributes value from `_attributeArray`
54
+ let value = CFRunArrayGetValueAtIndex ( _attributeArray, location, rangePointer, nil ) . takeUnretainedValue ( )
55
+
56
+ // Convert the value to [String : AnyObject]
57
+ let dictionary = unsafeBitCast ( value, to: NSDictionary . self)
58
+ var results = [ String : AnyObject] ( )
59
+ for (key, value) in dictionary {
60
+ guard let stringKey = ( key as? NSString ) ? . _swiftObject else {
61
+ continue
62
+ }
63
+ results [ stringKey] = value
64
+ }
65
+
66
+ // Update effective range
67
+ range. pointee. location = rangePointer. pointee. location
68
+ range. pointee. length = rangePointer. pointee. length
69
+
70
+ return results
71
+ }
72
+ }
51
73
52
74
public var length : Int {
53
75
return _string. length
@@ -64,24 +86,43 @@ public class NSAttributedString : NSObject, NSCopying, NSMutableCopying, NSSecur
64
86
public init ( string str: String ) {
65
87
_string = str
66
88
_attributeArray = CFRunArrayCreate ( kCFAllocatorDefault)
89
+
90
+ super. init ( )
91
+ addAttributesToAttributeArray ( attrs: nil )
67
92
}
68
93
69
94
public init ( string str: String , attributes attrs: [ String : AnyObject ] ? ) {
70
95
_string = str
71
96
_attributeArray = CFRunArrayCreate ( kCFAllocatorDefault)
72
97
73
- let length = _string. length
74
- if ( length > 0 ) {
75
- CFRunArrayInsert ( _attributeArray, CFRange ( location: 0 , length: length) , attrs? . _cfObject)
76
- }
98
+ super. init ( )
99
+ addAttributesToAttributeArray ( attrs: attrs)
77
100
}
78
101
79
102
public init ( attributedString attrStr: NSAttributedString ) { NSUnimplemented ( ) }
80
103
104
+ private func addAttributesToAttributeArray( attrs: [ String : AnyObject ] ? ) {
105
+ guard _string. length > 0 else {
106
+ return
107
+ }
108
+
109
+ let range = CFRange ( location: 0 , length: _string. length)
110
+ if let attrs = attrs {
111
+ CFRunArrayInsert ( _attributeArray, range, attrs. _cfObject)
112
+ } else {
113
+ let emptyAttrs = [ String : AnyObject] ( )
114
+ CFRunArrayInsert ( _attributeArray, range, emptyAttrs. _cfObject)
115
+ }
116
+ }
117
+
81
118
public func enumerateAttributesInRange( _ enumerationRange: NSRange , options opts: NSAttributedStringEnumerationOptions , usingBlock block: ( [ String : AnyObject ] , NSRange , UnsafeMutablePointer < ObjCBool > ) -> Void ) { NSUnimplemented ( ) }
82
119
public func enumerateAttribute( _ attrName: String , inRange enumerationRange: NSRange , options opts: NSAttributedStringEnumerationOptions , usingBlock block: ( AnyObject ? , NSRange , UnsafeMutablePointer < ObjCBool > ) -> Void ) { NSUnimplemented ( ) }
83
120
}
84
121
122
+ extension NSAttributedString : _CFBridgable {
123
+ internal var _cfObject : CFAttributedString { return unsafeBitCast ( self , to: CFAttributedString . self) }
124
+ }
125
+
85
126
public struct NSAttributedStringEnumerationOptions : OptionSet {
86
127
public let rawValue : UInt
87
128
public init ( rawValue: UInt ) { self . rawValue = rawValue }
0 commit comments