0

I've done this tutorial http://rdcworld-iphone.blogspot.com.au/2013/03/how-to-use-barcode-scanner-br-and-qr-in.html

I'm using the iPhone simulator on IOS SDK 7.1, Xcode 5.1.1, Mac OSX 10.9.4 and objective c. What is supposed to happen when I run the program is as follows:

1) I click the scan button on the window which first appears

2) I get the option to select an image to scan in the iPhone photo album

3) I select an QR or Barcode

4) It scans the barcode

5) It determines the value and displays that on the screen along with a small version of the scanned image.

What actually happens is it gets up to step 4 fine and the method with scans the image runs to completion (startScanning). However instead of doing step 5 it shows a huge version of the barcode on the screen and the method which preforms step 5 is never called (didFinishPickingMediaWithInfo).

Contents of ViewController.h

//
//  ViewController.h
//  BarCodeScannerDemo
//
//  Created by RDC on 3/11/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "ZBarSDK.h"

@interface ViewController : UIViewController<ZBarReaderDelegate>

@property (weak, nonatomic) IBOutlet UIImageView *resultImageView;
@property (weak, nonatomic) IBOutlet UITextView *resultTextView;
- (IBAction)startScanning:(id)sender;

@end

Contents of ViewController.m

//
//  ViewController.m
//  BarCodeScannerDemo
//
//  Created by RDC on 3/11/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
@end

@implementation ViewController

@synthesize resultImageView;
@synthesize resultTextView;

#pragma mark - ViewController's LifeCycle methods

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"View did load");
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    NSLog(@"Did receive memory warning");
}

#pragma mark - Button click method


- (IBAction)startScanning:(id)sender
{
    NSLog(@"Scanning..");
    resultTextView.text = @"Scanning..";

    //Create a reader
    ZBarReaderViewController *codeReader = [ZBarReaderViewController new];
    //Setup a delegate to recieve the results
    //The delegate implements the ZBarReaderDelegate protocol, which inherits from UIImagePickerControllerDelegate
    codeReader.readerDelegate= self;

    codeReader.supportedOrientationsMask = ZBarOrientationMaskAll;

    ZBarImageScanner *scanner = codeReader.scanner;
    [scanner setSymbology: ZBAR_I25 config: ZBAR_CFG_ENABLE to: 0];

    [self presentViewController:codeReader animated:YES completion:nil];
    NSLog(@"End Start Scanning method");

}

#pragma mark - ZBar's Delegate method
//Called when a barcode is successsfully decoded
//reader is the reader controller instance that read the barcodes
- (void) imagePickerController: (UIImagePickerController*) reader didFinishPickingMediaWithInfo: (NSDictionary*) info
{
    NSLog(@"Decode results...");


    //  get the decode results
    id<NSFastEnumeration> results = [info objectForKey: ZBarReaderControllerResults];

    ZBarSymbol *symbol = nil;
    for(symbol in results)
        break;// just grab the first barcode

    // showing the result on textview
    resultTextView.text = symbol.data;

    resultImageView.image = [info objectForKey: UIImagePickerControllerOriginalImage];

    // dismiss the controller
    [reader dismissViewControllerAnimated:YES completion:nil];
}


-(void) readerControllerDidFailToRead:(ZBarReaderController *)reader withRetry:(BOOL)retry
{
    NSLog(@"readerControllerDidFailToRead");
    //If retry parameter is NO controller must be dismissed.
    if(retry==NO)
        reader=nil;
}

@end

Contents of AppDelegate.h

//
//  AppDelegate.h
//  BarCodeScannerDemo
//
//  Created by RDC on 3/11/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import <UIKit/UIKit.h>

@class ViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) ViewController *viewController;

@end

Contents of AppDelegate.m

//
//  AppDelegate.m
//  BarcodeScannerDemo
//
//  Created by Airefrig Australia on 18/07/2014.
//  Copyright (c) 2014 RDCWorld. All rights reserved.
//

#import "AppDelegate.h"
#import "ViewController.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end

I have spent many hours trying to find a solution to this and I haven't found anything which has provided a solution. The only person I've seen to have a problem like mine is on the tutorial page comments section but they never got a reply.

