Swift 调用 Objective-C 包含块的包装函数

Swift call Objective-C wrapper function containing blocks

我有一个 Objective-C 包装器(ObjCWrapper.h 和 ObjCWrapper.m),原型为

+ (void) login:(NSString *)username andPassword:(NSString *)password andErrorBlock:(SuccessBlock)errorBlock andSuccessBlock:(SuccessBlock)successBlock;

有typedef

typedef void (^SuccessBlock)(NSString *);

和实施

+ (void)login:(NSString *)username andPassword:(NSString *)password andErrorBlock:(SuccessBlock)errorBlock andSuccessBlock:(SuccessBlock)successBlock
{
    // do stuff like
    successBlock(@"test");
}

从我的 swift 视图控制器 (ViewController.swift),我调用了登录函数:

ObjCWrapper.login("abc", andPassword: "abc",
        andErrorBlock:
        {
            (error:String) -> Void in
            println();
        },
        andSuccessBlock:
        {
            (map:String) -> Void in
            println();
        }
    )

但是我得到错误:

无法使用类型为“(String, andPassword: String, andErrorBlock:(String)->void, andSuccessBlock:(String)->void)”的参数列表调用 'login'

在 google 中搜索说我在参数中传递了一些无效类型,但我在代码中找不到任何错误。从函数中删除块使代码工作,所以我想这与调用块函数的方式有关。

感谢您的帮助!

可能值得向您的完成块添加可空性说明符:

typedef void (^SuccessBlock)( NSString * _Nonnull );

以及方法本身:

+ (void) login:(nonnull NSString *)username andPassword:(nonnull NSString *)password andErrorBlock:(nullable SuccessBlock)errorBlock andSuccessBlock:(nullable SuccessBlock)successBlock;

那么您应该可以在 Swift:

中调用您的方法
        ObjCWrapper.login("login", andPassword: "pass", andErrorBlock: { (error:String) -> Void in
        //error handling
        }) { (map:String) -> Void in
            //other stuff
    }

Obj-C NSString != Swift 字符串 换句话说,您在需要 NSString 的地方传递了一个 String。 放下它应该可以解决这个问题。

这就是我最后做的事情

let username = "username" //usernameField.text
let password = "password" //passwordField.text

        ObjCWrapper.login(username, andPassword: password,
            andErrorBlock:
            {
                (map) -> Void in
                // stuff
            })
            {
                (map) -> Void in
                // stuff
            }