我正在iOS的Swift中创建一个OCR应用程序,它需要按下一个按钮(“快照/上传图像”),然后该按钮允许用户从其照片中选择图像或拍照。这在iPhone 11 pro max模拟器中完美运行,但是,在iPhone 8模拟器和iPhone 8本身上运行时,我收到错误消息,或者它不起作用。我已附上代码和错误。
import UIKit
import MobileCoreServices
import TesseractOCR
import GPUImage
class ViewController: UIViewController {
@IBOutlet weak var textView: UITextView!
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
}
// IBAction methods
@IBAction func backgroundTapped(_ sender: Any) {
view.endEditing(true)
}
@IBAction func takePhoto(_ sender: Any) {
let imagePickerActionSheet =
UIAlertController(title: "Snap/Upload Image",
message: nil,
preferredStyle: .actionSheet)
if UIImagePickerController.isSourceTypeAvailable(.camera) {
let cameraButton = UIAlertAction(
title: "Take Photo",
style: .default) { (alert) -> Void in
self.activityIndicator.startAnimating()
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .camera
imagePicker.mediaTypes = [kUTTypeImage as String]
self.present(imagePicker, animated: true, completion: {
self.activityIndicator.stopAnimating()
})
}
imagePickerActionSheet.addAction(cameraButton)
}
let libraryButton = UIAlertAction(
title: "Choose Existing",
style: .default) { (alert) -> Void in
self.activityIndicator.startAnimating()
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
imagePicker.mediaTypes = [kUTTypeImage as String]
self.present(imagePicker, animated: true, completion: {
self.activityIndicator.stopAnimating()
})
}
imagePickerActionSheet.addAction(libraryButton)
let cancelButton = UIAlertAction(title: "Cancel", style: .cancel)
imagePickerActionSheet.addAction(cancelButton)
present(imagePickerActionSheet, animated: true)
}
// Tesseract Image Recognition
func performImageRecognition(_ image: UIImage) {
let scaledImage = image.scaledImage(1000) ?? image
let preprocessedImage = scaledImage.preprocessedImage() ?? scaledImage
if let tesseract = G8Tesseract(language: "eng+fra") {
tesseract.engineMode = .tesseractCubeCombined
tesseract.pageSegmentationMode = .auto
tesseract.image = preprocessedImage
tesseract.recognize()
textView.text = tesseract.recognizedText
}
activityIndicator.stopAnimating()
}
}
// MARK: - UINavigationControllerDelegate
extension ViewController: UINavigationControllerDelegate {
}
// MARK: - UIImagePickerControllerDelegate
extension ViewController: UIImagePickerControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard let selectedPhoto =
info[.originalImage] as? UIImage else {
dismiss(animated: true)
return
}
activityIndicator.startAnimating()
dismiss(animated: true) {
self.performImageRecognition(selectedPhoto)
}
}
}
// MARK: - UIImage extension
extension UIImage {
func scaledImage(_ maxDimension: CGFloat) -> UIImage? {
var scaledSize = CGSize(width: maxDimension, height: maxDimension)
if size.width > size.height {
scaledSize.height = size.height / size.width * scaledSize.width
} else {
scaledSize.width = size.width / size.height * scaledSize.height
}
UIGraphicsBeginImageContext(scaledSize)
draw(in: CGRect(origin: .zero, size: scaledSize))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return scaledImage
}
func preprocessedImage() -> UIImage? {
let stillImageFilter = GPUImageAdaptiveThresholdFilter()
stillImageFilter.blurRadiusInPixels = 15.0
let filteredImage = stillImageFilter.image(byFilteringImage: self)
return filteredImage
}
}
[显示“快照/上传图像”及其限制的位置] [1]
当应用程序在iphone 11 max pro模拟器上运行时,它可以工作,但是在iphone 8模拟器上,这是我拥有的设备,会导致此错误
[错误] [2]
在控制台中:
2019-10-28 17:51:50.440498+0000 Love In A Snap[14813:703702] -[Love_In_A_Snap.ViewController takePhoto:]: unrecognized selector sent to instance 0x7fe503d06d50
2019-10-28 17:51:50.454363+0000 Love In A Snap[14813:703702] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Love_In_A_Snap.ViewController takePhoto:]: unrecognized selector sent to instance 0x7fe503d06d50'
*** First throw call stack:
(
0 CoreFoundation 0x000000010e63d1ee __exceptionPreprocess + 350
1 libobjc.A.dylib 0x000000010c275b20 objc_exception_throw + 48
2 CoreFoundation 0x000000010e65e154 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
3 UIKitCore 0x0000000119832e79 -[UIResponder doesNotRecognizeSelector:] + 302
4 CoreFoundation 0x000000010e641f6c ___forwarding___ + 1436
5 CoreFoundation 0x000000010e6440f8 _CF_forwarding_prep_0 + 120
6 UIKitCore 0x0000000119806082 -[UIApplication sendAction:to:from:forEvent:] + 83
7 UIKitCore 0x00000001191ec8e5 -[UIControl sendAction:to:forEvent:] + 223
8 UIKitCore 0x00000001191ecc2f -[UIControl _sendActionsForEvents:withEvent:] + 398
9 UIKitCore 0x00000001191ebb8e -[UIControl touchesEnded:withEvent:] + 481
10 UIKitCore 0x0000000119840a31 -[UIWindow _sendTouchesForEvent:] + 2604
11 UIKitCore 0x0000000119842338 -[UIWindow sendEvent:] + 4596
12 UIKitCore 0x000000011981d693 -[UIApplication sendEvent:] + 356
13 UIKitCore 0x000000011989de5a __dispatchPreprocessedEventFromEventQueue + 6847
14 UIKitCore 0x00000001198a0920 __handleEventQueueInternal + 5980
15 CoreFoundation 0x000000010e5a0271 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
16 CoreFoundation 0x000000010e5a019c __CFRunLoopDoSource0 + 76
17 CoreFoundation 0x000000010e59f974 __CFRunLoopDoSources0 + 180
18 CoreFoundation 0x000000010e59a67f __CFRunLoopRun + 1263
19 CoreFoundation 0x000000010e599e66 CFRunLoopRunSpecific + 438
20 GraphicsServices 0x000000011055dbb0 GSEventRunModal + 65
21 UIKitCore 0x0000000119804dd0 UIApplicationMain + 1621
22 Love In A Snap 0x000000010a61132b main + 75
23 libdyld.dylib 0x000000010d132d29 start + 1
24 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
答案 0 :(得分:0)
[将来的读者摘要:]
原来是unrecognized selector
崩溃; OP未能提及崩溃或崩溃日志(OP仅使用了“什么也没有发生”或“无法按下按钮”之类的短语),使诊断变得更加困难。但是我们最终到了那里。
但是,这有点不寻常 unrecognized selector
,因为Cocoa无法识别的选择器是[Love_In_A_Snap.ViewController takePhoto:]
,我们可以很好地看到ViewController 具有该方法:
@IBAction func takePhoto(_ sender: Any) {
最后,我们必须通过假设事物以某种方式变为“陈旧”来解决此问题。我们删除了情节提要中的连接并重新创建了它。这种固定的东西,但并非在每种情况下都如此。然后,我们从设备中删除了该应用程序,并清理了DerivedData文件夹,并对其进行了修复。