Skip to content

Commit 4cd5eb7

Browse files
committed
Implement attribute(atIndex:effectiveRange:)
1 parent 7e0ef38 commit 4cd5eb7

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

Foundation/NSAttributedString.swift

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,25 @@ public class NSAttributedString : NSObject, NSCopying, NSMutableCopying, NSSecur
7676
return CFAttributedStringGetLength(_cfObject)
7777
}
7878

79-
public func attribute(_ attrName: String, atIndex location: Int, effectiveRange range: NSRangePointer) -> AnyObject? { NSUnimplemented() }
79+
public func attribute(_ attrName: String, atIndex location: Int, effectiveRange range: NSRangePointer) -> AnyObject? {
80+
var cfRange = CFRange()
81+
return withUnsafeMutablePointer(&cfRange) { (rangePointer: UnsafeMutablePointer<CFRange>) -> AnyObject? in
82+
// Get attribute value using CoreFoundation function
83+
let attribute = CFAttributedStringGetAttribute(_cfObject, location, attrName._cfObject, rangePointer)
84+
85+
// Update effective range and return the result
86+
if let attribute = attribute {
87+
range.pointee.location = rangePointer.pointee.location
88+
range.pointee.length = rangePointer.pointee.length
89+
return attribute
90+
} else {
91+
range.pointee.location = NSNotFound
92+
range.pointee.length = 0
93+
return nil
94+
}
95+
}
96+
}
97+
8098
public func attributedSubstringFromRange(_ range: NSRange) -> NSAttributedString { NSUnimplemented() }
8199

82100
public func attributesAtIndex(_ location: Int, longestEffectiveRange range: NSRangePointer, inRange rangeLimit: NSRange) -> [String : AnyObject] { NSUnimplemented() }

TestFoundation/TestNSAttributedString.swift

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ class TestNSAttributedString : XCTestCase {
3939
XCTAssertEqual(range.location, NSNotFound)
4040
XCTAssertEqual(range.length, 0)
4141
XCTAssertEqual(attrs.count, 0)
42+
43+
let attribute = attrString.attribute("invalid", atIndex: 0, effectiveRange: &range)
44+
XCTAssertNil(attribute)
45+
XCTAssertEqual(range.location, NSNotFound)
46+
XCTAssertEqual(range.length, 0)
4247
}
4348

4449
func test_initWithStringAndAttributes() {
@@ -51,15 +56,27 @@ class TestNSAttributedString : XCTestCase {
5156

5257
var range = NSRange()
5358
let attrs = attrString.attributesAtIndex(0, effectiveRange: &range)
54-
5559
guard let value = attrs["attribute.placeholder.key"] as? NSString else {
5660
XCTAssert(false, "attribute value not found")
5761
return
5862
}
59-
6063
XCTAssertEqual(range.location, 0)
6164
XCTAssertEqual(range.length, attrString.length)
6265
XCTAssertEqual(value, "attribute.placeholder.value")
66+
67+
let invalidAttribute = attrString.attribute("invalid", atIndex: 0, effectiveRange: &range)
68+
XCTAssertNil(invalidAttribute)
69+
XCTAssertEqual(range.location, NSNotFound)
70+
XCTAssertEqual(range.length, 0)
71+
72+
let attribute = attrString.attribute("attribute.placeholder.key", atIndex: 0, effectiveRange: &range)
73+
XCTAssertEqual(range.location, 0)
74+
XCTAssertEqual(range.length, attrString.length)
75+
guard let validAttribute = attribute as? NSString else {
76+
XCTAssert(false, "attribuet not found")
77+
return
78+
}
79+
XCTAssertEqual(validAttribute, "attribute.placeholder.value")
6380
}
6481

6582
}

0 commit comments

Comments
 (0)