How can I cast an NSMutableArray to a Swift array of a specific type?
You can make this work with a double downcast, first to NSArray
, then to [String]
:
var strings = myObjcObject.getStrings() as NSArray as [String]
Tested in a Playground with:
import Foundation
var objCMutableArray = NSMutableArray(array: ["a", "b", "c"])
var swiftArray = objCMutableArray as NSArray as [String]
Update:
In later versions of Swift (at least 1.2), the compiler will complain about as [String]
. Instead you should use an if let
with a conditional downcast as?
:
import Foundation
var objCMutableArray = NSMutableArray(array: ["a", "b", "c"])
if let swiftArray = objCMutableArray as NSArray as? [String] {
// Use swiftArray here
}
If you are absolutely sure that your NSMutableArray
can be cast to [String]
, then you can use as!
instead (but you probably shouldn't use this in most cases):
import Foundation
var objCMutableArray = NSMutableArray(array: ["a", "b", "c"])
var swiftArray = objCMutableArray as NSArray as! [String]
How to cast a swift array of tuples to NSMutableArray?
Since swift types like Tuple
or Struct
have no equivalent in Objective-C they can not be cast to or referenced as AnyObject
which NSArray
and NSMutableArray
constrain their element types to.
The next best thing if you must return an NSMutableArray from a swift Array of tuples might be returning an Array of 2 element Arrays:
let itemsTuple = [("Pheonix Down", "Potion"), ("Elixer", "Turbo Ether")]
let itemsArray = itemsTuple.map { [$0.0, $0.1] }
let mutableItems = NSMutableArray(array: itemsArray)
NSMutableArray cast to swift Array of custom type
What I needed was this:
let newVC = UIViewController(array: mutableArray as AnyObject as [CustomType])
Combine NSMutableArray with [Swift Array]
You can use addObjectsFromArray
method of NSMutableArray
for that
var allDevices: NSMutableArray {
get {
var blueToothDevices = CentralManager.shared().storedDevices
let devices = blueToothDevices.addObjectsFromArray(wifiDevices)
return devices
}
}
Edit: If you want allDevices
to be of swift array and your blueToothDevices
contains WifiDevice
type of object you can use [WifiDevice]
like this way.
var blueToothDevices = CentralManager.shared().storedDevices
var devices = blueToothDevices.objectEnumerator().allObjects as! [WifiDevice]
let devices = devices + wifiDevices
For Any Object
var allDevices: [AnyObject] {
get {
var blueToothDevices = CentralManager.shared().storedDevices
var blueTooths = blueToothDevices.objectEnumerator().allObjects
blueTooths = blueTooths + wifiDevices
return blueTooths
}
}
Declare NSMutableArray content type
If you want to declare a variable of type array of Card
but not save an array into it, you'd use
var cardArray: [Card]
That's equivalent to the Objective-C
NSMutableArray<Card*> cardArray;
(Or rather, the Objective-C is equivalent to the Swift, since Objective-C adopted typed arrays in order to be compatible with Swift.)
If you want to define a variable of type array of Card
and put a blank array into it, you'd use
var cardArray = [Card]()
That's equivalent to
NSMutableArray<Card*> cardArray = [NSMutableArray new];
(Although I forget how you satisfy the type requirement in Objective-C. That Objective-C statement might need minor tweaking...)
Type 'Any' has no subscript members - NSMutableArray
The reason you are getting this error is because the type of the object that is in your array is ambiguous to the compiler.
This is due to the fact that NSArray
s aren't typed concretely.NSArray
is basically the Objective-C bridge of Array<Any>
or [Any]
.
Let me walk you through your code...
let cellType = cellDescriptors[0][i][typeKey] as! String
The compiler knows that cellDescriptors
is an NSArray
as it is declared as one above. NSArray
s can be subscripted to get the value at a given index, as you are doing with cellDescriptors[0]
. The value this gives is of type Any
, as explained above, so when you try and subscript it again with cellDescriptors[0][i]
, you are getting your error. As it happens, you can likely cast that Any
object to an array, then you'll be able to perform the subscript, like so:
if let newArr = (cellDescriptors[0] as? [Any])[i] { }
However, this really isn't a nice approach and you end up dealing with a load of nasty optionals.
A better approach would be to concrete your declaration of cellDescriptors
. I don't know how your type structure lies, but by the looks of things, it's an array of arrays of dictionaries (yuck). So in a raw form, your declaration should be var cellDescriptors = [[[AnyHashable:Any]]]()
in order to subscript as you are now.
This said, the code you have in place is messy and I would consider changing the way you model your objects to make it more usable.
Swift code problem - trying to cast objects out from a NSMutableArray as a custom object
Better approach would be to use JSONDecoder() instead of a JSONSerailizer. Try using the following code.
struct User: Codable {
var userId, firstName, lastName, userSessionId: String
enum CodingKeys: String, CodingKey {
case userId = "Userid"
case firstName = "First_Name"
case lastName = "Last_Name"
case userSessionId = "Session_ID"
}
}
func parseJSON(_ data: Data) {
do {
let users = try JSONDecoder().decode([User].self, from: data)
users.forEach { user in
print("users first name:", user.firstName)
}
} catch {
print(error.localizedDescription)
}
}
why to i have to cast NSMutableArray to NSMutableArray?
mutableCopy
is implemented by NSObject and defined as:
func mutableCopy() -> Any
So therefore when you call mutableCopy()
the resulting object needs to be cast.
Related Topics
How to Change the Size of Uiactivityindicator
Change the Font Size of Uisearchbar
Accidentally Removed Xcassets File from Xcode Project
Black Screen After Presenting Modal View Controller in Current Context from Uitabbarcontroller
How Does One Print All Wkwebview on and Offscreen Content Osx and iOS
Swift "Bridging-Header.H" File Not Allowing Me to Instantiate Objective-C Classes in .Swift Files
iOS Alamofire Stop All Requests
How to Detect Live Changes on Textfield in Swiftui
Sendasynchronousrequest Was Deprecated in iOS 9, How to Alter Code to Fix
App Crashes on Enabling Camera Access from Settings iOS 8
When Will Applicationwillterminate Be Called
What Exactly Are Protocols and Delegates and How Are They Used in iOS