简体   繁体   English

创建快速关闭并将其作为完成块传递给Objective-C类

[英]Create swift closure and pass it to objective-c class as completion block

Now I'm adding Swift code on objective-C based iOS application. 现在,我在基于Objective-C的iOS应用程序上添加Swift代码。

But I have a problem in calling the objective-C method from Swift side. 但是从Swift方面调用Objective-C方法时遇到问题。

I'd like to get and draw image on UIImageView in View or ViewController which is written with Swift. 我想在用Swift编写的ViewViewController UIImageView上获取和绘制图像。 On the other hand my wrapper class of Photos Library is written with objective-C. 另一方面,我的照片库包装器类是用Objective-C编写的。

My wrapper class of Photos Library is below. 我的照片库包装器类如下。

・MyPhotoLibraryMgr.h ・ MyPhotoLibraryMgr.h

typedef void (^AppPhotoLibraryGetImageCompletion)(UIImage *image, NSError *error);

- (void)getImageWithTarget:(NSInteger)index
                targetSize:(CGSize)targetSize
                completion:(AppPhotoLibraryGetImageCompletion)completion;

・MyPhotoLibraryMgr.m ・ MyPhotoLibraryMgr.m

- (void)getImageWithTarget:(NSInteger)index
                targetSize:(CGSize)targetSize
                completion:
(AppPhotoLibraryGetImageCompletion)completion
{
    PHAsset *asset = _myAsetsList[index];

    PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
    options.resizeMode = PHImageRequestOptionsResizeModeFast;
    options.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;

    [[PHImageManager defaultManager] requestImageForAsset:asset
                                               targetSize:targetSize
                                              contentMode:PHImageContentModeAspectFill
                                                  options:options
                                            resultHandler:^(UIImage *result, NSDictionary *info) {
                                                NSError *error = [info objectForKey:PHImageErrorKey];
                                                if (error) {
                                                    NSLog(@"error=%@", error);
                                                }
                                                completion(result, error);
                                            }];
}

I can get and draw image in View or ViewController written by objective-C like below, 我可以在由Objective-C编写的ViewViewController获取并绘制图像,如下所示,

・MyViewController.m ・ MyViewController.m

AppPhotoLibraryMgr *photoLibMgr = [AppPhotoLibraryMgr sharedInstance];
AppPhotoLibraryGetImageCompletion completion = ^(UIImage *image, NSError *error) {
                imageView.image = image;
};

[[AppPhotoLibraryMgr sharedInstance] getImageWithTarget:index
                                             targetSize:imageView.frame.size
                                             completion:completion];

But I can't get image in View or ViewController written in Swift. 但是我无法在用Swift编写的ViewViewController获得图像。

・MySwiftViewController.swift ・ MySwiftViewController.swift

let completion = {(image: UIImage, error: NSError) -> AppPhotoLibraryGetImageCompletion in
    let imageView = UIImageView(image: image)
}

photoLibMgr?.getImageWithTarget(index, targetSize: size, completion: completion)

Error message from Xcode is 来自Xcode的错误消息是


Cannot convert value of type 'UIImage, NSError -> AppPhotoLibraryGetImageCompletion" to expected argument type 'AppPhotoLibraryGetImageCompletion' 无法将类型'UIImage,NSError-> AppPhotoLibraryGetImageCompletion'的值转换为预期的参数类型'AppPhotoLibraryGetImageCompletion'

The block typedef void (^AppPhotoLibraryGetImageCompletion)(UIImage *image, NSError *error); typedef void (^AppPhotoLibraryGetImageCompletion)(UIImage *image, NSError *error); in objective-c has return type void . Objective-C中,返回类型为void

But the counter part in your Swift has return type other than Void . 但是Swift中的计数器部分具有Void以外的返回类型。 The completion block should be like: 完成块应类似于:

let completion = {(image: UIImage, error: NSError) -> Void in
    ...
    ...
}

Use typealias for making your closure reusable. 使用typealias使封闭可重用。

Example: 例:

typealias AppPhotoLibraryGetImageCompletion = (UIImage, NSError) -> Void

let completion: AppPhotoLibraryGetImageCompletion = { (image, error) in
    ...
    ...
}

Edit: Different way 编辑:不同的方式

photoLibMgr?.getImageWithTarget(index, targetSize: size, completion: { (image, error) in
    ...
    ...
})

Your declaration of completion variable is wrong in MySwiftViewController.swift file. 您的completion声明变量在MySwiftViewController.swift文件中是错误的。
Edit it like this: 像这样编辑它:

let completion: AppPhotoLibraryGetImageCompletion = { (image, error) in
   let imageView = UIImageView(image: image)
}

OR 要么
If you don't want to declare completion handler as variable, then simply do the: 如果您不想将完成处理程序声明为变量,则只需执行以下操作:

LinphoneLoginController.shared().getImageWithTarget(index, targetSize: size) { (image, error) in
    let imageView = UIImageView(image: image)
}

It should be typedef instead of Typedef . 它应该是typedef而不是Typedef Move typedef on top of interface declare and don't declare it again: typedef移动到接口声明的顶部,然后不再声明:

typedef void (^AppPhotoLibraryGetImageCompletion)(UIImage *image, NSError *error);

@interface MyPhotoLibraryMgr....

After the changes it should work similar in Swift , auto complete will change your AppPhotoLibraryGetImageCompletion to (image, error) {..} 更改后,它应在Swift类似地工作,自动完成将把您的AppPhotoLibraryGetImageCompletion更改为(image, error) {..}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM