前提
Swiftではこのメソッドが呼び出したい。
func hoge(object: [String: AnyObject?]) {
}
Objective-cではこんな定義されているメソッド/プロパティを呼び出したい。
(気づく人は気づくかもしれませんが、TiledMap関連のコードです。。。)
@interface CCTiledMapObjectGroup : NSObject
@property (nonatomic,readwrite,strong) NSMutableArray *objects;
-(NSMutableDictionary*) objectNamed:(NSString *)objectName;
@end
NSMutableArray
これでいけそう・・・
let group = CCTiledMapObjectGroup() // ※実際はこんな感じでインスタンスを作ることは出来ないないクラス。(例として記載)
for object in group.objects {
hoge(object as! [String: AnyObject?])
}
コンパイルは通るが、実行時に以下のエラーが出力される。
Could not cast value of type '__NSDictionaryM' (0x799fa80c) to 'Swift.Dictionary<Swift.String, Swift.Optional<Swift.AnyObject>>' (0x7d4bf16c).
ということで、以下のメソッドでは受け取れないことがわかった。
func hoge(object: [String: AnyObject?]) {
}
なので指示通りSwift側のメソッドのAnyObject?→AnyObjectに変更。
let group = CCTiledMapObjectGroup() // ※実際はこんな感じでインスタンスを作ることは出来ないないクラス。(例として記載)
for object in group.objects {
hoge(object as! [String: AnyObject])
}
func hoge(object: [String: AnyObject]) {
}
いけた!
NSMutableDictionary
で、NSMutableDictionary。
NSMutableArrayができたのでハマることは無いと思っていた。
なぜならObjective-cで取得するobjects
の中身をピンポイントで取得する以下のobjectNamed
を呼び出すだけですから。
@interface CCTiledMapObjectGroup : NSObject
-(NSMutableDictionary*) objectNamed:(NSString *)objectName;
@end
これを以下のように取り出そうとした。
let group = CCTiledMapObjectGroup() // ※実際はこんな感じでインスタンスを作ることは出来ないないクラス。(例として記載)
if let object = group.objectNamed("name") {
hoge(object as! [String: AnyObject])
}
まさかのコンパイルエラー・・・
Cannot invoke 'hoge' with an argument list of type '([String : AnyObject])'
これではダメなのでAnyObject?へ元に戻してみた。
(このメソッドは上記のNSMutableArrayと共通で使うので、この例はダメなのだが検証のためやってみる。)
let group = CCTiledMapObjectGroup()
if let object = group.objectNamed("name") {
hoge(object as! [String: AnyObject?])
}
func hoge(object: [String: AnyObject?]) {
}
なんか、どっかで見たような警告文が表示されている・・・。
Cast from 'NSMutableDictionary' to unrelated type '[String : AnyObject?]' always fails
構わず実行!
Could not cast value of type 'NSMutableDictionary' (0x7fcd189c) to 'Swift.Dictionary<Swift.String, Swift.Optional<Swift.AnyObject>>' (0x7fcd176c).
まぁ、当然の結果。
うーん。とりあえず、以下のコードで出来たがなぞが残る。
let group = CCTiledMapObjectGroup()
if let object:NSDictionary = group.objectNamed("name") {
hoge(object as! [String: AnyObject])
}
func hoge(object: [String: AnyObject]) {
}
NSMutableDictionaryだとダメな模様。
NSDictionaryとして処理をさせればNSMutableArrayのところと同じようにキャストができる。
はじめはlet
の定義がダメなのかと思ってvar
に変えてみたりしたけど、、、関係ないみたい。
まとめ
SwiftからObjective-cのコードを呼び出すことは多々あるかと思います。
こういうケースに引っかかる人の役に立てればと思います。