2012年7月4日水曜日

iOSでQRコードを読み込む(ZXing 2.0)

ちょっと前に Android で Zxing を使ってQRコードを読み込んでました。
http://teru2-bo2.blogspot.jp/2012/06/androidqrzxing.html

ZXing はiOS用のライブラリも持っているので今回もZXingを使ってQRコードを読み込んでみました。
READMEもサンプルもあるんでそれをそのまま動かせばなんとなく動きはわかると思いますが自分も忘れないように。

とりあえずライブラリをダウンロードして解凍しておきます。
http://code.google.com/p/zxing/downloads/list

Xcodeを起動してプロジェクトを作成しましょう。(ここではZxingTestとしました)
「zxing-2.0/iphone/README」があるんでそれを抜粋しながらZXingを使用する準備をします。

1. Locate the "ZXingWidget.xcodeproj" file under "`zxing/iphone/ZXingWidget/`". Drag ZXingWidget.xcodeproj and drop it onto the root of your Xcode project's "Groups and Files" sidebar. A dialog will appear -- make sure "Copy items" is unchecked and "Reference Type" is "Relative to Project" before clicking "Add". Alternatively you can right-click on you project navigator and select 'Add files to "MyProject"'

「zxing-2.0/iphone/ZXingWidget/ZXingWidget.xcodeproj」を作成したプロジェクトにドラッグ&ドロップします。

2. Now you need to link the ZXingWidget static library to your project. To do that,
 a. select you project file in the project navigator
 b. In the second column, select your _target_ and not the project itself
 c. Go to the 'build phases' tab, expand the 'link binary with libraries' section,
 d. Click the add button A dialog will appear and you should see libZXingWidget.a in the very first possibilities

作成したプロジェクト >> TARGETS(ZXingTest) >> Build Phases >> Link Binary With Libraries に libZXingWidget.a を追加します。

3. Now you need to add ZXingWidget as a dependency of your project, so Xcode compiles it whenever you compile your project.
 a. like in substep c. of previous step, you nedd to do that in the 'build phases' tab of your target
 b. Expand the 'Target Dependencies' section
 c. Click the add Button and a dialog will appear select ZXingWidget target

先ほどの画面上にある Target Dependencies に ZXingWidget を追加します。

4. Headers search path 1: you need to tell your project where to find the ZXingWidget headers. Select your project in the project navigator, and the select your target and go to the "Build Settings" tab. Look for "Header Search Paths" and double-click it. Add the relative path from your project's directory to the "zxing/iphone/ZXingWidget/Classes" directory. Make sure you click the checkbox "recursive path" !

5. Headers search path 2: You need to add zxing cpp headers to your headers search path, do this similarly as previous step to point the path to cpp/core/src/ where the 'zxing' directory is. Do not check the "recursive path" option for this path.

作成したプロジェクト >> PROJECT(ZXingTest) >> Build Settings >> Search Paths >> Header Search Paths に 「zxing-2.0/cpp/core/src」と「zxing-2.0/iphone/ZXingWidget/Classes」を追加します。

6. Import the following iOS frameworks:
 a. AVFoundation
 b. AudioToolbox
 c. CoreVideo
 d. CoreMedia
 e. libiconv
 f. AddressBook
 g. AddressBookUI

 This must be done by adding them in the 'Link Libraries with Binary' just like step 2.c.

これはそのままですね。上のフレームワークを追加します。

これで前準備はOK。
なかなか面倒です。

次は画面ですが特に説明することもないので Assistant Editor と合わせて以下のようになります。 

次にコードです。

ViewController.h
#import <UIKit/UIKit.h>
#import "ZXingWidgetController.h"

@interface ViewController : UIViewController
<
    ZXingDelegate
>

- (IBAction)scanPressed:(id)sender;

@property (retain, nonatomic) IBOutlet UITextView *resultsView;
@property (copy, nonatomic) NSString *resultsString;

@end

ViewController.mm
#import "ViewController.h"
#import "QRCodeReader.h"

@interface ViewController ()

@end

@implementation ViewController
@synthesize resultsView;
@synthesize resultsString;

- (void)viewDidLoad
{
    [super viewDidLoad];
 // Do any additional setup after loading the view, typically from a nib.
}

- (void)viewDidUnload
{
    [self setResultsString:nil];
    [self setResultsView:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}
- (void)dealloc {
    [resultsString release];
    [resultsView release];
    [super dealloc];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

- (IBAction)scanPressed:(id)sender {
    ZXingWidgetController *zwc = [[ZXingWidgetController alloc] initWithDelegate:self showCancel:YES OneDMode:NO];
    QRCodeReader *qrcodeReader = [[QRCodeReader alloc] init];
    NSSet *readers = [[NSSet alloc] initWithObjects:qrcodeReader, nil];
    zwc.readers = readers;
    [self presentModalViewController:zwc animated:YES];
    
    [qrcodeReader release];
    [readers release];
    [zwc release];
}

- (void)zxingController:(ZXingWidgetController *)controller didScanResult:(NSString *)result
{
    self.resultsString= result;
    if (self.isViewLoaded)
    {
        [resultsView setText:resultsString];
        [resultsView setNeedsDisplay];
    }
    
    [self dismissModalViewControllerAnimated:YES];
}

- (void)zxingControllerDidCancel:(ZXingWidgetController *)controller
{
    [self dismissModalViewControllerAnimated:YES];
}

@end

コード自体は難しいものではないので問題ないかと思います。
ZXingWidgetController がいいかんじに何でもやってくれます。

一点注意する点はコードのファイル名。
プロジェクトを作成した段階では「ViewContrller.m」ですが、ここでは「ViewController.mm」となります。
.m のままビルドすると「iostream file not found」とかいうエラーが出ると思います。

.m ではなく .mm にするのは簡単に言うと Objective-C と C++ を混在させて動作させることができるようにするため。
ZXing がC++ とかでラップされてるんでしょうね。きっと。

これで動作すると思います。
実機で試してみてください。

SCAN をタップすると以下の画面が立ち上がります。この白い枠内にQRコードをも

認識すると以下のように内容が表示されると思います。





0 件のコメント:

コメントを投稿