Search code examples
objective-cswiftnsarraycgrect

CGrect NSArray error


I'm trying to create a CGRect array from a Swift class, that eventually will be send to an Objective C class.

As far as i understand, Objective C expecting a NSArray or NSMutableArray when creating a CGRect array. I tried to make an NSArray and appending CGRect, tho it print the error :

 Cannot convert value of type 'NSValue' to expected argument type 'NSArray'

Swift Code:

            var rects = [NSArray]()
            let v = NSValue(CGRect: feature.bounds)
            rects.append(v)

Any suggestions folks?


Solution

  • This is not an NSArray:

    var rects = [NSArray]()
    

    This is a Swift array of NSArray objects (i.e an array within an array). If you want to append NSValues to your array, then you want a [NSValue].

    var rects = [NSValue]()
    let v = NSValue(CGRect: feature.bounds)
    rects.append(v)
    

    However, I would generally advise against doing this (depends on your exact use case) as it adds a wrapper that Swift itself doesn't need, as well as reducing type safety. If you need to interact with this array in Swift before sending it off to an Objective-C API, then I would instead create an array of CGRects directly, as @Bhushan suggests.

    var rects = [CGRect]()
    rects.append(CGRect(x: 50, y: 50, width: 100, height: 100))
    

    However, you now can't pass this array to an NSArray argument, you'll get an error saying Cannot convert value of type '[CGRect]' to '[AnyObject]'. In order to deal with this, you can simply use map on your array – in order to wrap each CGRect in an NSValue before sending it off to Objective-C.

    someObjCInstance.someProperty = rects.map{NSValue(CGRect:$0)}
    

    This way you can have the best of both worlds. You get the flexibility and type safety of being able to use an array of CGRects in Swift and you also get the interoperability with Objective-C.