2013년 1월 15일 화요일

[iOS] ZBarSDK를 이용한 바코드 리더 개발

ZBarSDK의 적용 및 커스터마이징은 문서화가 잘되어있다. 여기서는 기본적인 사용법만 간단히 기록한다. XCode 4.5 / iOS 6.0 SDK 개발환경에서 iPhone 4S를 이용해 테스트했다.

준비

ZBarSDK 1.2 다운로드

프로젝트 생성 및 ZBarSDK 추가

 Single View Application 템플릿을 이용하여 새 프로젝트를 하나 만든다. 여기서는 ZBarSample을 사용한다. 프로젝트가 생성되면 Project Navigator에서 프로젝트를 선택하고 "Add File to..."를 선택하여 ZBarSDK를 프로젝트에 추가한다. Destination과 Add to targets 옵션을 확인한다.


필요 프레임워크 추가

 TARGETS에서 프로젝트를 선택하고, "Build Phases" 탭의 "Link Binary with Libraries"에 필요한 프레임워크들을 추가한다. 추가해야하는 프레임워크는 다음과 같다.
  • AVFoundation.framework
  • CoreMedia.framework
  • CoreVideo.framework
  • QuartzCore.framework
  • libiconv.dylib



바코드 리더 뷰 추가

 새 UIViewController 클래스를 프로젝트에 추가한다. 이 클래스는 실제 바코드 리더로 사용된다. 여기서는 가장 기본적인 바코드 리더 기능만 구현하기 때문에, ZBarReaderViewController 클래스를 상속받는 것 외에는 별도의 뷰와 코드가 필요가 없다. 바코드 리더 UI를 커스터마이징하려면 이 컨트롤러를 수정해야 한다.

BarcodeReaderController.h
#import <UIKit/UIKit.h>
#import "ZBarReaderViewController.h"

@interface BarcodeController : ZBarReaderViewController

@end



바코드 리더 뷰 호출하기

 ViewController에는 바코드 리더 뷰를 불러올 버튼과 바코드 정보를 처리할 Delegate 메서드가 추가된다. ZBarReaderViewController.h 헤더 파일을 추가하고 ZBarReaderDelegate 프로토콜을 추가한다.

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

@interface ViewController : UIViewController <ZBarReaderDelegate>

@end


닙 파일을 통해 버튼과 IBAction을 추가하는 대신 동적으로 버튼을 하나 추가하고 메시지를 하나 선언한다.

ViewController.m
#import "ViewController.h"
#import "BarcodeController.h"

@interface ViewController ()

- (void)scan:(id)sender;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    UIButton *scanButton = 
        [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [scanButton addTarget:self
                   action:@selector(scan:)
         forControlEvents:UIControlEventTouchUpInside];
    [scanButton setTitle:@"SCAN" forState:UIControlStateNormal];
    scanButton.frame = CGRectMake(20.0, 40.0, 280.0, 35.0);
    
    [self.view addSubview:scanButton];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

@end

버튼을 터치하면 BarcodeController가 모달 뷰로 표시된다. 실제 카메라를 사용하므로 시뮬레이터 대신 실제 기기를 통해 실행시켜야 한다.

ViewController.m
#pragma mark - Private methods

- (void)scan:(id)sender
{
    BarcodeController *barcodeController = 
        [[[BarcodeController alloc] init] autorelease];
    barcodeController.readerDelegate = self;
    
    [self presentViewController:barcodeController
                       animated:YES
                     completion:nil];
}


바코드 정보 가져오기

 BarcodeController에 추가로 ZBarReaderDelegate 프로토콜 메서드들을 구현한다. 바코드가 읽히면 imagePickerController:didFinishPickingMediaWithInfo: 메시지가 실행되고 NSDictionary 타입으로 인식된 바코드의 정보를 전달한다.

ViewController.m
#pragma mark - ZBarReaderController methods

- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    id<NSFastEnumeration> scanResults =
        [info objectForKey:ZBarReaderControllerResults];
    
    NSString *result;
    
    ZBarSymbol *symbol;
    for (symbol in scanResults)
    {
        result = [symbol.data copy];
        break;
    }
  
    NSLog(@"Result : %@", result);
    
    [result release];
    
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)imagePickerControllerDidCancel:
    (UIImagePickerController *)picker
{
    [self dismissViewControllerAnimated:YES
                             completion:nil];
}


2013년 1월 3일 목요일

[iOS] iPhone 5 확인 매크로

아이폰5 덕분에 개발자가 신경써야 할 일들이 늘었다. 새삼 안드로이드 개발자분들이 존경스러워진다. 아래 코드는 아이폰5를 구분하는 매크로다. 출처는 스택오버플로.
#define IS_IPHONE ( [[[UIDevice currentDevice] model] isEqualToString:@"iPhone"] )
#define IS_IPOD   ( [[[UIDevice currentDevice ] model] isEqualToString:@"iPod touch"] )
#define IS_HEIGHT_GTE_568 [[UIScreen mainScreen ] bounds].size.height >= 568.0f
#define IS_IPHONE_5 ( IS_IPHONE && IS_HEIGHT_GTE_568 )