因为要写原生插件,swift 刚接触,语法比 objc 好看多了。
在开发相机组件时遇到一个问题,AVCapturePhotoCaptureDelegate 契约用自定义 UIView/UIViewController 实现没问题, 换成独立的类实现就回调不了,不是什么原因。
上代码:
TakePhotoDelegate.swift
import Foundation
import AVFoundation
import UIKit
public typealias TakePhotoCallback = ((String, String) -> Void)?;
class TakePhotoWithCompletion : NSObject, AVCapturePhotoCaptureDelegate {
// ...
var completion: TakePhotoCallback;
init(callback: TakePhotoCallback) {
self.completion = callback;
super.init();
}
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
// todo sth
self.completion!("{file path}", "{error}");
}
}
CameraxView.swift
import AVFoundation
import UIKit
class CameraxView: UIView {
// ...
@objc
func takePhoto(options: Dictionary<String, String>, completion: TakePhotoCallback) {
let photoSettings = AVCapturePhotoSettings.init(format:[AVVideoCodecKey:AVVideoCodecType.jpeg])
let delegate = TakePhotoWithCompletion.init(callback: completion)
imageOutPut?.capturePhoto(with:photoSettings, delegate: delegate)
}
// ...
}
点击拍照按钮能听到快门声,但是 photoOutput 没有回调
如果换成如下自定义 UIView 实现 AVCapturePhotoCaptureDelegate 没有问题,能正常回调
import AVFoundation
import UIKit
class CameraxView: UIView, AVCapturePhotoCaptureDelegate {
// ...
var completion: TakePhotoCallback = nil;
@objc
func takePhoto(options: Dictionary<String, String>) {
let photoSettings = AVCapturePhotoSettings.init(format:[AVVideoCodecKey:AVVideoCodecType.jpeg])
self.completion = completion
imageOutPut?.capturePhoto(with:photoSettings, delegate: self)
}
@objc
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
// todo sth
self.completion!("{file path}", "{error}");
}
// ...
}
有这个差异的原因是因为系统 API 的限制吗还是 swift 语言层面问题, 如果 takePhoto 方法希望传闭包参数回调拍照结果,正确应该怎么写。
(回调参数赋值给实例对象, 个人感觉是个很奇怪的做法)