얼마전 출판사에서 리뷰요청과 함께 책을 보내주어 아이폰과 안드로이드 관련 책을 받아 보았습니다. 마침 요즘 하고 있는 안드로이드 프로젝트 때문에 정신이 없어 이제서야 간단하게 나마 책에 대한 느낌을 올려 봅니다.

두권의 책은 일본서적을 번역한 것이라는 것과 초보자를 대상으로 하고 있다는 공통점을 가지고 있습니다. 안드로이드와 아이폰으로 나누어져 있다는 것만 제외하고는 편집상태도 그렇고 두책을 본 느낌은 거의 동일합니다. 이 두 책의 장점은 대상이 명확하다는 것입니다. 어느정도 익숙한 사람도 아닌 해당 플랫폼에 처음으로 입문하는 사람을 그 대상으로 하고 있습니다.

300페이지가 조금 넘어가는 부담없는 분량에 기본적으로 알아야할 내용들을 자세하게 설명하고 있습니다. 개발에 익숙하신 분들이면 하루 정도면 읽을 수있고 해당 플랫폼에서의 개발을 어느정도 이해하실 수 있습니다.

애플리케이션 개발자 안드로이드 매력에 빠지다
카테고리 컴퓨터/IT
지은이 HIDEO KINAMI (영진닷컴, 2010년)
상세보기
안드로이드 관련서적은 2개 정도 이미 가지고 있었습니다. 그 두책에 비해서 내용은 적지만 오히려 초반에 감을 익히기에는 이 책이 더 나았을 거란 생각이 들었습니다. 어차피 책은 처음에 개념만 익히는 것이고 실제 개발시에는 책보다는 대부분 관련 사이트의 레퍼런스를 많이 활용하게 됩니다.

내용은 쉽게 이해할 수 있도록 되어 있으나 오타들이 있는 것 같습니다. 100 페이지에 보면 아래와 같은 ImageView와 ImageButton의 속성을 정의하는 소스가 있습니다.

<ImageView
.. 중략 ..
android:text=@"android:drawable/ic_menu_help"/>

<ImageButton
.. 중략 ..
android:text="@android:drawable/btn_start_big_on"/>

ImageView, ImageButton 두 위젯 모두 'android:src'로 리소스를 지정하는데 'android:text'로 잘 못 지정되어 있습니다. btn_start_big_on도 btn_star_big_on로 변경되어야 하고요. 그외에 111 페이지에 있는 소스에서도 아래와 같은 이상한 내용의 소스가 있습니다.

<FrameLayout
<TableLayout
<FrameLayout
<LinearLayout
...중략...
>
<Chrometer
<Button
</LinearLayout>

붉은 색의 갑자기 나타나 닫히지도 않은 태그들은 아마 편집시 잘 못들어 온 것 같습니다. 현재까지 본 이 오타들은 처음 보는 분들에게는 혼란을 줄 수 있을고, 초보자를 대상으로 한 책에서 이런 오류는 아쉬운 부분입니다. 이런 오타에도 불구하고 누군가 안드로이드 입문서를 물어 본다면 이 책을 추천하겠습니다.

[2쇄 부터는 수정되어 인쇄되었다고 합니다]


애플리케이션 개발자 아이폰 매력에 빠지다
카테고리 컴퓨터/IT
지은이 KENGO TSURUZONO (영진닷컴, 2010년)
상세보기
이책 역시 처음 입문하는 분들을 대상으로 쉽고 친절하게 설명되어 있습니다. 광대한 범위를 다루고 있지는 않지만 아이폰 개발에 입문하기에 좋은 책으로 생각됩니다. 많은 이미지와 도표들이 있어 이해하기도 쉽습니다. 디자인적인 측면에서 읽기가 좀 불편하지 않나 하는 생각인데 이는 보는 사람들에게 따라 평가가 달라질 것 같습니다. 확인해 보니 원서와 같은 디자인인 것 같습니다.

