Skip to content

Implementando um leitor QRCode em iOS

Implementando um leitor QRCode em iOS

Bom pessoal vamos fazer mais um tutorial de objective C hoje vamos criar um leitor de QRCode ( caso você não saiba exatamente o que é um segue um link para dar uma introdução sobre o que são e como funcionam). OK vamos la nosso leitor será algo extremamente simples porem bem legal e não é tão complexo de se fazer, vamos começar com uma singleView.

Em nosso storyboard vamos inserir 1 View, 1 label e por fim 1 botão, nosso tela fica mais ou menos assim:

storyboard

Ainda em nosso storyboard já vamos criar as properties , e também uma ação para nosso botão:

@property (weak, nonatomic) IBOutlet UIView *CapturaDela;

@property (weak, nonatomic) IBOutlet UILabel *status;

@property (weak, nonatomic) IBOutlet UIButton *botaoLerCodigo;

  • (IBAction)lerCodigo:(UIButton *)sender;

Como em nosso projeto vamos precisar acessar alguns dados sobre a câmera, vamos importar a classe AVFoundation caso não tenha sido importada ainda , e importe também o protocolo AVCaptureMetadataOutputObjectsDelegate.

Partindo para nosso .m

Antes de mais nada vamos criar 4 properties dentro de @interface ViewController ()

@property (nonatomic, strong) AVCaptureSession *captureSession;

@property (nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewLayer;

@property (nonatomic, strong) AVAudioPlayer *audioPlayer;

@property (nonatomic) BOOL estaLendo;

Essas propertys serão as responsáveis por gravar as imagens, e também trabalham com o áudio.

Feito isso a próxima coisa a se fazer é importar nosso áudio, o beep.mp3 do download está aqui, com o nosso beep já dentro do projeto vamos desenvolver um método para que o som seja pré-carregado e que seja apenas executado quando necessário, vamos então criar nosso método preCarregarBeep, nosso método fica assim:

-(void)preCarregarBeep{

// neste metodo vai fazer o seguite, ele vai deixar nosso beep para ser executado na hora que precisar

// criamos a string que contem o nome do nosso arquivo e sua extensão

NSString *beepFilePath = [[NSBundle mainBundle] pathForResource:@”beep” ofType:@”mp3″];

// criamos agora uma NSURL usando nosso arquivo anterior

NSURL *beepURL = [NSURL URLWithString:beepFilePath];

// vamos fazer um tratamento de erros, caso não tenhamos erro com nosso arquivo vamos deixar nosso beep pronto para ser executado

NSError *error;

_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:beepURL error:&error];

if (error) {

NSLog(@”Erro ao abrir o som”);

NSLog(@”%@”, [error localizedDescription]);

}

else{

[_audioPlayer prepareToPlay];

}

O próximo método que vamos criar é o comecarALer esse método será disparado quando o usuário clicar no botão para começar a verificar o código.

-(BOOL)comecarALer{

NSError *error;

// criamos nossas instancias de captura de imagem

AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];

if (!input) {

// Se acontecer algum erro vai dar um log no erro

NSLog(@”%@”, [error localizedDescription]);

return NO;

}

// inicia a captura de imagem

self.captureSession = [[AVCaptureSession alloc] init];

[self.captureSession addInput:input];

AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];

[self.captureSession addOutput:captureMetadataOutput];

// Create um novo serial dispatch queue.

dispatch_queue_t dispatchQueue;

dispatchQueue = dispatch_queue_create(“myQueue”, NULL);

[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];

[captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]];

//inicia o video preview e atribui ele a nossa view.

_videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];

[_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];

[_videoPreviewLayer setFrame:self.CapturaDela.layer.bounds];

[self.CapturaDela.layer addSublayer:_videoPreviewLayer];

// começa a captura de tela

[self.captureSession startRunning];

return YES;

}

Criamos um método do tipo booleano pois vamos nos basear na resposta do método para determinar se o código conseguiu ou não executar a leitura.

Bom já temos o método que executa nosso beep, e já temos a leitura do código o que ainda falta? Ainda precisamos que pare a leitura do código afinal se não fecharmos o acesso a camera ela ficaria ainda funcionando, então vamos la vamos criar o método parandoLeitura.

-(void)parandoLeitura{

// para a captura de video

[self.captureSession stopRunning];

self.captureSession = nil;

// Remove o preview do video da view

[self.videoPreviewLayer removeFromSuperlayer];

}

Estamos quase lá aguentem só mais um pouco, vamos ao nosso último método, e esse é o responsável por fazer a mágica, ele realiza a ligação entre o que a câmera está registrando e o que aparecerá na view.

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{

// esse metodo é onde “ligamos” nossa camera para fazer a leitura

// checa se o metadataObjects array não é vazio, e que contem ao menos 1 objeto

if (metadataObjects != nil && [metadataObjects count] > 0) {

AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];

if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {

[self.status performSelectorOnMainThread:@selector(setText:) withObject:[metadataObj stringValue] waitUntilDone:NO];

[self performSelectorOnMainThread:@selector(parandoLeitura) withObject:nil waitUntilDone:NO];

[self.botaoLerCodigo performSelectorOnMainThread:@selector(setTitle:) withObject:@”Start!” waitUntilDone:NO];

self.estaLendo = NO;

// lembra do primeiro metodo que criamos, então agora que utilizamo ele

// verifica se nosso audio não for nil executa o som

if (_audioPlayer) {

[_audioPlayer play];

}

}

}

}

Bom pessoal é isso, já temos todos os métodos criados, vamos “chama-los”, lembram da action que criamos no início do projeto dentro dele chamaremos os métodos que acabamos de criar nossa action ficou da seguinte maneira.

– (IBAction)lerCodigo:(UIButton *)sender {

// precisamos primeiramente verificar se nosso usuario já não esta lendo algum código

if (!_estaLendo) {

if ([self comecarALer]) {

self.botaoLerCodigo.enabled = NO;

self.status.text = @”Escaneando código”;

}else{

[self parandoLeitura];

}

}

// inverte o valor de nosso booleano para que nossa action possa ser executa de novo

self.estaLendo = !self.estaLendo;

}

Agora só falta testar o código, lembrando que o código não pode ser testado no simulador pois o simulador não tem camera instalado no simulador faça um teste e tente ler o QRCode abaixo:

qr_code_without_logo

Esse é o link para o download do projeto completo.

Objective-C
Xcode 6.1
iOS 8.1

No comment yet, add your voice below!


Add a Comment

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *