Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert NSArray to Swift Array<T>

In CoreData I have defined an ordered to-many relationship. This relationship is defined in Swift like this:

@NSManaged var types : NSMutableArray 

However, to use Swift at it's best, I want to use a normal Swift array like Type[]. However, CoreData forces me to use NS(Mutable)Array. How can I type-cast / convert the NSArray to Array<Type>[]?

Apparently the confusion arises from the following error:

let array = obj.types as T[] // Cannot convert expression's type 'Node[]' to type '$T2' 

While this is accepted by the editor:

let array = obj.types as AnyObject[] as T[] // No complaint 
like image 952
Bouke Avatar asked Jun 26 '14 05:06

Bouke


People also ask

Can we use NSArray in Swift?

In Swift, the NSArray class conforms to the ArrayLiteralConvertible protocol, which allows it to be initialized with array literals. For more information about object literals in Swift, see Literal Expression in The Swift Programming Language (Swift 4.1).

What is the difference between NSArray and array in Swift?

Array is a struct, therefore it is a value type in Swift. NSArray is an immutable Objective C class, therefore it is a reference type in Swift and it is bridged to Array<AnyObject> . NSMutableArray is the mutable subclass of NSArray . Because foo changes the local value of a and bar changes the reference.

What is NSArray?

NSArray is an immutable Objective C class, therefore it is a reference type in Swift and it is bridged to Array<AnyObject> . NSMutableArray is the mutable subclass of NSArray .


2 Answers

I'm currently using obj.types.allObjects as Type[], but that feels like a hack/workaround.

Then revise your feelings. What you're doing is exactly how you do "type-cast / convert the NSArray to Array<Type>[]."

An NSArray always arrives into Swift as containing AnyObject (i.e. an Array<AnyObject>, aka AnyObject[]). Casting it down to a specific type, if you know that it contains all one type, is up to you, and how you are doing it is exactly what you are supposed to do.

EDIT In Swift 2.0 and the new iOS 9 APIs, an NSArray will often arrive correctly typed, and no cast will be needed.

EDIT 2 In Swift 3.0, an NSArray that is not correctly typed, though uncommon, will arrive as containing Any instead of AnyObject and will still have to be cast down to a specific type.

like image 199
matt Avatar answered Sep 22 '22 11:09

matt


The following is a working piece of code from one of my projects that might help?

if let rawArray = rawData as? NSArray,    let castArray = rawArray as? Array< Dictionary< String, AnyObject > >    {         // etc...     } 

It works, although I'm not sure it would be considered optimal.

like image 29
Joseph Beuys' Mum Avatar answered Sep 18 '22 11:09

Joseph Beuys' Mum