-
Notifications
You must be signed in to change notification settings - Fork 94
Description
I'm trying to run Microblink in my UIKit project, but I'm getting some errors I don't fully understand.
In my UIKit project, I'm integrating the CustomUIScanningView from the Microblink sample project.
Here's my implementation:
`
import UIKit
import SwiftUI
import Combine
import BlinkID
import BlinkIDUX
class ViewController: UIViewController {
let blinkIDViewModel = BlinkIDViewModel()
private var cancellables = Set()
let licencia = "xxxxxxxxxxxxxx"
@IBOutlet weak var btnLaunchLib: UIButton!
var activityView: UIView?
var activityIndicator: UIActivityIndicatorView?
override func viewDidLoad() {
super.viewDidLoad()
self.iniciarAnimacion()
let navbar = NavBarVC()
navbar.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(navbar)
NSLayoutConstraint.activate([
navbar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
navbar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
navbar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
navbar.heightAnchor.constraint(equalToConstant: 150)
])
navbar.updateProgressBar(progreso: .id)
}
func iniciarAnimacion() {
btnLaunchLib.isUserInteractionEnabled = false
btnLaunchLib.backgroundColor = .clear
// Configurar estado inicial de la animación
btnLaunchLib.transform = CGAffineTransform(scaleX: 0.95, y: 0.95) // Escala inicial
btnLaunchLib.alpha = 0.8 // Opacidad inicial
// Crear activityIndicator
activityIndicator = UIActivityIndicatorView(style: .medium)
activityIndicator?.translatesAutoresizingMaskIntoConstraints = false
activityIndicator?.startAnimating()
activityIndicator?.alpha = 0 // Inicialmente invisible
guard let activityIndicator = activityIndicator else { return }
btnLaunchLib.addSubview(activityIndicator)
NSLayoutConstraint.activate([
activityIndicator.centerXAnchor.constraint(equalTo: btnLaunchLib.centerXAnchor),
activityIndicator.centerYAnchor.constraint(equalTo: btnLaunchLib.centerYAnchor)
])
// Animación de entrada
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseInOut) {
self.btnLaunchLib.transform = .identity // Vuelve a tamaño original
self.btnLaunchLib.alpha = 1 // Opacidad completa
self.btnLaunchLib.configuration?.baseForegroundColor = .clear // Oculta el texto
activityIndicator.alpha = 1 // Muestra el activity
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let manager = ServiceManager()
manager.delegate = self
manager.getPublicKeyFT()
btnLaunchLib.layer.cornerRadius = 20
}
@IBAction func prepareForUnwind(segue: UIStoryboardSegue) {
print("prepareForUnwind")
}
func irAVistaResultados(con result: BlinkIDScanningResult) {
// Aquí haces segue o presentas el ViewController manualmente
guard let resultadosVC = storyboard?.instantiateViewController(withIdentifier: "ResultadosOCRViewController") as? ResultadosOCRViewController else {
return
}
// Pasa datos al VC de resultados
resultadosVC.resultadoEscaneo = result
self.present(resultadosVC, animated: true)
}
func createCustomScanningViewController() async throws -> UIViewController {
let settings = BlinkIDSdkSettings(
licenseKey: licencia,
downloadResources: true,
bundleURL: Bundle.main.bundleURL
)
let sdk = try await BlinkIDSdk.createBlinkIDSdk(withSettings: settings)
let scanningSettings = ScanningSettings(
croppedImageSettings: CroppedImageSettings(
returnDocumentImage: true,
returnFaceImage: true
)
)
let sessionSettings = BlinkIDSessionSettings(scanningSettings: scanningSettings)
let analyzer = try await BlinkIDAnalyzer(
sdk: sdk,
blinkIdSessionSettings: sessionSettings,
eventStream: BlinkIDEventStream()
)
let viewModel = CustomScanningViewModel(analyzer: analyzer)
let scanningView = CustomUIScanningView(viewModel: viewModel)
let hostingController = UIHostingController(rootView: scanningView)
hostingController.modalPresentationStyle = .fullScreen
viewModel.$scanningResult
.compactMap { $0 }
.first()
.sink { [weak self] result in
DispatchQueue.main.async {
hostingController.dismiss(animated: true) {
self?.irAVistaResultados(con: result)
}
}
}
.store(in: &self.cancellables)
return hostingController
}
@IBAction func didTapCustomUI(_ sender: Any) {
Task {
do {
let scannerVC = try await createCustomScanningViewController()
self.present(scannerVC, animated: true)
} catch {
print("❌ Error lanzando escáner personalizado: \(error.localizedDescription)")
}
}
}
}
extension ViewController: ServiceManagerProtocol{
func error(service: String) {
switch service {
case "getPublicKeyFT":
let manager = ServiceManager()
manager.delegate = self
manager.getPublicKeyFT()
break
default:
break
}
}
func returnPublicKey(theKey: String) {
let publickey = FaceTecConfig.init(JSONString: theKey)
AppConfig.shared.FTConfig = publickey
print("Public Face Scan Encryption Key: \(publickey?.productionKey?.publicFaceScanEncryptionKey ?? "No data")")
AppConfig.shared.expirationDate = publickey?.productionKey?.expiryDate ?? ""
AppConfig.shared.baseUrl = publickey?.productionKey?.baseURL ?? ""
AppConfig.shared.DeviceKI = publickey?.productionKey?.deviceKeyIdentifier ?? ""
AppConfig.shared.publicKey = publickey?.productionKey?.publicFaceScanEncryptionKey ?? ""
AppConfig.shared.prodKey = publickey?.productionKey?.key ?? ""
AppConfig.shared.appID = publickey?.productionKey?.appID ?? ""
DispatchQueue.main.async() {
UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseInOut) {
// Animación de salida del activity
self.activityIndicator?.alpha = 0
self.btnLaunchLib.configuration?.baseForegroundColor = .white
self.btnLaunchLib.backgroundColor = .accentColor1
} completion: { _ in
// Eliminar el activity después de la animación
self.activityIndicator?.stopAnimating()
self.activityIndicator?.removeFromSuperview()
// Animación adicional de "éxito"
UIView.animate(withDuration: 0.5,
delay: 0,
usingSpringWithDamping: 0.5,
initialSpringVelocity: 0.5,
options: .curveEaseInOut) {
self.btnLaunchLib.transform = CGAffineTransform(scaleX: 1.05, y: 1.05)
} completion: { _ in
UIView.animate(withDuration: 0.5) {
self.btnLaunchLib.transform = .identity
self.btnLaunchLib.isUserInteractionEnabled = true
}
}
}
}
}
}
`
If I set downloadResources to true, I get this message in the console:
The operation couldn't be completed. (BlinkID.InvalidLicenseKeyError error 1.)
[E] func [line::54] Provided license is invalid for product DocumentVerification. It is valid only for application IDs 'com.testdicio.IDDownloadSample', for products 'BlinkID', on platform 'iOS'. Please contact support for more information.
But if I set the downloadResources value to false, I get the following:
Model_2cd038a917eb424b973a73e06f0b96c99649b1fa43dcabd5bd19996c6e4aee4c.strop expected hash is '35260cfb1b7b5007632e596fb04abaf2c8d9fb1792ba5e3e727cdd1da1ff4c8c', but actual is 'missing file'
Model_4521998f12dfb7ceb1270a78f11efded1c61c91151c7b7ccc7d01796047f169a.strop expected hash is 'e45d7b9989c471a85907a7c355973c3427b5b2c08cb2af8c63d61a81eef91bc3', but current is 'missing file'
Model_d2bcaf18d17504513598e04f472c035b3d4f22d8653d5a79c05b4508a4b547b3.strop expected hash is '299ab7aeef01eb09cbdc9b2b8c1d2e6a6fe75ce98126688a4e43b9d887fb1599', but current is 'missing file'
Model_b901a610b69813465d5fd5ac34356dcf4fff1e51b31a0b60ae63592d28a1325c.strop expected hash is '36e6a9b02c3bb4b11ce6fd9b7676408a341b7ca01831cafcb93ccfd8fe8b9422', but current is 'missing file'
Model_abdf47396dafdacf87bc8650c081372e1b355ce20277f1fa47c5bbc79a003664.strop expected hash is '6f5682401a1705eb2f561ea649e5e72480d6ccd623b4e1827593dab83d89cc34', but current is 'missing file'
static_features.zzip expected hash is '6d202616abd8c0661063ab97f899c5881ad1a738c4db2e057d6f2ab0c041672c', but actual is 'cdc5240cdc7100dd9f1deff9e23a8cec61968ad38beaa73aca4e7fb4d20b075b'