11

I'm getting an error when translating some Objective-C code to Swift.

I'm using - attribute:atIndex:effectiveRange: of NSAttributedString and having an error concerning the effectiveRange parameter, which is an NSRangePointer.

Objective-C:

NSRange range;
id value = [self.textanalyze
                      attribute:attribute
                        atIndex:index
                 effectiveRange:&range]

Swift:

var range : NSRange?
var value : Any = self.textanalyze.attribute(attributes,
                      atIndex: index,
               effectiveRange: &range)   

I got an error near &range.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
daniyal yousuf
  • 107
  • 1
  • 3

2 Answers2

13

You need to unwrap the range.

Also, you need to initialize range. Otherwise, this will crash your program.

var range : NSRange? = NSMakeRange(0, 1)
self.textanalyze.attribute(attributes, atIndex: index, effectiveRange: &range!)

Or, if you don't want to unwrap your range (it might be nil), rewrite your function like this:

var range : NSRange?
doSomethingWithRangePointer(&range)

func doSomethingWithRangePointer(range : UnsafeMutablePointer<NSRange?>) {
    // Do stuff
}

But you may not have needed to make your range an optional in the first place (think, does range ever need to be nil? If not, then it doesn't need to be optional.), in which case, just initializing range like this will work:

var range = NSMakeRange(0, 1)
michaelsnowden
  • 6,031
  • 2
  • 38
  • 83
  • 2
    That might work, but wouldn't it be easier to declare the range as a non-optional instead of unwrapping it in the function call? – Martin R Sep 13 '14 at 17:00
  • @MartinR Sure would, but OP has implied range should be nil at some point. Otherwise, I don't think he would have left his range declared as an optional. – michaelsnowden Sep 13 '14 at 17:01
  • 1
    @MartinR Also, it's not that this might work. This will definitely work. See my example above. – michaelsnowden Sep 13 '14 at 17:03
  • 2
    I assume that OP declared it as an optional only due to a misunderstanding how the NSRangePointer parameter works. – Martin R Sep 13 '14 at 17:04
  • @MartinR I added your input as the third option. However, OP might still need to use an optional NSRange, in which case, the second answer will suffice. – michaelsnowden Sep 13 '14 at 17:10
2
let a = sizeof(NSRange)
let objRangePtr:NSRangePointer = NSRangePointer.alloc(a) //alloc memory
objLayoutManager.characterRangeForGlyphRange(range, actualGlyphRange:objRangePtr)
let objRange = objRangePtr.move() //gain the value and dealloc()
zHeng
  • 21
  • 2