在自定义键盘内添加相机视图 - Swift 3.0 和 IOS 10

Adding Camera View Inside Custom Keyboard - Swift 3.0 and IOS 10

如标​​题所示,我正在尝试在键盘的视图内添加摄像头,就像在当前“消息”应用程序内添加摄像头一样。

使用我当前的代码,当我尝试更改键盘时,键盘只是简单地被跳过,即使我在 info.plist 中设置了正确的键,它也从不请求访问相机的权限(我在键盘和主 class 的 info.plist 中设置它)。我没有写其他代码。

这是我的 KeyboardViewController 中的代码

import UIKit
import AVFoundation

class KeyboardViewController: UIInputViewController {

@IBOutlet weak var cameraView: UIView!
@IBOutlet var nextKeyboardButton: UIButton!

var session : AVCaptureSession?
var stillImageOutput : AVCaptureStillImageOutput?
var videoPreviewLayer : AVCaptureVideoPreviewLayer?

var captureDevice : AVCaptureDevice?

override func updateViewConstraints() {
    super.updateViewConstraints()

    // Add custom view sizing constraints here
}

override func viewDidLoad() {
    super.viewDidLoad()

    // Perform custom UI setup here
    self.nextKeyboardButton = UIButton(type: .system)

    self.nextKeyboardButton.setTitle(NSLocalizedString("Next Keyboard", comment: "Title for 'Next Keyboard' button"), for: [])
    self.nextKeyboardButton.sizeToFit()
    self.nextKeyboardButton.translatesAutoresizingMaskIntoConstraints = false

    self.nextKeyboardButton.addTarget(self, action: #selector(handleInputModeList(from:with:)), for: .allTouchEvents)

    self.view.addSubview(self.nextKeyboardButton)

    self.nextKeyboardButton.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
    self.nextKeyboardButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
}

override func viewWillAppear(_ animated: Bool) {

    session = AVCaptureSession()
    session!.sessionPreset = AVCaptureSessionPresetPhoto

    let videoDevices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo)

    for device in videoDevices! {

        let device = device as! AVCaptureDevice
        if device.position == AVCaptureDevicePosition.front {

            captureDevice = device

        }

    }

    //We will make a new AVCaptureDeviceInput and attempt to associate it with our backCamera input device.
    //There is a chance that the input device might not be available, so we will set up a try catch to handle any potential errors we might encounter.
    var error : NSError?
    var input : AVCaptureDeviceInput!
    do {

        input = try AVCaptureDeviceInput(device: captureDevice)

    } catch let error1 as NSError {

        error = error1
        input = nil
        print(error!.localizedDescription)

    }

    if error == nil && session!.canAddInput(input) {

        session!.addInput(input)

        // The remainder of the session setup will go here...

        stillImageOutput = AVCaptureStillImageOutput()
        stillImageOutput?.outputSettings = [AVVideoCodecKey : AVVideoCodecJPEG]

        if session!.canAddOutput(stillImageOutput) {

            session!.addOutput(stillImageOutput)

            //configure live preview here

            videoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
            videoPreviewLayer!.videoGravity = AVLayerVideoGravityResizeAspect
            videoPreviewLayer!.connection?.videoOrientation = AVCaptureVideoOrientation.portrait

            cameraView.layer.addSublayer(videoPreviewLayer!)

            session!.startRunning()

        }

    }

}

override func viewDidAppear(_ animated: Bool) {
    videoPreviewLayer!.frame = cameraView.bounds
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated
}

override func textWillChange(_ textInput: UITextInput?) {
    // The app is about to change the document's contents. Perform any preparation here.
}

override func textDidChange(_ textInput: UITextInput?) {
    // The app has just changed the document's contents, the document context has been updated.

    var textColor: UIColor
    let proxy = self.textDocumentProxy
    if proxy.keyboardAppearance == UIKeyboardAppearance.dark {
        textColor = UIColor.white
    } else {
        textColor = UIColor.black
    }
    self.nextKeyboardButton.setTitleColor(textColor, for: [])
}

}

您无权通过自定义键盘扩展访问相机。根据 Apple 指南,某些 API 不适用于 iOS 扩展。请查看 "Some APIs Are Unavailable to App Extensions" 下的 Appple Extensions guideline

Access the camera or microphone on an iOS device (an iMessage app, unlike other app extensions, does have access to these resources, as long as it correctly configures the NSCameraUsageDescription and NSMicrophoneUsageDescription Info.plist keys)

但是 iMessage 应用程序确实可以访问。