Please help!

Edit:

The image that is displayed is rotated at 90 degrees. Also I am new to objective c so if you provide code please explain why the difference should make an effect. I want to improve my knowledge =)

Edit: Solution

Since I can't answer my own question less then 8 hours after asking, here is what I found:

Upon reading the ZBarSDK API reference about ZBarReaderViewController here: http://zbar.sourceforge.net/iphone/sdkdoc/ZBarReaderViewController.html

It says "This is the controller to use for live scanning from the camera feed with automatic capture. For scanning from image files or with manual capture, see ZBarReaderController."

This means that the ZBarReaderViewController object setup in startScanning method is not what is supposed to be there. Well, not for scanning a static image. I'll have to test the original code with an actual device rather than a Mac but it seems ZBarReaderController is what I really want.

The new startScanning method now looks like this:

- (IBAction)startScanning:(id)sender
{
    resultTextView.text = @"Scanning..";

    //Create a reader
    ZBarReaderViewController *codeReader = [ZBarReaderController new];
    //Setup a delegate to recieve the results
    //The delegate implements the ZBarReaderDelegate protocol, which inherits from UIImagePickerControllerDelegate
    codeReader.readerDelegate= self;

    [codeReader.scanner setSymbology: ZBAR_I25 config: ZBAR_CFG_ENABLE to: 0];

    [self presentViewController:codeReader animated:YES completion:nil];

}

When testing I noted that images with a transparent background (such as the QR code and Barcode images provided on the tutorial site) do not work - you'll get a message saying no code found. You should save them as a jpg file with a white background.

I don't know if there should be anything else done to this since I only renamed an object and deleted a few code lines which gave errors - but the program does run the way I expect it to at the moment. If I have any future issues I'll post a new question.

SOair
  • 173
  • 1
  • 3
  • 14

1 Answers1

0

Try this code.

ZBarReaderViewController *codeReader = [ZBarReaderViewController new];
codeReader.readerDelegate= self;
codeReader.supportedOrientationsMask = ZBarOrientationMaskAll;
[codeReader.scanner setSymbology:ZBAR_I25 config:ZBAR_CFG_ENABLE to:0];
[codeReader.readerView start];

[self presentViewController:codeReader animated:YES completion:nil];

Below is optional =)

[codeReader.readerView setZoom:2];
codeReader.view.frame = self.view.bounds;
Ryan
  • 4,799
  • 1
  • 29
  • 56
  • Thank you for you quick reply! =) I replaced the contents of startScanning with that code and then attempted the option code (inserted just before the presentViewController line) but it appears to have the same issue. I should add that the image that displays is rotated 90 degrees as well as covering the screen. Also I am new to objective c so I am not sure what the effect of replacing the scanner object with just codeReader.scanner. I'll update the original post to reflect all this. – SOair Jul 22 '14 at 01:58
  • Are you sure that `-(void) imagePickerController: (UIImagePickerController*) reader didFinishPickingMediaWithInfo: (NSDictionary*) info` is never invoked? You have a line of code `resultImageView.image = [info objectForKey: UIImagePickerControllerOriginalImage];` in it. I guess this makes the barcode image on your screen. – Ryan Jul 22 '14 at 02:02
  • I say it is not invoked because I put in NSlog statements and they do not appear in the message log. This could be my lack of knowledge speaking though. Is there any alternative method of display messages/error messages/exceptions? – SOair Jul 22 '14 at 02:05
  • You can use breakpoint. How do you know `4) It scans the barcode` is fine? If it's fine, the delegate method must be invoked. Isn't `huge version of the barcode on the screen ` the `resultImageView`? – Ryan Jul 22 '14 at 02:25
  • I inserted a breakpoint at the beginning of didFinishPickingMediaWithInfo but the program didn't stop when it should have been reached. In reguards to resultImageView I also tried commenting out the entire contents of didFinishPickingMediaWithInfo but the giant screen filling image still appeared. When the large transparent barcode appears I still see the screen that asks me to go to photos by pressing down 2 fingers. – SOair Jul 22 '14 at 02:50