ZXing 라이브러리를 이용한 아이폰 어플리케이션 개발

2010. 7. 14. 10:36아이폰 개발

ZXing에서 제공하는 iphone용 샘플 소스를 다른 아이폰 프로젝트에서 가져다가 쓰기 위해서 한동안 삽질을 하다가... 드디어 성공했다. 만사가 그렇듯 알고보면 별 것도 아닌데... 그 과정을 극복하기가 쉽지 않은 것 같다.

1. 새로운 프로젝트 생성
아이폰용 Windows 베이스 프로젝트를 생성한다.

2. zxing 라이브러리 파일 복사 및 등록
zxing 1.4의 아이폰 샘플 프로젝트(ZXing.xcodeproj)를 열고 컴파일을 하면, /build/Debug-iphoneos 폴더에 libzxingcore.a 파일이 생성되어있는 것을 확인할 수 있다. 이것을 새로 만든 프로젝트 폴더의 루트에 복사하고, 프로젝트의 Frameworks에 추가해준다.

3. zxing 샘플의 Classes 폴더 복사
zxing 샘플 프로젝트의 Classes 폴더에 있는 모든 파일들을 새로 만든 프로젝트에 복사하고 프로젝트에 추가해준다. (ZXingAppDelegate 관련 파일만 제외) 새로 만든 프로젝트의 AppDelegate 파일에 ZXingAppDelegate 파일의 내용을 복사한다.

예)ZXingTest 프로젝트일 경우

ZXingTestAppDelegate.h 파일에는 붉은 색으로 표시한 내용을 추가

#import <UIKit/UIKit.h>
@class DecoderViewController;
@interface ZXingTestAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    DecoderViewController *viewController;
    UINavigationController *navigationController;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) DecoderViewController *viewController;
@property (nonatomic, retain) UINavigationController *navigationController;
@end

ZXingTestAppDelegate.m 파일에도 역시 붉은색으로 표시한 내용 추가

#import "ZXingTestAppDelegate.h"
#import "DecoderViewController.h"
@implementation ZXingTestAppDelegate
@synthesize window;
@synthesize viewController;
@synthesize navigationController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {   
    DecoderViewController *vc =
    [[DecoderViewController alloc] initWithNibName:@"DecoderView"
                                            bundle:[NSBundle mainBundle]];
    self.viewController = vc;
    [vc release];
   
    navigationController = [[UINavigationController alloc]
                            initWithRootViewController:viewController];
   
    // hook up the view controller's view to be in the window
    [window addSubview:navigationController.view];

    [window makeKeyAndVisible];
   
    // pick and decode using the first available source type in priority order
#define N_SOURCE_TYPES 3
    UIImagePickerControllerSourceType sourceTypes[N_SOURCE_TYPES] = {
        UIImagePickerControllerSourceTypeCamera,
        UIImagePickerControllerSourceTypeSavedPhotosAlbum,
        UIImagePickerControllerSourceTypePhotoLibrary
    };
   
    for (int i = 0; i < N_SOURCE_TYPES; i++) {
        if ([UIImagePickerController isSourceTypeAvailable:sourceTypes[i]]) {
            [viewController pickAndDecodeFromSource:sourceTypes[i]];
            break;
        }
    }
#undef N_SOURCE_TYPES
    return YES;
}
- (void)dealloc {
    [window release];
    [super dealloc];
}
@end

이 상태에서 컴파일을 하면 참조해야할 헤더 파일이 없다고 에러가 죽 뜬다.

4. zxing 라이브러리 header 파일 복사
zxing 1.4/cpp/core/src 의 모든 헤더 파일을 (폴더구조 유지) 통째로 새로운 프로젝트에 복사하고, 프로젝트에 추가해준다.
기존 소스에서 zxing 라이브러리의 헤더파일을 참조하기 때문이다. 라이브러리 파일을 이용하기 때문에 당연히 cpp 파일은 필요없다.

여기까지 진행하면, 컴파일이 되는 것 같이 보이지만 무려 45개의 에러가 뜨게 된다.

5. Decoder.m 파일 확장자 변경
Decoder.m 파일의 확장자를 Decoder.mm 으로 바꾸고 컴파일을 하면 에러가 하나도 뜨지 않고 컴파일이 성공한다.
(대신 300여개의 warning은 어쩔꺼니...)

컴파일이 성공했다고 실행도 성공하는건 아니다.

6. 리소스 파일 복사
ZXing 샘플 프로젝트의 en.lproj 폴더에 있는 리소스 파일들을 새로 만든 프로젝트에 복사한다.
MainWindow.xib 파일은 덮어쓰기를 한다음, Interface Builder에서 열고 Xing App Delegate를 자신의 App Delegate로 변경해준다.

이제 다시 컴파일하고 실행을 하면 정상적으로 동작하는 것을 확인할 수 있다.

나름 감격...