위에서도 언급했듯이 두 책 다 제가 본 책중에선 가장 쉽게 초보자를 대상으로 잘 나온 책인 것 같습니다. 책은 아무래도 서점에서 직접 보고서 자신과 궁합이 맞는 것을 고르는 것이 가장 좋을 것 같습니다.

AND

1. 빌드시 시뮬레이터 판별

#if !TARGET_IPHONE_SIMULATOR
pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
#endif
TARGET_IPHONE_SIMULATOR로 실제 아이폰에서만 실행되는 코드를 따로 관리할 수 있습니다.

2. 하위 View 검색

NSArray *subViewList = [searchBar subviews];
for (UIView *view in subViewList) {
    if ([view isKindOfClass:[UITextField class]]) {
        [(UITextField *)view setReturnKeyType:UIReturnKeyDone];
    }   
}
UIView의 subviews와 isKindOfClass를 사용하여 하위의 특정 뷰를 찾아내어 설정을 변경할 수 있습니다. UISearchBar에서 UITextField를 찾아내어 키보드의 Search 버튼의 텍스트를 Done으로 변경하는 예입니다.

- (void) setSubViewsClearColor: (UIView*)theView {
   NSArray *subViewList = theView.subviews;
   for (UIView *view in subViewList) {
       [view setBackgroundColor:[UIColor clearColor]];
       [self setSubViewsClearColor:view];
   }
}
하위 View를 모두 찾아 배경을 투명한 속성으로 변경하는 예입니다.
초기화 하는 곳에서 [self setSubViewsClearColor:self]; 와 같이 호출하여 사용합니다.
 
 
3. 사용자 데이터 저장

userLevel = [[NSUserDefaults standardUserDefaults] integerForKey:@"user_level"];
[[NSUserDefaults standardUserDefaults] setInteger:g_userLevel forKey:@"user_level"];
옵션등의 간단한 설정은 데이터베이스나 파일을 이용하는대신 NSUserDeraults를 사용하면 간단하게 저장하고 불러올 수 있습니다.

4. Rect와 Point
좌표로 많이 사용되는 Rectd와 Point에서 자주 사용되는 함수와 상수입니다.

CGRect  CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height);
x, y, width, height로 설정된 CGRect를 반환합니다.

CGRectZero
0, 0 좌표와 0, 0 크기를 가진 CGRect 상수입니다.

CGPointMake(CGFloat x, CGFloat y);
x, y로 설정된 CGPoint를 반환합니다.

CGPointZero
0, 0 좌표를 가진 CGPoint 상수입니다.

bool CGRectContainsPoint(CGRect rect, CGPoint point);
rect 사각형에 point가 속해있는지 여부를 반환합니다.

bool CGRectContainsRect(CGRect rect1, CGRect rect2);
rect1 사각형에 rect2 사각형이 속해있는지 여부를 반환합니다.

bool CGRectIntersectsRect (CGRect rect1,  CGRect rect2);
rect1과 rect2가 교차하는지 여부를 반환합니다.


5. Path

NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
어플리케이션 번들 디렉토리를 반환합니다.

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
번들에 포함된 파일들은 읽기만 가능하고 쓰기가 불가능합니다. 디비와 같이 변경이 필요한 경우에는 위와같이 어플리케이션의 도큐먼트 폴더를 구해와 도큐먼트 폴더로 복사 생성해 놓고 작업합니다.


6. URL

NSURL *url = [NSURL URLWithString:@"http://www.cocoadev.co.kr"];
[[UIApplication sharedApplication] openURL:url];
지정된 웹주소를 사파리에서 오픈합니다.

NSURL *url = [NSURL URLWithString:@"mailto:abc@def.com"];
[[UIApplication sharedApplication] openURL:url];         
받는사람이 설정되어 메일 프로그램의 새로운 메시지가 실행됩니다.

NSURL *url = [NSURL URLWithString:@"tel:02-111-2222"];
[[UIApplication sharedApplication] openURL:url];
지정된 번호로 전화를 겁니다.

AND

