【问题标题】:Call method with function as argument of Cocoa Touch Framework (swift) from Single View Application (objective-c)从单视图应用程序(objective-c)调用函数作为 Cocoa Touch Framework(swift)的参数的方法
【发布时间】:2016-11-08 02:44:01
【问题描述】:

我在swift(称为MyFramework)中创建了Cocoa Touch Framework。在 MyFramework 我有需要函数作为参数的方法。简而言之,MyFramework 包含以下代码:

public class MyFramework : NSObject {
    public func MyMethod(successCallback : (String) -> Void, errorCallback : (String, String) -> Void) -> Void {
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            // successCallback("some value");
            // errorCallback("error reason", "error message");
        });
    }
}

我可以将MyFramework 包含在Single View Application 中,称为MyAppSwift(在swift 中),并通过此代码成功调用ViewController.swift 中的MyFramework 的MyMethod

class ViewController: UIViewController {
    let myframework : MyFramework = MyFramework();

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        myframework.MyMethod(self.onSuccess, errorCallback : self.onError);
    }

    private func onSuccess(value : String) {
        // ... 
    }

    private func onError(reason : String, error : String) {
        // ...
    }
}

我可以在Single View Application 中包含MyFramework,称为MyAppObjectiveC(在objective-c 中),但我不知道如何在ViewController.m 中调用MyFramework 的MyMethod ...

// In ViewController.h

#import <UIKit/UIKit.h>
#import <MyFramework/MyFramework.h>
@interface ViewController : UIViewController {

}
@property (strong, nonatomic) MyFramework * myframework;
- (void) onSuccess : (NSString *) value;
- (void) onError : (NSString *) reason : (NSString *) error;
@end

.

// In ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void) viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.myframework = [[MyFramework alloc] init];
    [self.myframework MyMethod : self onSuccess, self onError];
}
- (void) onSuccess : (NSString *) value {
    // ...
}
- (void) onError : (NSString *) reason : (NSString *) error {
    // ...
}

@end

这一行 [self.myframework MyMethod : self onSuccess, self onError]; 不起作用。 Xcode 在 onSuccess 之后说期望标识符“:”,然后期望表达式。我不确定要插入什么。我读了几个关于stackoverflow如何在objective-c中将方法作为参数传递但没有成功的答案。例如,我尝试过选择器 [self.myframework MyMethod : @selector(onSuccess:), @selector(onError::)]; 但 Xcode 说:“将 'SEL' 发送到不兼容类型的参数' void(^_Nonnull)(NSString * _Nonnull __strong)'

【问题讨论】:

  • 在文件 MyFramework.framework/Headers/MyFramework-Swift.hi 中看到 MyMethod 在objective-c中声明为: - (void)MyMethod:(void (^ _Nonnull)(NSString * _Nonnull))successCallback;(没有errorCallback)和第二种选择:- (void)MyMethod:(void (^ _Nonnull)(NSString * _Nonnull))successCallback errorCallback:(void (^ _Nonnull)(NSString * _Nonnull, NSString * _Nonnull))errorCallback;

标签: ios objective-c swift function


【解决方案1】:

正如您所指出的,根据*-Swift.hheader Swift 的MyMethod 被导入到Objective-C 中,以blocks 作为参数。因此,您需要传递包装 Objective-C 方法调用的块,如下所示:

[self.myframework MyMethod: ^ (NSString * s){ [self onSuccess:s]; }
       errorCallback: ^(NSString * s1, NSString * s2) { [self onError:s1:s2]; }];

有关 Objective-C 块的更多信息,请参见此处:https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithBlocks/WorkingwithBlocks.html

【讨论】:

  • 感谢 OmniProg!效果很好!只是细节... errorCallback "[self onError:s1 reason:s2]" 应该是 [self onError:s1 error:s2] 吗?但是,我必须只写“[self onError:s1:s2]”(不带键),因为 xcode 说“'ViewController' 没有可见的@interface 声明选择器'onError:error:'”。
  • 抱歉,已更正。事实上,编译器是绝对正确的,像往常一样:为了让选择器成为onError:s1 error:s2,函数必须是- (void) onError : (NSString *) reason error : (NSString *) error
猜你喜欢
  • 2018-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-03
相关资源
最近更新 更多