2014-09-14 6 views
52

Ich migriere mein iOS-Projekt zu Swift. Ich mache diese Klasse nach Klasse. Wenn ich Objective-C-Methoden von Swift aus anrufe, werden viele Ziel-C-Typen in ihre Swift-Gegenstücke konvertiert.Wie kann ich ein NSMutableArray in ein Swift-Array eines bestimmten Typs umwandeln?

In meinem Fall wird ein Objective C NSMutableArray in Swifts Array<AnyObject> konvertiert. Jetzt kommt mein Problem. Innerhalb meiner Swift-Klasse bekomme ich ein solches Array von einem Objective-C-Objekt zurück. Jetzt, wo ich in der Swift-Welt bin, möchte ich dieses Array auf einen bestimmten Typ anstatt AnyObject umwandeln, weil ich genau weiß, welche Art von Objekten in diesem Array existieren.

Der Compiler lässt mich das nicht tun! Lassen Sie mich mein Problem vereinfachen, indem ich sage, dass ich in ein Array mit Strings umwandeln möchte. Das ist, was ich versuchte:

var strings = myObjcObject.getStrings() as [String] 

bekomme ich folgende Fehler von dem Compiler:

ich mit dem Compiler, da String müsste zustimmen ist in der Tat nicht identisch mit ANYOBJECT. Aber ich sehe nicht, warum das ein Problem ist. Ich kann AnyObject in String umwandeln, wenn ich will, oder?

Ich habe auch versucht:

var strings = myObjcObject.getStrings() as? [String] 

Dies scheint ein Schritt in die richtige Richtung zu sein, aber getStrings() gibt ein NSMutableArray, damit ich die folgende Fehlermeldung erhalten:

'NSArray' is not a subtype of 'NSMutableArray'

Gibt es eine Was kann ich hier tun?

Antwort

119

Sie können diese Arbeit mit einem Doppelniedergeschlagenen, zuerst NSArray, dann [String]:

var strings = myObjcObject.getStrings() as NSArray as [String] 

in einem Spielplatz Getestet mit:

import Foundation 

var objCMutableArray = NSMutableArray(array: ["a", "b", "c"]) 
var swiftArray = objCMutableArray as NSArray as [String] 

Update:

In späteren Versionen von Swift (mindestens 1.2), der Compiler wird sich beschweren über as [String]. Stattdessen sollten Sie einen if let mit einem bedingten gesenkten verwenden as?:

import Foundation 

var objCMutableArray = NSMutableArray(array: ["a", "b", "c"]) 
if let swiftArray = objCMutableArray as NSArray as? [String] { 
    // Use swiftArray here 
} 

Wenn Sie absolut sicher sind, dass Ihr NSMutableArray-[String] gegossen werden kann, dann können Sie as! stattdessen verwenden (aber Sie sollten wahrscheinlich nicht verwenden, um dies in den meisten Fällen):

import Foundation 

var objCMutableArray = NSMutableArray(array: ["a", "b", "c"]) 
var swiftArray = objCMutableArray as NSArray as! [String] 
+1

Vielen Dank für Ihre klare und präzise Antwort auf mein Problem kann betrachten! Es funktioniert jetzt! –

+0

Ich habe das verwendet, um mein Problem mit GestureRecognizers zu beheben. 'var arrayOfGestureRecognizers: [UIGestureRecognizer] = self.topViewController.view.gestureRecognizer! als NSArray als [UIGestureRecognizer] 'Danke! –

+0

@Mike, könnten Sie Ihre Antwort mit 'NSArray as aktualisieren! [String] 'für Swift 1.2? –

5

Mit Swift 1.2 folgendes funktioniert:

let mutableArray = NSMutableArray(array: ["a", "b", "c"]) 
let swiftArray = NSArray(array: mutableArray) as? [String] 
+0

Wenn ich dies mit Swift 1.2 versuche, bekomme ich: 'NSMutableArray' ist nicht konvertierbar zu "[AnyObject]"; Wolltest du 'wie!' niedergeschlagen werden? –

+0

Versuchen Sie es in Xcode 6.3 Beta Spielplatz? – Kasztan

2

in Xcode 6.3 i verwendet die folgenden Möglichkeiten:

var mutableArray = NSMutableArray(array:"1", "2", "3") 
let swiftArray = mutableArray as AnyObject as! [String] 
4
let mutableArray = NSMutableArray() 

mutableArray.addObject("Abc") 
mutableArray.addObject("def") 
mutableArray.addObject("ghi") 

if let array = mutableArray as? [String] { 
    print(array) // ["a", "b", "c"] 
} 
23

flatMap ist dein Freund in Swift 2.0 - 4.0.3. Dies bedeutet, dass Sie kein doppeltes oder erzwungenes Casting haben.

let mutableArray = NSMutableArray(array: ["a", "b", "c"]) 
let swiftArray: [String] = mutableArray.flatMap { $0 as? String } 

Bitte beachten Sie, dass mit Swift 4.1.0 (derzeit in der Beta) starten, flatMap in diesem speziellen Kontext zu compactMap veraltet und umbenannt wurde.

+1

Dies hat den Vorteil, dass, selbst wenn das Array ** nicht ** als Ganzes ** ** ** ** ** ** ** ** ** vom Typ 'String' /' NSString' ** ** sein kann "Kompatible" Elemente können noch gerettet werden. –

0

für eine schnelle 3

Sie den folgenden Code

let array: [String] = nsMutableArrayObject.copy() as! [String] 
Verwandte Themen