파이썬에서 사용할 수 있는 BeautifulSoup을 이용해 xml 데이터를 sqlite3 DB에 넣는 툴을 만들는 간단한 예입니다.

1. BeautifulSoup 다운로드 및 설치
필요한 파일은 BeautifulSoup 사이트에서 다운로드 받으실 수있습니다. 파이썬 버젼이 2.*이면 3.0* 버젼을 3.*이면 3.1* 버젼중 최신버젼을 다운로드 받습니다. 다운로드가 완료되면 압축을 풀고 터미널에서 아래와 같이 setup.py를 실행합니다.

>python ./setup.py install

2. BeautifulSoup 사용예
1) 셈플 xml 파일 (test.xml)
테스트를 위해 간단히 작성해본 XML 입니다.
<?xml version='1.0' encoding='UTF-8'?>
<alcohol>
    <cate1 tt="술">
        <cate2 tt="소주">  
            <item>참이슬</item>
            <item>처음처럼</item>
            <item>잎새주</item>
        </cate2>   
        <cate2 tt='맥주'>  
            <item>카스</item>
            <item>라거</item>
            <item>하이트</item>
        </cate2>   
    </cate1>    
    <cate1 tt="안주">  
        <cate2 tt="고가">
            <item>회</item>
            <item>등심</item>
            <item>양곱창</item>
        </cate2>
        <cate2 tt="저가">
            <item>참치캔</item>
            <item>날계란</item>
            <item>새우깡</item>
        </cate2>
    </cate1>   
</alcohol>

2) 파이썬 소스파일 (con_data.py)
  1. #!/usr/bin/python
  2. #  -*- coding: utf-8 -*-
  3.  
  4. import sys
  5. import sqlite3
  6. from BeautifulSoup import BeautifulStoneSoup
  7.  
  8. argCount = len(sys.argv)
  9. if argCount is not 3:
  10.     print 'Usage:con_data.py [xml file] [db file]'
  11.     sys.exit(0)
  12.  
  13. xml_file = sys.argv[1]
  14. db_file = sys.argv[2]
  15.  
  16. #XML open
  17. src = open(xml_file)
  18. soup = BeautifulStoneSoup(src)
  19.  
  20. #DB & Table create
  21. db = sqlite3.connect(db_file)
  22. cursor = db.cursor()
  23.  
  24. cursor.execute("CREATE TABLE item(cate1, cate2, name)");
  25.  
  26. #Insert data
  27. for cate1 in soup.alcohol('cate1'):
  28.     query1 = 'INSERT INTO item VALUES("' + cate1['tt'] + '", "'
  29.     print 'CATE1: ' + cate1['tt']
  30.    
  31.     for cate2 in cate1('cate2'):
  32.         query2 = query1 + cate2['tt'] + '", "'
  33.         print   '\tcate2: ' + cate2['tt']
  34.      
  35.         for item in cate2('item'):
  36.             query3 = query2 + item.string + '")'
  37.             print '\t\t' + item.string
  38.  
  39.             cursor.execute(query3)
  40.     print "---------------------"
  41.  
  42. #Close
  43. cursor.close()
  44. db.commit()
  45. db.close()

3) 테스트
아래와 같이 실행하면 test.db가 생성되어 있음을 확인하실 수 있습니다.


해당 사이트에서 문서 페이지를 읽어 보시면 보다 세부적인 기능과 상세한 사용법을 확인하실 수  있습니다.  사용한 con_data.py외 test.xml은 압축하여 첨부하였습니다. 테스트 시에는 터미널에서 chmod +x ./con_data.py로 실행권한을 설정하셔야 합니다.


'기타 > 자잘한 Tip' 카테고리의 다른 글

특정 날짜 요일 구하기  (0) 2012.02.04
sqlite3에서 csv import/export  (0) 2009.08.26
Python에서 sqlite3 사용하기  (1) 2009.08.26
텍스트파일 문자셋 변환 스크립트  (6) 2008.08.25
Xcode에서의 Ruby on Rails  (8) 2008.08.20
AND