应用程序在模拟器中工作正常,但在手机上无法正常运行

时间:2019-10-27 15:19:11

标签: ios swift iphone ocr

我正在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) 

1 个答案:

答案 0 :(得分:0)

[将来的读者摘要:]

原来是unrecognized selector崩溃; OP未能提及崩溃或崩溃日志(OP仅使用了“什么也没有发生”或“无法按下按钮”之类的短语),使诊断变得更加困难。但是我们最终到了那里。

但是,这有点不寻常 unrecognized selector,因为Cocoa无法识别的选择器是[Love_In_A_Snap.ViewController takePhoto:],我们可以很好地看到ViewController 具有该方法:

 @IBAction func takePhoto(_ sender: Any) {

最后,我们必须通过假设事物以某种方式变为“陈旧”来解决此问题。我们删除了情节提要中的连接并重新创建了它。这种固定的东西,但并非在每种情况下都如此。然后,我们从设备中删除了该应用程序,并清理了DerivedData文件夹,并对其进行了修复。