'Any' 无法转换为 'AVCaptureDevice' 将 Objective C 转换为 Swift 时出错
'Any' is not convertible to 'AVCaptureDevice' error translating Objective C to Swift
我正在重建 Google Mobile Vision "Googly Eyes" demo Swift 3. 我几乎想通了,但我一直在翻译从 Objective C 到 Swift 的函数。
演示视图控制器中的Objective C函数是:
- (AVCaptureDeviceInput *)cameraForPosition:(AVCaptureDevicePosition)desiredPosition {
BOOL hadError = NO;
for (AVCaptureDevice *device in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
if ([device position] == desiredPosition) {
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
error:&error];
if (error) {
hadError = YES;
NSLog(@"Could not initialize for AVMediaTypeVideo for device %@", device);
} else if ([self.session canAddInput:input]) {
return input;
}
}
}
if (!hadError) {
NSLog(@"No camera found for requested orientation");
}
return nil;
}
我已将其翻译成以下内容:
func camera(for desiredPosition: AVCaptureDevicePosition) -> AVCaptureDeviceInput {
var hadError: Bool = false
for device: AVCaptureDevice in AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) { // ERROR ON THIS LINE
if device.position() == desiredPosition {
var error: Error? = nil
let input = try? AVCaptureDeviceInput(device: device)
if error != nil {
hadError = true
print("Could not initialize for AVMediaTypeVideo for device \(device)")
}
else if session.canAdd(input!) {
return input!
}
}
}
if !hadError {
print("No camera found for requested orientation")
}
}
我遇到的错误在第 3 行 (for device: AVCaptureDevice in AVCaptureDevice.devices...
)。错误是:'Any' is not convertible to 'AVCaptureDevice'
。我对 Objective C 不是很熟悉并且之前从未使用过 AVCaptureSession 所以我一直在努力弄清楚它。关于我需要如何重写此 "for device" 语句的任何建议?
假设您使用 Xcode 的最新发布版本。在 post.
时是 Xcode 8.3.3
我给你看一些简化案例的代码。
案例一
继续使用已弃用的方法(不推荐):
func camera(for desiredPosition: AVCaptureDevicePosition) -> AVCaptureDeviceInput? {
var hadError: Bool = false
for device in AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) as! [AVCaptureDevice] { //### You need to cast
if device.position == desiredPosition {
do {
let input = try AVCaptureDeviceInput(device: device)
if session.canAddInput(input) { //###<-
return input
}
} catch {
hadError = true
print("Could not initialize for AVMediaTypeVideo for device \(device) with \(error)")
}
}
}
if !hadError {
print("No camera found for requested orientation")
}
return nil
}
devices(withMediaType:)
的return类型是[Any]!
,所以如果想把每个元素都当成AVCaptureDevice
,就需要强制转换
与您的代码类似,但我修复了一些部分,canAdd
到 canAddInput
和错误处理。
案例二
使用 AVCaptureDeviceDiscoverySession
忽略比 10.0 更旧的 iOS 版本。
func camera(for desiredPosition: AVCaptureDevicePosition) -> AVCaptureDeviceInput? {
var hadError: Bool = false
for device in AVCaptureDeviceDiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: desiredPosition).devices {
do {
let input = try AVCaptureDeviceInput(device: device)
if session.canAddInput(input) {
return input
}
} catch {
hadError = true
print("Could not initialize for AVMediaTypeVideo for device \(device) with \(error)")
}
}
if !hadError {
print("No camera found for requested orientation")
}
return nil
}
使用AVCaptureDeviceDiscoverySession
的简单示例,.builtInWideAngleCamera
在双摄像头设备上匹配前置摄像头、普通后置摄像头和广角摄像头。
注意
上述代码中的很多方法在Swift4/Xcode9中改变了它们的签名,包括return类型。在 iOS SDK 11 中,有一个很好的方法:
我正在重建 Google Mobile Vision "Googly Eyes" demo Swift 3. 我几乎想通了,但我一直在翻译从 Objective C 到 Swift 的函数。
演示视图控制器中的Objective C函数是:
- (AVCaptureDeviceInput *)cameraForPosition:(AVCaptureDevicePosition)desiredPosition {
BOOL hadError = NO;
for (AVCaptureDevice *device in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
if ([device position] == desiredPosition) {
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
error:&error];
if (error) {
hadError = YES;
NSLog(@"Could not initialize for AVMediaTypeVideo for device %@", device);
} else if ([self.session canAddInput:input]) {
return input;
}
}
}
if (!hadError) {
NSLog(@"No camera found for requested orientation");
}
return nil;
}
我已将其翻译成以下内容:
func camera(for desiredPosition: AVCaptureDevicePosition) -> AVCaptureDeviceInput {
var hadError: Bool = false
for device: AVCaptureDevice in AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) { // ERROR ON THIS LINE
if device.position() == desiredPosition {
var error: Error? = nil
let input = try? AVCaptureDeviceInput(device: device)
if error != nil {
hadError = true
print("Could not initialize for AVMediaTypeVideo for device \(device)")
}
else if session.canAdd(input!) {
return input!
}
}
}
if !hadError {
print("No camera found for requested orientation")
}
}
我遇到的错误在第 3 行 (for device: AVCaptureDevice in AVCaptureDevice.devices...
)。错误是:'Any' is not convertible to 'AVCaptureDevice'
。我对 Objective C 不是很熟悉并且之前从未使用过 AVCaptureSession 所以我一直在努力弄清楚它。关于我需要如何重写此 "for device" 语句的任何建议?
假设您使用 Xcode 的最新发布版本。在 post.
时是 Xcode 8.3.3我给你看一些简化案例的代码。
案例一
继续使用已弃用的方法(不推荐):
func camera(for desiredPosition: AVCaptureDevicePosition) -> AVCaptureDeviceInput? {
var hadError: Bool = false
for device in AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) as! [AVCaptureDevice] { //### You need to cast
if device.position == desiredPosition {
do {
let input = try AVCaptureDeviceInput(device: device)
if session.canAddInput(input) { //###<-
return input
}
} catch {
hadError = true
print("Could not initialize for AVMediaTypeVideo for device \(device) with \(error)")
}
}
}
if !hadError {
print("No camera found for requested orientation")
}
return nil
}
devices(withMediaType:)
的return类型是[Any]!
,所以如果想把每个元素都当成AVCaptureDevice
,就需要强制转换
与您的代码类似,但我修复了一些部分,canAdd
到 canAddInput
和错误处理。
案例二
使用 AVCaptureDeviceDiscoverySession
忽略比 10.0 更旧的 iOS 版本。
func camera(for desiredPosition: AVCaptureDevicePosition) -> AVCaptureDeviceInput? {
var hadError: Bool = false
for device in AVCaptureDeviceDiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: desiredPosition).devices {
do {
let input = try AVCaptureDeviceInput(device: device)
if session.canAddInput(input) {
return input
}
} catch {
hadError = true
print("Could not initialize for AVMediaTypeVideo for device \(device) with \(error)")
}
}
if !hadError {
print("No camera found for requested orientation")
}
return nil
}
使用AVCaptureDeviceDiscoverySession
的简单示例,.builtInWideAngleCamera
在双摄像头设备上匹配前置摄像头、普通后置摄像头和广角摄像头。
注意
上述代码中的很多方法在Swift4/Xcode9中改变了它们的签名,包括return类型。在 iOS SDK 11 中,有一个很好的方法: