2

Is there a way to annotate an NSArray of NSNumber:

@property (nonatomic) NSArray<NSNumber *> *myProperty

in Objective-C, so that it will be imported in Swift as

var myProperty: [Int] instead of var myProperty: [NSNumber]?

I know of NS_SWIFT_NAME, but that does not allow changing the type.

jscs
  • 63,694
  • 13
  • 151
  • 195
Trenskow
  • 3,783
  • 1
  • 29
  • 35
  • Can you explain more clearly? Do you need an `Int` array or `NSNumber` array in swift? Or maybe an `Int` array in Objective c? – trungduc Oct 29 '17 at 06:29
  • An `Int` array in Swift from an `NSArray *` in Objective-C. – Trenskow Oct 29 '17 at 06:56
  • After asking the question I researched a little more. I don't think it's possible. If you look at the `allowedTouchTypes` property of `UIGestureRecognizer`. That one is also an `NSArray *` return type, and is imported in Swift as `[NSNumber]`. – Trenskow Oct 29 '17 at 07:00
  • @Trenskow you can get any element from your number array `[NSNumber]` and access its `intValue` property which will return an `Int`. You can also map all elements `numbers.map{$0.intValue}` will return an array of Int `[Int]` – Leo Dabus Oct 29 '17 at 07:06
  • @Trenskow If you are working with NSArray you would need to cast from `Any` to `NSNumber` `numbers.flatMap{($0 as? NSNumber)?.intValue}`. But you should work with Swift native Array type – Leo Dabus Oct 29 '17 at 07:12
  • Yes. I'm designing an API, and I would like this to be automatically imported as this in Swift, but I know now, that it is not possible. – Trenskow Oct 29 '17 at 08:19

1 Answers1

2

Unfortunately you can't change the static type when importing a symbol from Objective-C.

But you can assign a Swift Int array without any type cast (assuming foo is an instance of the ObjC class). However the type doesn't change.

foo.myProperty = [1, 2, 3, 4, 5]
print(type(of: foo.myProperty)) // Optional<Array<NSNumber>>

On the other hand to get a distinct [Int] type you have to cast the type

let mySwiftProperty = foo.myProperty as! [Int]
print(type(of: mySwiftProperty)) // Array<Int>
vadian
  • 274,689
  • 30
  • 353
  • 361
  • I accept this as the correct answer. After the initial question I did some research, and even UIKit does this, so I guess it's not possible. I just wanted not to make it my users responsibility to cast it to the correct type. Thanks! – Trenskow Oct 30 '17 at 15:04