在闭包中输入Error(从obj c到swift的已翻译代码)

时间:2014-07-31 23:01:45

标签: objective-c swift xcode6

我正在尝试使用在我的swift应用程序中用目标c编写的库。 我试图将自述文件中的代码段转换为快速代码 - 但是我得到了一个我不理解的类型错误。

自述文件中的Obj.C代码:

[self.client logonWithUsername:self.username.text password:self.password.text responseCallback:^(NSDictionary *response, NSError *error) {
    if (error) {
        [self handleFailedAuth:error];
        return;
    }
    [self handleSuccessfulAuth];
}];

我对swift的翻译:

    var username = NSUserDefaults.standardUserDefaults().stringForKey("username")
    var password = NSUserDefaults.standardUserDefaults().stringForKey("password")

    client.logonWithUsername(username, password: password, responseCallback: {
        (response: NSDictionary, error: NSError) in
            if(error){
                handleFailedAuth(error)
                return;
            }
            handleSuccessfulAuth()
        }
    )

我得到[NSObject:AnyObject]!在定义闭包参数的行上,它不是NSDictionary的子类型。怎么可能?我使用的是与示例中相同的类型。

2 个答案:

答案 0 :(得分:0)

你的Swift应该阅读以下内容:

var username = NSUserDefaults.standardUserDefaults().stringForKey("username")
    var password = NSUserDefaults.standardUserDefaults().stringForKey("password")

    client.logonWithUsername(username, password: password, responseCallback: {
        (response: NSDictionary?, error: NSError?) in
            if(error){
                handleFailedAuth(error!)
                return;
            }
            handleSuccessfulAuth()
        }
    )

这是因为Swift选项在某些方面取代了你在objective-c中传递nil的方式。因为NSDictionary可能是nil并且NSError可能是nil,你在它们之后添加一个?-mark,然后当你需要访问它的值时,在块内有条件地解包w!-mark

答案 1 :(得分:0)

您在Swift中明确指定了block / closure参数类型,而Swift编译器没有关于NSDictionary的足够信息。这是因为Swift Dictionary的输入类型比Objective-C NSDictionary更强。

错误消息(不可否认,非常隐蔽)说明Swift所期望的确切类型是Dictionary<NSObject, AnyObject>!

有几种方法可以解决这个问题。一个是在Swift闭包定义中更明确地说明你的NSDictionary参数: -

  client.logonWithUsername(username, password: password, responseCallback: {
    (response: Dictionary<NSObject, AnyObject>!, error: NSError) in
      // ... handler body
      }
  )

一种更简单的方法是不要试图告诉Swift关于类型的东西,让编译器推断它需要什么: -

  client.logonWithUsername(username, password: password, responseCallback: {
    response, error in
      // ... handler body
      }
  )