Lomohome.com :: 괴발자 모근원


 





























Sony NEX-5 / HORUSBENNU 35mm f1.7  / RAW / Lightroom 3 / 2011. 3. 20


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

동묘 나들이  (2) 2011.04.03
홍대 고기벙개  (0) 2011.04.03
방이동 안장골 회전 오리구이  (1) 2011.03.29
우리집은 사과 밭  (0) 2011.03.21
요즘  (0) 2011.03.21
서울의 중심에서 놀기  (0) 2011.03.14
Posted by 모근원


어쩌다보니 방이 이지경.
막내의 2009년 17인치, 내 2010년 15인치, 둘째의 2011년 13인치 맥북 프로. 


Sony NEX-5 / HORUSBENNU 35mm f1.7  / RAW / Lightroom 3 / 2011. 3. 19


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

홍대 고기벙개  (0) 2011.04.03
방이동 안장골 회전 오리구이  (1) 2011.03.29
광욱이형 딸 유정이 돌잔치  (2) 2011.03.21
요즘  (0) 2011.03.21
서울의 중심에서 놀기  (0) 2011.03.14
요즘  (0) 2011.03.14
Posted by 모근원

사무실에서 야근중에 바라본 잠실역 사거리



홋카이도에서 왔어요. 미호와 나루미에게 받은 선물

Sony NEX-5 / HORUSBENNU 35mm f1.7  / RAW / Lightroom 3 / 2011. 3


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

방이동 안장골 회전 오리구이  (1) 2011.03.29
광욱이형 딸 유정이 돌잔치  (2) 2011.03.21
우리집은 사과 밭  (0) 2011.03.21
서울의 중심에서 놀기  (0) 2011.03.14
요즘  (0) 2011.03.14
북촌 한옥마을  (4) 2011.03.13
Posted by 모근원

명동 프리스비

명동

치과 엘레베이터에서 간만의 셀프. 살 뺍시다~

화이트데이 선물

명동에서 만난 그녀

그리고 헌혈하러 고고싱

난생 처음 해봐요~

상담중

원래는 같이 하려 했으나, 스케일링하고 72시간내엔 헌혈이 안된다니... OTL


으힉


피뽑았으니 맛난 점심먹어야죠~

점심먹고 남산

남산 애니메이션 센터


남산 구경중


수백만개의 자물쇠들

섹시라인


남산 버스들이 전기차로 바뀌어있었다.

내려가는길


날씨는 그저 그런..



태극당. 내부에선 사진을 못찍게 했었다.

여기저기 원조. 원조 장충동

월미도에서 동대문으로 이사온 디스코 팡팡


우이쒸~

커피한잔하러 갑시다용~



실내에서 새 장난감 렌즈 테스트 중..

화장실 다녀온 사이 써프라이즈 화이트데이 선물~

:-)

시계

저녁 간식으로 순대



D.S.T!  (떡볶이,순대,튀김)

생애 첫 헌혈증서

집으로 가는 신도림역 버스정류장;;

로또는 언제 될까?


Sony NEX-5 / HORUSBENNU 35mm f1.7  / RAW / Lightroom 3 / 2011. 3. 12


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

광욱이형 딸 유정이 돌잔치  (2) 2011.03.21
우리집은 사과 밭  (0) 2011.03.21
요즘  (0) 2011.03.21
요즘  (0) 2011.03.14
북촌 한옥마을  (4) 2011.03.13
친구들  (0) 2011.03.13
Posted by 모근원

야근은 한우와 함께

퇴근길


신도림역

하나은행

집 앞.

방안에서

로모

윤원이

출근길

물가걱정인 중년남성 둘

집으로 가는 버스


Sony NEX-5 / HORUSBENNU 35mm f1.7  / RAW / Lightroom 3 / 2011. 3


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

우리집은 사과 밭  (0) 2011.03.21
요즘  (0) 2011.03.21
서울의 중심에서 놀기  (0) 2011.03.14
북촌 한옥마을  (4) 2011.03.13
친구들  (0) 2011.03.13
닭갈비를 대하는 우리의 자세  (2) 2011.03.10
Posted by 모근원

안국역 북촌 한옥마을

한옥마을 입구에서 한장


이쯤이면 홍보대사 시켜도 되겠음

옛 정취가 아직 그대로



신+구 의 조화


모델

길거리에 예쁜 가계도 많아요



남산


그런데 그닥 조용하지는 않은 동네

컵뽂이!

집으로 가는 길

Sony NEX-5 / E18-55mm F3.5-5.6 OSS / RAW / Lightroom 3 / 2011. 3. 5


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

요즘  (0) 2011.03.21
서울의 중심에서 놀기  (0) 2011.03.14
요즘  (0) 2011.03.14
친구들  (0) 2011.03.13
닭갈비를 대하는 우리의 자세  (2) 2011.03.10
호루스벤누 35mm 테스트 샷  (2) 2011.03.09
Posted by 모근원




나루미, 미호, 에미코, 나


Sony NEX-5 / E18-55mm F3.5-5.6 OSS / RAW / Lightroom 3 / 2011. 2. 28


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

서울의 중심에서 놀기  (0) 2011.03.14
요즘  (0) 2011.03.14
북촌 한옥마을  (4) 2011.03.13
닭갈비를 대하는 우리의 자세  (2) 2011.03.10
호루스벤누 35mm 테스트 샷  (2) 2011.03.09
SBS 미라클 아트전  (0) 2011.03.02
Posted by 모근원






집으로 고고싱


Sony NEX-5 / HORUSBENNU 35mm f1.7  / RAW / Lightroom 3 / 2011. 3. 9


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

요즘  (0) 2011.03.14
북촌 한옥마을  (4) 2011.03.13
친구들  (0) 2011.03.13
호루스벤누 35mm 테스트 샷  (2) 2011.03.09
SBS 미라클 아트전  (0) 2011.03.02
AKAI LPD8  (0) 2011.03.01
Posted by 모근원




비록 태생이 미천한 CCTV용 렌즈이지만 로모만큼 뽑아주니깐.

Sony NEX-5 / HORUSBENNU 35mm f1.7  / RAW / Lightroom 3 / 2011. 3. 8


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

북촌 한옥마을  (4) 2011.03.13
친구들  (0) 2011.03.13
닭갈비를 대하는 우리의 자세  (2) 2011.03.10
SBS 미라클 아트전  (0) 2011.03.02
AKAI LPD8  (0) 2011.03.01
발렌타인 데이  (0) 2011.02.28
Posted by 모근원

양재동 at 센터에서 했었던 SBS 미라클 아트전

요런식으로 그림에 입체효과(?)를 줘서 참여형 사진을 찍는것이 가능한 전시회

일본원숭이?

그.. 연예인 아저씨도 와서 무슨 촬영하던데..

그리스 신화에 대한 경배

쏘쏘는 엽기적인 사진말고 안망가지는(?) 사진만을 찍기원함.

페러슈트 모근원

화가 이소영

곰돌이

야생

응징

쌩뚱맞게 갑자기 앵무새(?) 한마리

유치 찬란

복근 마니아 아줌마 표정

그러니까 저게 어떻게 트뢰퐁뤼우로 읽히는거지?

현정화와 한판

이천수?....

변태

변태2

변태3...


개인적으로 친숙한 그림

아아앍

펌프질

이웃사촌


집으로 가는길 저녁을 뭐 먹을까 고민중

저녁은 보쌈으로 결정~


Sony NEX-5 / E18-55mm F3.5-5.6 OSS / RAW / Lightroom 3 / 2011. 2. 26


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

친구들  (0) 2011.03.13
닭갈비를 대하는 우리의 자세  (2) 2011.03.10
호루스벤누 35mm 테스트 샷  (2) 2011.03.09
AKAI LPD8  (0) 2011.03.01
발렌타인 데이  (0) 2011.02.28
로또  (0) 2011.02.27
Posted by 모근원

너저분한 방

DJ.MO(?)


Sony NEX-5 / E18-55mm F3.5-5.6 OSS / RAW / Lightroom 3 / 2011. 2. 25


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

닭갈비를 대하는 우리의 자세  (2) 2011.03.10
호루스벤누 35mm 테스트 샷  (2) 2011.03.09
SBS 미라클 아트전  (0) 2011.03.02
발렌타인 데이  (0) 2011.02.28
로또  (0) 2011.02.27
짱어  (0) 2011.02.27
Posted by 모근원


음식앞에 숙연해지시는 쏘

인상좋은 옆집 아저씨?

한땀 한땀 장인의 손길이 베여있는 쿠션

장인 인증샷

쿠션 방석 그리고 초콜릿
방석 정말 따뜻하다 ㅠ_ㅠd

까르보나라

해물 토마토 스파게티~ 맛나~ 맛나~

2차는 항상 이정도

치킨 떡볶이!


Sony NEX-5 / E18-55mm F3.5-5.6 OSS / RAW / Lightroom 3 / 2011. 2. 14


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

호루스벤누 35mm 테스트 샷  (2) 2011.03.09
SBS 미라클 아트전  (0) 2011.03.02
AKAI LPD8  (0) 2011.03.01
로또  (0) 2011.02.27
짱어  (0) 2011.02.27
우리집 설 풍경  (0) 2011.02.27
Posted by 모근원

될리가 없다는걸 알면서도 가지게되는 미련한 미련


Sony NEX-5 / E18-55mm F3.5-5.6 OSS / RAW / Lightroom 3 / 2011. 2. 14

'내가찍은사진 > 디카사진들' 카테고리의 다른 글

SBS 미라클 아트전  (0) 2011.03.02
AKAI LPD8  (0) 2011.03.01
발렌타인 데이  (0) 2011.02.28
짱어  (0) 2011.02.27
우리집 설 풍경  (0) 2011.02.27
오랜 친구들의 저녁식사  (0) 2011.02.27
Posted by 모근원



파주 갈릴리 농원에서 맛나는 짱어 6Kg!!!


Sony NEX-5 / E18-55mm F3.5-5.6 OSS / RAW / Lightroom 3 / 2011. 2. 12


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

AKAI LPD8  (0) 2011.03.01
발렌타인 데이  (0) 2011.02.28
로또  (0) 2011.02.27
우리집 설 풍경  (0) 2011.02.27
오랜 친구들의 저녁식사  (0) 2011.02.27
생일선물  (0) 2011.02.01
Posted by 모근원


올해도 배터지게 드시는 할아버지 할머니.

늦었지만 떡국많이 드시고 새해복 많이 받으세요~


Sony NEX-5 / E18-55mm F3.5-5.6 OSS / RAW / Lightroom 3 / 2011. 2. 3


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

발렌타인 데이  (0) 2011.02.28
로또  (0) 2011.02.27
짱어  (0) 2011.02.27
오랜 친구들의 저녁식사  (0) 2011.02.27
생일선물  (0) 2011.02.01
내 생일 @2011.1.22  (2) 2011.01.23
Posted by 모근원

영등포가는 길 중에 구로역에서.

신도림 디큐브시티 공사현장

영등포 타임스퀘어



책읽는 소영. 요즘 부쩍 인터리어에 관심을..


친구들 만나러 가는 길

커피기다리는 상민이 

당구집 아들경력 동안이


자넷 쏘?

오랜친구 동안이와 상민이

당구만 15년을 쳐도 실력은 그바닥들 ㅋ


귀여운(?) 상민

파마한 동안이




Sony NEX-5 / E18-55mm F3.5-5.6 OSS / RAW / Lightroom 3 / 2011. 1. 29

'내가찍은사진 > 디카사진들' 카테고리의 다른 글

로또  (0) 2011.02.27
짱어  (0) 2011.02.27
우리집 설 풍경  (0) 2011.02.27
생일선물  (0) 2011.02.01
내 생일 @2011.1.22  (2) 2011.01.23
MT  (0) 2011.01.23
Posted by 모근원

COCOSDenshion (of cocos2d 0.99.5) 의 SimpleAudioEngine 믿고 배경음을 출력했었다.
시뮬레이터에서 잘 되고~ 아이팟 터치 2세대에서 잘 되고~

그런데!! iPhone 4에서만 배경음악이 출력이 안되는것~! (효과음 effect 출력은 잘 되고있는데?!)
로그를 찍어보니 파일의 위치를 읽어오지 못하고 있었다.
참고로 한 Sample 의 TomTheTurret 도 마찬가지의 버그를 내고있었고..
버그인지.. cocos2d 라이브러리를 직접 수정하다가. 곧 업데이트가 될것 같아서 원복하고..
그냥 임시로 업데이트될때까지 SimpleAudioEngine 에서 배경음 재생 실패할 경우 AVAudioPlayer 를 이용해서 재생하도록 했다.
그리고 Fadein/out 시켜주는 메소드 하나 추가하고..
결과는 기종에 관계없이 배경음이 자~알 출력된다.
사운드 엔진은 싱글턴으로 프로그램내에서 어디서든지 불러다 쓸수있게 했다.

SimpleAudioEngine *soundEngine_;



//-- 이 아래에는 AVAudioPlayer를 위한 멤바들.

BOOL isAVAudioPlayer; //한번이라도 AVAudioPlayer 이용하여 배경음을 재생하면 셋팅된다.

//차선책으로 쓰는 AVAudioPlayer

AVAudioPlayer *bgmPlayer;

CGFloat fadeAmt; //Fadeout 감소값.

CGFloat fadeDesc; //Fadein 목표값.

요러한 멤버객체가 인터페이스에 선언이 되어있다 치고..

-(SimpleAudioEngine *) soundEngine

요런식으로 심플 오디오 엔진을 리턴하는 메소드가 있다 하자..

객체 init 해줄때 초기화 꼼꼼히 해주고..

isAVAudioPlayer = NO;

fadeAmt = 0;


dealloc  해줄땐 AVAudioPlayer 로 배경음 재생중이면 꺼주고 죽여주자.

if (self.bgmPlayer != nil) {

[self stopBGMwithAudioPlayer];

}




발로짠 오디오 플레이어 부분.

//배경음 재생을 시작한다.

-(void)playBGMwithAudioPlayer:(NSString*)filename ext:(NSString*)ext volume:(CGFloat)vol{

if (self.isSoundOn) {

[self stopBGMwithAudioPlayer];

if(self.bgmPlayer == nil){

self.bgmPlayer = [self createAudioPlayer:filename ext:ext volume:vol];

//-1 무한반복

self.bgmPlayer.numberOfLoops = -1;

}

[self.bgmPlayer play];

}

}


-(void)stopBGMwithAudioPlayer{

if (self.isSoundOn && self.bgmPlayer != nil) {

NSLog(@"AVAudioPlayer 스탑!");

[self.bgmPlayer stop];

// self.bgmPlayer.currentTime = 0; //rewind

self.bgmPlayer = nil;

}

}



//오디오 플레이어를 만든다.

-(AVAudioPlayer*)createAudioPlayer:(NSString*)filename ext:(NSString*)ext volume:(CGFloat)vol{

NSString *audioPath = [[NSBundle mainBundle]pathForResource:filename ofType:ext];

NSLog(@"새로운 AVAudioPlayer 생성 %@.%@ (%f%%)",filename,ext,vol);

AVAudioPlayer *tmpAudioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:audioPath] error:nil];

tmpAudioPlayer.numberOfLoops = 0;

tmpAudioPlayer.volume = vol;

//소리를 위해 버퍼에 로딩

[tmpAudioPlayer prepareToPlay];

isAVAudioPlayer = YES;

[tmpAudioPlayer autorelease];

return tmpAudioPlayer;

}



//음악을 서서히 죽여준다.

-(void)fadeoutBGMwithAudioPlayer{

    if (self.bgmPlayer!=nil && self.bgmPlayer.volume > 0.01f) {

//2초정도 소리를 줄여주기 위하여

if (fadeAmt == 0) fadeAmt = self.bgmPlayer.volume/20;

        self.bgmPlayer.volume = self.bgmPlayer.volume - fadeAmt;

        [self performSelector:@selector(fadeoutBGMwithAudioPlayer) withObject:nil afterDelay:0.1f];

} else {

NSLog(@"fadeOut finish");

fadeAmt = 0;


[self stopBGMwithAudioPlayer];

}

}



//음악을 서서히 살려준다.

-(void)fadeinBGMwithAudioPlayer{

//NSLog(@"fadeIn %f amount %f desc %f",self.bgmPlayer.volume,fadeAmt,fadeDesc);

    if (self.bgmPlayer!=nil && self.bgmPlayer.volume <= fadeDesc) {

//2초정도 소리를 줄여주기 위하여

if (fadeAmt == 0) fadeAmt = fadeDesc/20;

        self.bgmPlayer.volume = self.bgmPlayer.volume + fadeAmt;

        [self performSelector:@selector(fadeinBGMwithAudioPlayer) withObject:nil afterDelay:0.1f];

} else {

NSLog(@"fadeIn finish");

fadeAmt = 0;

}

}


그리고 SimpleAudioPlayer 를 같이 쓰면서 배경음 재생 실패하면 바로 AVAudioPlayer 를 이용.

//BGM재생.

-(void) playBGM:(NSString*)filename ext:(NSString*)ext volume:(CGFloat)vol{

if (self.isSoundOn){

//soundEngine

if (!isAVAudioPlayer && [self soundEngine] != nil) {

NSLog(@"soundEngine 으로 배경음 재생 시도.");

[self soundEngine].backgroundMusicVolume = vol;

[[self soundEngine] playBackgroundMusic:[[NSBundle mainBundle] pathForResource:filename ofType:ext] loop:YES];

}

NSLog(@"soundEngine : isBackgroundMusicPlaying (%d), isAVAudioPlayer(%d)",[[self soundEngine] isBackgroundMusicPlaying],isAVAudioPlayer);

if (isAVAudioPlayer || [self soundEngine] == nil || ([self soundEngine] != nil && ![[self soundEngine] isBackgroundMusicPlaying])) {

//AudioPlayer

NSLog(@"soundEngine 으로 배경음 재생 실패하여 AVAudioPlayer 시도.");

[self playBGMwithAudioPlayer:filename ext:ext volume:vol];

}

}

}


-(void) fadeinBGM:(NSString*)filename ext:(NSString*)ext volume:(CGFloat)vol{

if (self.isSoundOn){

//soundEngine

if (!isAVAudioPlayer && [self soundEngine] != nil) {

NSLog(@"soundEngine 으로 배경음 페이드 재생 시도.");

[self soundEngine].backgroundMusicVolume = 0;

[[self soundEngine] playBackgroundMusic:[[NSBundle mainBundle] pathForResource:filename ofType:ext] loop:YES];

[CDXPropertyModifierAction fadeBackgroundMusic:2.0f finalVolume:vol curveType:kIT_SCurve shouldStop:NO];

}

if (isAVAudioPlayer || [self soundEngine] == nil || ([self soundEngine] != nil && ![[self soundEngine] isBackgroundMusicPlaying])) {

//AudioPlayer

NSLog(@"soundEngine 으로 배경음 재생 실패하여 AVAudioPlayer 페이드 재생 시도.");

fadeDesc = vol;

[self playBGMwithAudioPlayer:filename ext:ext volume:0];

[self fadeinBGMwithAudioPlayer];

}

}

}


-(void) stopBGM{

if (self.isSoundOn){

if (isAVAudioPlayer) {

[self stopBGMwithAudioPlayer];

} else {

if ([self soundEngine] != nil){

[[self soundEngine] stopBackgroundMusic];

}

}

}

}


-(void) fadeoutBGM {

if (self.isSoundOn) {

if (isAVAudioPlayer) {

[self fadeoutBGMwithAudioPlayer];

} else {

if ([self soundEngine] != nil){

//2 페이드 아웃.

[CDXPropertyModifierAction fadeBackgroundMusic:2.0f finalVolume:0.0f curveType:kIT_SCurve shouldStop:YES];

}

}

}

}


끗. (이랬는데 뭔가 잘못써서 SimpleAudioEngine 에서 출력이 안된거라면 대략 난감.. 삽질의 향기가..)


- (덧) COCOS 2D 1.0rc 버전에서는 수정되었음 -_-......... 
Posted by 모근원
상황 1 : 
SuperScene 이라는 상위클래스에서 private 변수로 CGPoint winSize 라는 변수를 생성해 두었음.

//  SuperScene.h

...

@interface SuperScene : CCScene {

CGSize winSize; //윈도우 사이즈

}

...


상황 2 : 
이 SuperScene 을 상속 받은 다른 클래스들에서는 상위 클래스에서 선언한 winSize 변수에 자유롭게 접근이 가능함. 이렇게 구현된 클래스가 수십개가 있는데 문제가 없었다.

그런데 SuperScene을 상속받은 수많은 클래스 중에서 유독 한 클래스에서 선언하지 않았다고 에러.. 
뭔가가 잘못되었음. (이밖에 상위 클래스인 SuperScene 에서 선언한 변수들은 죄다 에러)

상속받은 클래스에서 변수를 선언하려고하면 중복선언이라고 에러..





해결책 : 
@property 와 @synthesize 를 구현한 멤버변수가 없으면 엄한데서 오류가 나오기 시작한다!!!
내 경우엔 BattleScene 이란 하위 클래스(SuperScene을 상속받은..) 에서 @property 로 CurrentWeapon 이라는 멤버 변수를 보내주고 @synthesize 로 구현까지 해주었는데 정작.. CurrentWeapon 이라는 멤버변수를 선언하지 않았다;;;

- 이렇게 되어있으면 문제.. 정작 변수 선언이 되어있지 않았다.

@interface BattleScene : SuperScene {

}


@property (nonatomic, retain) CCSprite* currentWeaponMark;

@synthesize currentWeaponMark;


- 요렇게 해주거나 변수가 필요없으면 @property 와 @synthesize 를 삭제한다.

@interface BattleScene : SuperScene {

CCSpritecurrentWeaponMark;

}


@property (nonatomicretain) CCSprite* currentWeaponMark;

@synthesize currentWeaponMark;

Posted by 모근원


사랑스런 쏘쏘가 저번주에 선물해준 필립스 전기 면도기~
면도좀 깨끗이 하고 다니라는 여느님의 계시?





Sony NEX-5 / E18-55mm F3.5-5.6 OSS / RAW / Lightroom 3 / 2011. 1. 22

'내가찍은사진 > 디카사진들' 카테고리의 다른 글

짱어  (0) 2011.02.27
우리집 설 풍경  (0) 2011.02.27
오랜 친구들의 저녁식사  (0) 2011.02.27
내 생일 @2011.1.22  (2) 2011.01.23
MT  (0) 2011.01.23
눈오던 날  (0) 2011.01.23
Posted by 모근원
2011년 새해도 밝았고 앱을 만들어 앱스토어에 올리자! 라는 명목으로 맥을 구입한지도 3년째..
그간 맥북 기변에 업그레이드만 줄창 하다가 올해 목표는 진심으로 앱스토어에 앱을 올리는것으로 정했다.

처음엔 유용한 어플을 만들어 올릴까 했는데 눈이 점점 높아져서 어릴적부터 만들어보고 싶었던 게임을 만들기로 했다.
생각해보면 프로그래밍을 처음 배우기 시작했던것도 게임을 만들어보고 싶어서였었는데.. 
그냥 그렇게 10년도 넘게 훌쩍 지나가버렸다.

게임 그래픽은 죽마고우인 민태와 같이 작업하기로 하고 기획하고 기본 메소드들 만들기 시작하는데 하...
이거 cocos2d 라는 게임엔진이 상당히 잘 되어있다.
어플제작만 하고 게임제작은 난생 처음해보는 나도 공부한지 3일만에 쉬운 게임정도는 간단히(실은 그렇게 간단하지 않고 노가다가 필요하지만..) 만들수 있겠더라.

하여간 블로그에 공부하면서 개발하면서 얻은 노하우와 게임제작 기법등을 정리해 올려보기로 했다.
반년이내에 완성해서 앱스토어에 진출하리라~

*사진은 전투씬에서 충돌검사를 테스트하면서 찍은 스크린샷.
Posted by 모근원
2011년에도 생일이 찾아왔습니다.

처음으로 동생이 사준 생일 케잌


용산역 도착

영화보기전에 밥먹으러 가는길

소뽕

어떤 피자를 먹을지 고르는 중

피자 나오기전 샐러드 바 접수

내가 제일 좋아하는 고칼로리


고칼로리 위주로 식사

피자헛을 찾는 이유는 딱 하나, 맥주를 팔기 때문에!

용산역 피자헛에서 내려다본 풍경.


드디어 나온 슈프림님

고 칼 로 리!

하루 밖에 안지났는데 벌써 그립군..

후식 요거트.

요구르트 바나나

커피숍에서

설정아님. 진짜 통화중.

내사랑 소영이

프랑쓰

저녁먹으러 종로로 고고싱

광장시장 육회집

2000원 오른 12,000원.


맛은 그대로. :-)

서비스 국물도 얼큰하게~


Sony NEX-5 / E18-55mm F3.5-5.6 OSS / RAW / Lightroom 3 / 2011. 1. 22


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

우리집 설 풍경  (0) 2011.02.27
오랜 친구들의 저녁식사  (0) 2011.02.27
생일선물  (0) 2011.02.01
MT  (0) 2011.01.23
눈오던 날  (0) 2011.01.23
커피 대량 구입  (0) 2011.01.20
Posted by 모근원
좋은사람들과 성우리조트 1박2일 MT

기차타고 원주가는 길


원주 도착!

그래도 서울이 더 추웠던것 같음.




저녁식사


갈매기살~ 이날 고기를 남기다니 ㅠ

진선,현숙누나.

+소뽕

형님들~



문차장님

끝나가는 분위기



다음날 우째형님~

신비주의 

퉁퉁 부으셨슴다.



일어나라~

주방장 용택형

날이 추워 차 두대가 전부 얼어버린날.




사실은 내 셀프샷 임.


Sony NEX-5 / E18-55mm F3.5-5.6 OSS / RAW / Lightroom 3 / 2011. 1. 15~16


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

오랜 친구들의 저녁식사  (0) 2011.02.27
생일선물  (0) 2011.02.01
내 생일 @2011.1.22  (2) 2011.01.23
눈오던 날  (0) 2011.01.23
커피 대량 구입  (0) 2011.01.20
2011.1.8 데이트 @홍대,대학로  (0) 2011.01.11
Posted by 모근원
서울에 눈오던 날.

사무실에서 내려다 본 눈오는 잠실 사거리

막내 유원이

둘째 윤원이

Sony NEX-5 / E18-55mm F3.5-5.6 OSS / RAW / Lightroom 3 / 2011. 1. 15


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

생일선물  (0) 2011.02.01
내 생일 @2011.1.22  (2) 2011.01.23
MT  (0) 2011.01.23
커피 대량 구입  (0) 2011.01.20
2011.1.8 데이트 @홍대,대학로  (0) 2011.01.11
대학모임  (2) 2011.01.11
Posted by 모근원
UCC 아로마 리치 1회용 드립커피. 32포 구입.
한달치 커피 구입완료


스미야키보다는 역시 오리지날 블렌드가 내입엔 더 맛남.


Sony NEX-5 / E18-55mm F3.5-5.6 OSS / RAW / Lightroom 3 / 2011. 1. 20


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

내 생일 @2011.1.22  (2) 2011.01.23
MT  (0) 2011.01.23
눈오던 날  (0) 2011.01.23
2011.1.8 데이트 @홍대,대학로  (0) 2011.01.11
대학모임  (2) 2011.01.11
카메라 테스트  (0) 2011.01.10
Posted by 모근원
홍대에서 점심먹고 대학로가서 연극보기.


도리가라아게(?) + 카레 + 우동


히레까쓰 + 매운카레 + 우동


아 매웠습니다. 가성비는 그럭저럭. 맛나게 먹었음.


카레먹고 잠시 홍대 로모샵에서 사진전 구경하며 커피한잔


뭔가 보고 빵터지신 마느님.


둘다 포동포동 살이 올랐군요,,;;


립스틱 바르는척


끽연하는척


냠냠. 과자입니다.




로모그라피 코리아.


LC-A 홍보 대사




학구파 컨셉


스트로보 사용


포즈의 재발견


쿠키소녀


늙지도 않는 욱환형님


사진찍었더니 피곤해요




지금 다중노출전을 하고 있습니다. 구경오세요~


홍대 로모그라피 코리아 + 까페


킁!


대학로 도착.






urban


사랑하는 소영님 하사품.




날이 추워요~


d(-_-)b


연극보러 들어가기전에


죽여주는 이야기 세트.


입술보습도 중요합니다.


ISO 12800의 위력(?)


어두운 연극 공연장에서도 무리없이 셔터스피드 확보


공연이 끝나고 난뒤 배우들과~
아날 저의 상품명은 '하버드' 였습니다. not yet~!


땡글땡글 사랑스런 마느님.




웃으며 삽시다요


저녁에 술안주로 먹었던 떡볶이+순대+김말이


집으로 가는 버스 안에서


Sony NEX-5 / E18-55mm F3.5-5.6 OSS / RAW / Lightroom 3 / 2011. 1. 8


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

MT  (0) 2011.01.23
눈오던 날  (0) 2011.01.23
커피 대량 구입  (0) 2011.01.20
대학모임  (2) 2011.01.11
카메라 테스트  (0) 2011.01.10
작년 여름.  (2) 2011.01.03
Posted by 모근원
오랬만에 본 내 부하들.


삼겹살 지글지글


털털한 유댕이




소라.




역시 멋진 나.








표정의 마술사








컨셉쟁이들.


Sony NEX-5 / E18-55mm F3.5-5.6 OSS / RAW / Lightroom 3 / 2011. 1. 7


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

눈오던 날  (0) 2011.01.23
커피 대량 구입  (0) 2011.01.20
2011.1.8 데이트 @홍대,대학로  (0) 2011.01.11
카메라 테스트  (0) 2011.01.10
작년 여름.  (2) 2011.01.03
정신없는 하루하루  (0) 2010.06.20
Posted by 모근원
새로산 카메라 Sony NEX-5 수령후 테스트샷~
일단 조그맣고 가볍고 잘나오는거 같아 다행이다. 생각외로 만족감을 주는 기기 :-)
이제 g35만 사면 되겠다.

아이뽄4


iHub


내 맥북이


애물단지 매직 마우스


토로


분사저지?


사과밭 책상위


맥북 상판 테스트샷


나는 커피 내려마시는 남자

책상 테스트 샷.


Sony NEX-5 / E18-55mm F3.5-5.6 OSS / RAW / Lightroom 3 / 2011. 11. 6


'내가찍은사진 > 디카사진들' 카테고리의 다른 글

커피 대량 구입  (0) 2011.01.20
2011.1.8 데이트 @홍대,대학로  (0) 2011.01.11
대학모임  (2) 2011.01.11
작년 여름.  (2) 2011.01.03
정신없는 하루하루  (0) 2010.06.20
지금은 곤란하다.  (6) 2010.03.17
Posted by 모근원
모홈에 사진 포스팅을 오래도안 안했더니 일년치 사진이 하드에 가득 쌓여버렸다.

작년 사진은 작년 여름 소풍사진으로 퉁치고 올해부턴 착실히 블로그에 사진을 올려봐야겠다.




임진각 평화누리 공원에서. 마나님.






간단히 싸온 간식.


알록달록 초딩생 신발.








임진각.






















이동해서 해이리의 한 식당에서 늦은 점심.


배고파유~


























처제. 안나.








GF1 + 20.7 / 2010.8.7

'내가찍은사진 > 디카사진들' 카테고리의 다른 글

2011.1.8 데이트 @홍대,대학로  (0) 2011.01.11
대학모임  (2) 2011.01.11
카메라 테스트  (0) 2011.01.10
정신없는 하루하루  (0) 2010.06.20
지금은 곤란하다.  (6) 2010.03.17
로모 살아나다  (2) 2010.03.16
Posted by 모근원

- 이번 글은 보기좋게 PDF로 첨부합니다.




- 개인적인용도로 요약한 글이라 글에서는 경어체를 사용하지 않습니다. 글 읽으시는데 참고부탁드립니다.

- Mac의 Pages 로 작성한 후 블로그에 포스팅하려니 서식이 다 깨졌네요.

   PDF 파일로 보는것이 보기 좋습니다.


저번엔 안드로이드용 위치기반 지점찾기 (LBS)를 구현하였고, 이번에 아이폰용 뱅킹어플을 만들면서 아이폰용도 지점찾기를 어플로 구현할 필요가 생겼다.


이번엔 계속 써와서 익숙한 Java 가 아니라 Objective C 여서 시작하기가 막막했다. 배우면서, 삽질하며 완성시킨거라 버그도 있을것이고 여러부분에서 미숙한 점이 있을테지만 마찬가지로 까먹지 않기 위하여 정리를 해둔다.


1. 프로젝트에 프레임웍 추가하기.

프로젝트의 프레임웍에서 마우스 오른쪽버튼 (또는 옵션클릭)을 하여 프레임웍을 추가해준다.

사용자 위치정보를 가져올 CoreLocation.framework 와 지도표시에 필요한 MapKit.framework 을 추가해준다.


추가가 된것을 확인하면 성공.










2. 뷰에서 사용할 마커(어노테이션) 준비하기.


지도 앱들을 보면 다음과 같은 핀이 있는데 이것이 안드로이드에서는 마커, iOS에서는 어노테이션이라고 불리우는 드랍핀이다. 


그냥 써도 되지만 지점찾기 앱에서는 각 마커마다 지점의 정보를 가지고 있기

때문에 MKAnnotation 을 구현하여 커스텀 어노테이션을 만들어 쓰기로 했다.



//  BranchMarker.h

// 마커(어노테이션) 쓰일 객체.


#import <Foundation/Foundation.h>

#import <MapKit/MKAnnotation.h>


@interface BranchMarker : NSObject <MKAnnotation>{

//요거 세개는 어노테이션에 필수로 구현해줘야 동작한다.

CLLocationCoordinate2D coordinate;

NSString *title;

NSString *subtitle;

// 아래는 추가로 필요해서 변수 준비.

NSString *bussBrNm; //영업점명

NSString *bussBrTelNo; //영업점 전화번호

NSString *bussBrAdr; //영업점주소 (찾아오시는길)

NSString *trscDrtm; //거래시간

NSString *bussBrAdr2; //영업점주소 (주소)

NSString *markerType; //마커 타입 (0:지점, 1:ATM)

}


@property (nonatomic,assign) CLLocationCoordinate2D coordinate;

@property (nonatomic,copy) NSString *title;

@property (nonatomic,copy) NSString *subtitle;


@property (nonatomic,retain) NSString *bussBrNm;

@property (nonatomic,retain) NSString *bussBrTelNo;

@property (nonatomic,retain) NSString *bussBrAdr;

@property (nonatomic,retain) NSString *trscDrtm;

@property (nonatomic,retain) NSString *bussBrAdr2;

@property (nonatomic,retain) NSString *markerType;


@end

헤더에서는 coordinate, title, subtitle 을 필수로 구현해줘야 MKAnnotation 이 멀쩡히 돌아간다.


//  BranchMarker.m

#import "BranchMarker.h"


@implementation BranchMarker

@synthesize coordinate, title, subtitle;

@synthesize bussBrNm,bussBrTelNo,bussBrAdr,trscDrtm,bussBrAdr2,markerType;


-(void) dealloc{

[title release];

[subtitle release];

[super dealloc];

}


@end

구현파일에서는 특별히 구현할것이 없고 synthesize 만 충실히 해주도록 한다.



3. 뷰컨트롤러 준비하기.

이제 실제 지도를 구현해본다. 이번 어플에서는 크게 다음과 같이 네개의 뷰가 겹쳐져 있다.

맨 아래에 지도를 표시하는 MKMapView 가 깔리고 그 위로 서브뷰로 아이콘 버튼들이 있는 툴바,

그리고 툴바위에 역 지오코딩 (위도, 경도를 가지고 주소를 추적해내는 기술) 한 스트링이 UILabel 로 뿌려지고, 마지막으로 그 위에 어플이 로딩상태일때 로딩을 표시할 스피너가 올려져있다.


//  BranchMapViewController.h

// 지점찾기 컨트롤러.


#import <UIKit/UIKit.h>

#import <MapKit/MapKit.h>

#import <CoreLocation/CoreLocation.h>


//위치관리자, 맵뷰, 그리고 리버스 지오코더 딜리게이트를 구현한다.

@interface BranchMapViewController : UIViewController <CLLocationManagerDelegate , MKMapViewDelegate, MKReverseGeocoderDelegate>{

NSString *searchType; //지점,ATM 검색 타입

MKMapView *mapView; //지도

//,경도를 가지고 해당위치의 주소를 가지고 오는 리버스지오코더

MKReverseGeocoder *reverseGeocoder

//위지관리자. GPS,wifi 등으로 현재 기기의 위치를 가져온다.

CLLocationManager *locationManager;

CLLocation *lastScannedLocation; //마지막으로 검색된 위치를 저장할 객체.

UIActivityIndicatorView * spinner; //화면의 로딩 스피너.

UILabel *geoLabel; //툴바에 리버스지오코더의 결과를 표시한다.

}


@property (retain, nonatomic) NSString *searchType;

@property (retain, nonatomic) MKMapView *mapView;

@property (nonatomic, retain) MKReverseGeocoder *reverseGeocoder;

@property (nonatomic, retain) CLLocationManager *locationManager;

@property (nonatomic, retain) CLLocation *lastScannedLocation;

@property (nonatomic, retain) UIActivityIndicatorView * spinner;

@property (nonatomic, retain) UILabel *geoLabel;


//뷰컨트롤러를 만들때 검색타입을 지정한다. BRANCH/ATM

- (id)initWithShowType:(NSString *)showType;  

//지점정보를 HTTP통신으로 가지고 온다.
- (void)getBranchDataWithLocation:(CLLocation *)location; 

@end


메인 구현파일이라 엄청길다.

//  BranchMapViewController.m

#import "BranchMapViewController.h"

#import <MapKit/MapKit.h>

#import <CoreLocation/CoreLocation.h>

#import "BranchMarker.h"

#import "BranchMapGetDataAction.h"


@implementation BranchMapViewController


@synthesize searchType;

@synthesize mapView,reverseGeocoder,geoLabel;

@synthesize locationManager;

@synthesize lastScannedLocation;

@synthesize spinner;


- (id)initWithShowType:(NSString *)showType {

if ((self = [super init])) {

        // Custom initialization

self.searchType = showType;

    }

NSLog(@"initWithShow %@",self.searchType);

    return self;

}


//이미지로 커스텀 뷰를 만들어준다.

//_normalImg : 버튼 이미지, _touchImg : 눌럿을때 바뀔 이미지, _width : 이미지버튼의 가로길이, _height : 이미지버튼의 세로길이 , _sel : 버튼눌렀을때 액션

-(UIButton*) createCustomImageButtonWithNormalImgNm:(NSString*)_normalImg

  andTouchImg:(NSString*)_touchImg andWidth:(float)_width

andHeight:(float)_height andSEL:(SEL)_sel{

// 버튼 배경에 사용할 이미지 준비.

    UIImage *normalImage = [UIImage imageNamed:_normalImg];

    UIImage *touchImage = [UIImage imageNamed:_touchImg];

    

    // 버튼 생성 

//x,y,width,height

    CGRect buttonRect = CGRectMake(0.0f, 0.0f, _width, _height); 

    UIButton *button = [[[UIButton alloc

initWithFrame:buttonRect] autorelease];

    // 버튼의 배경 이미지 설정

    [button setBackgroundImage:normalImage forState:UIControlStateNormal];

    [button setBackgroundImage:touchImage forState:UIControlStateHighlighted];

    

    // 버튼에 액션 설정

[button addTarget:self action:_sel

forControlEvents:UIControlEventTouchUpInside];


return button;

}


- (void)viewDidLoad {

    [super viewDidLoad];

//searchType 널탕이 들어오면 기본적으로 지점 검색으로 한다.

if (self.searchType == nil) self.searchType = @"BRANCH";

//위치 관리자를 초기화한다.

self.locationManager = [[[CLLocationManager alloc] init] autorelease];

//딜리게이트는 self 설정후 하단에서 딜리게이트 구현.

self.locationManager.delegate = self;

//측정방법은 가장 좋게.

self.locationManager.desiredAccuracy = kCLLocationAccuracyBest

//2000m 이상 위치가 변경되면 노티를 .

self.locationManager.distanceFilter = 2000.0f

    [self.locationManager startUpdatingLocation]; //현재위치 가져오기 시작~

//지도 뷰를 만든다.

//뷰의 크기만큼 지도를 채운다.

mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];

mapView.showsUserLocation = YES; // 위치 표시.

[mapView setMapType:MKMapTypeStandard]; //지도 형태는 기본.

[mapView setZoomEnabled:YES]; //줌가능

[mapView setScrollEnabled:YES]; //스크롤가능

mapView.delegate = self; //딜리게이트 설정 (anotation 메소드를 구현한다.)

MKCoordinateRegion region;

MKCoordinateSpan span; //보여줄 지도가 처리하는 넓이 정의.

span.latitudeDelta = 0.02; //숫자가 적으면 좁은영역 까지 보임.

span.longitudeDelta = 0.02;

CLLocationCoordinate2D location = mapView.userLocation.coordinate;

//위치정보를 못가져왔을때 기본으로 보여줄 위치.

location.latitude = 37.566275; //37.490481 이건 우리집

location.longitude = 126.981794; //126.857790

region.span = span; //크기 설정.

region.center = location; //위치 설정.

[mapView setRegion:region animated:TRUE]; //지도 뷰에 지역 설정.

[mapView regionThatFits:region]; //지도 화면에 맞게 크기 조정.

[self.view addSubview:mapView]; //서브 뷰로 지도를 추가함.

//하단에 버튼들 toolbar 추가

//현재 뷰의 크기를 가져와서 상단 바의 길이가 조정되면 하단 바가 잘리는것을 방지하기 위함.

float heightPos = self.view.bounds.size.height

UIToolbar *toolbar = [[UIToolbar alloc

  initWithFrame:CGRectMake(0.0, heightPos - 50.0f , 320.0, 50.0)]; toolbar.barStyle = UIBarStyleBlackTranslucent; //툴바스타일은 까만 투명색

// 영역 잡아주는 버튼아이템. 왼쪽에 빈 영역 두고, 오른쪽으로 버튼들을 배치하기위함.

UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc]

  initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace

  target:nil action:nil];

 

//이미지 커스텀 버튼.

UIBarButtonItem *hereBtn = [[UIBarButtonItem alloc]

   initWithCustomView:[self createCustomImageButtonWithNormalImgNm:@"here.png"

   andTouchImg:@"here_pressed.png" andWidth:40.0f andHeight:40.0f

   andSEL:@selector(setSearchTypeToHere)]]; //현위치

UIBarButtonItem *branchBtn = [[UIBarButtonItem alloc]

   initWithCustomView:[self createCustomImageButtonWithNormalImgNm:@"atm_btn.png" 

   andTouchImg:@"atm_btn_pressed.png" andWidth:40.0f andHeight:40.0f 

   andSEL:@selector(setSearchTypeToATM)]]; //ATM검색

UIBarButtonItem *atmBtn = [[UIBarButtonItem alloc]

   initWithCustomView:[self createCustomImageButtonWithNormalImgNm:@"hana_btn.png"

   andTouchImg:@"hana_btn_pressed.png" andWidth:40.0f andHeight:40.0f 

   andSEL:@selector(setSearchTypeToBranch)]]; //지점검색

//툴바 아이템 배치

toolbar.items = [NSArray

arrayWithObjects:flexibleSpace,hereBtn,atmBtn,branchBtn,nil];


//툴바를 뷰에 추가.

[self.view addSubview:toolbar];

//툴바에 쓰인 버튼들 릴리즈.

[flexibleSpace release];

[hereBtn release];

[branchBtn release];

[atmBtn release];

[toolbar release];

//화면스피너 셋팅. 로딩중을 표시하기 위함.

self.spinner = [[UIActivityIndicatorView alloc

initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];

//화면중간에 위치하기위한 포인트.

[self.spinner setCenter:CGPointMake(320.0f/2.0, 480.0f/2.0)]; 

[self.view addSubview:spinner]; //스피너를 뷰에 추가하고 필요시에 start

//geoCoder 라벨 셋팅. '서울시 송파구 신천동' 따위를 툴바에 표시한다

geoLabel = [[UILabel alloc

initWithFrame:CGRectMake(5.0, heightPos - 45.0f, 160.0, 40.0)];

geoLabel.backgroundColor = [UIColor clearColor];

geoLabel.highlighted = YES;

geoLabel.highlightedTextColor = [UIColor whiteColor];

geoLabel.shadowColor = [UIColor blackColor];

geoLabel.textColor = [UIColor whiteColor];

geoLabel.textAlignment = UITextAlignmentLeft;

geoLabel.numberOfLines = 2; //두줄 표시 가능.

[self.view addSubview:geoLabel]; //뷰에 라벨 추가.

//초기 환영 메세지.

UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"위치기반 지점찾기" message:@"위치정보를 가져오는데 기기,통신상태에 따라 시간이 걸릴수 있으며 일부 동작하지 않는 기기도 있습니다.\n\n하단의 아이콘을 이용하여 현재 지도가 표시하고 있는 지역을 중심으로 지점/ATM 검색하실 있습니다." delegate:nil cancelButtonTitle:nil

otherButtonTitles:@"확인",nil];

[alert show];

[alert release];

}


//검색 타입 ATM으로 셋팅.

-(void)setSearchTypeToATM{

//현재 지도가 위치하는곳을 중심으로.

CLLocation *customLocation = [[CLLocation alloc

initWithLatitude:mapView.centerCoordinate.latitude 

longitude:mapView.centerCoordinate.longitude];

self.searchType = @"ATM";

[self getBranchDataWithLocation:customLocation]; //HTTP 통신

[customLocation release];

}


//검색 타입 지점으로 셋팅.

-(void)setSearchTypeToBranch{

//현재 지도가 위치하는곳을 중심으로.

CLLocation *customLocation = [[CLLocation alloc

initWithLatitude:mapView.centerCoordinate.latitude 

longitude:mapView.centerCoordinate.longitude];

self.searchType = @"BRANCH";

[self getBranchDataWithLocation:customLocation]; //HTTP 통신

[customLocation release];

}


//현위치

-(void)setSearchTypeToHere{

[self.locationManager startUpdatingLocation];  //로케이션 메니저 다시 시작~

}


//문자열 치환 메소드. source : 원본, 찾을문자열, 바꿀문자열.

-(NSString*)replaceStrSource:(NSString*)sourceStr 

strFrom:(NSString*)_from strTo:(NSString*)_to{

NSMutableString *mstr = [NSMutableString stringWithString:sourceStr];

NSRange substr = [mstr rangeOfString: _from];

while (substr.location != NSNotFound) {

[mstr replaceCharactersInRange: substr withString:_to];

substr = [mstr rangeOfString: _from];

}

return mstr;

}



//지도 데이터를 HTTP통신을 통해 받아와서 표시해준다.

- (void)getBranchDataWithLocation:(CLLocation *)location{

NSLog(@"getBranchDataWithLatitude:%f andLongitude:%f",

location.coordinate.latitude,location.coordinate.longitude);

//화면에 로딩스피너 스타트.

[self.spinner startAnimating];

//HTTP통신에 ContentProvide server 규격을 맞추기 위해, 위도,경도에서 콤마(.) 제거해서 보내야한다.

NSString *lat = [self replaceStrSource:

[NSString stringWithFormat:@"%f",location.coordinate.latitude]

strFrom:@"." strTo:@""];

NSString *lng = [self replaceStrSource:

[NSString stringWithFormat:@"%f",location.coordinate.longitude]

strFrom:@"." strTo:@""];

NSString *range = @"3000"; //기본 3Km반경 지점을 검색해 오게 만든다.

NSString *sType = @"0";

//ATM = 1, 지점 = 0

if ([self.searchType isEqualToString:@"ATM"]) sType = @"1";

else sType = @"0";


//HTTP통신으로 지점정보 가져오는 액션 초기화.

BranchMapGetDataAction *getAction = [[BranchMapGetDataAction alloc

initWithSearchType:sType andReqLat:lat andReqLng:lng andReqRange:range];

//HTTP통신으로 지점정보를 가져온다.

NSMutableArray *branchMarkerAry = [getAction getData];

//마커를 새로 찍기전에 기존에 지도에 있던 마커(annotation) 전부 지운다.

NSMutableArray *toRemove = [NSMutableArray arrayWithCapacity:1];

for(id annotation in mapView.annotations){

if (annotation != mapView.userLocation){

[toRemove addObject:annotation];

}

}

NSLog(@"remove %d annotations.",[toRemove count]);

[mapView removeAnnotations:toRemove];

//받아온 마커(annotation) 맵에 찍어낸다.

NSLog(@"branch marker count : %d",[branchMarkerAry count]);

if([branchMarkerAry count] > 0){

for (BranchMarker* marker in branchMarkerAry){

if (marker != nil) [mapView addAnnotation:marker];

}

}


//reverseGeocoding 시작.

self.reverseGeocoder = [[[MKReverseGeocoder alloc

initWithCoordinate:location.coordinate] autorelease];

    reverseGeocoder.delegate = self;

    [reverseGeocoder start];

//화면의 로딩 스피너 없애기.

[self.spinner stopAnimating];


}


//메모리 부족을 받았을때.

- (void)didReceiveMemoryWarning {

    // Releases the view if it doesn't have a superview.

    [super didReceiveMemoryWarning];

    NSLog(@"branchmap memory warning.");

    // Release any cached data, images, etc that aren't in use.

}


// 내릴때.

- (void)viewDidUnload {

    

NSLog(@"branchmap viewDidUnload");

[self.locationManager stopUpdatingLocation];

self.locationManager = nil;

self.reverseGeocoder = nil;

self.mapView = nil;

self.searchType = nil;

self.lastScannedLocation = nil;

self.spinner = nil;

[super viewDidUnload];

}


//객체 내려갈때.

- (void)dealloc {

NSLog(@"branchmap dealloc");

//사용한 객체들 릴리즈.

[mapView release];

[reverseGeocoder release];

[locationManager release];

[searchType release];

[lastScannedLocation release];

[spinner release];

    [super dealloc];

}



#pragma mark MKMapViewDelegate


NSString *tempTelNo; //어노테이션의 더보기에서 전화걸기를 누를때 임시로 전화번호를 저장할 변수.


//맵의 어노테이션 (마커) 표시.

-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id<MKAnnotation>)annotation{

if (annotation==self.mapView.userLocation){

[mV.userLocation setTitle:@"현재 위치"]; //현재위치 마커에 표시할 타이틀.

return nil; //현재 위치 마커일경우 커스텀 마커를 사용하지 않는다.

}

//현재위치 마커가 아닐때에는 지점마커이다.

BranchMarker *mk = (BranchMarker *) annotation;

MKPinAnnotationView *dropPin = nil; //마커 준비

static NSString *reusePinID = @"branchPin"; //마커 객체를 재사용 하기위한 ID

//마커 초기화

dropPin = (MKPinAnnotationView *)[mapView 

dequeueReusableAnnotationViewWithIdentifier:reusePinID]; 

if ( dropPin == nil ) dropPin = [[[MKPinAnnotationView alloc]

initWithAnnotation:annotation reuseIdentifier:reusePinID] autorelease];

//핀이 떨어지는 애니메이션

dropPin.animatesDrop = YES;

//마커 오른쪽에 (>) 모양 버튼 초기화.

UIButton *infoBtn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

dropPin.userInteractionEnabled = TRUE;

dropPin.canShowCallout = YES;

dropPin.rightCalloutAccessoryView = infoBtn;

//마커 왼쪽에 표시할 지점,ATM 아이콘

NSString* markerImg = nil;

if ([mk.markerType isEqualToString:@"0"]){

markerImg = @"hana.png";

dropPin.pinColor = MKPinAnnotationColorGreen;

} else {

markerImg = @"atm.png";

dropPin.pinColor = MKPinAnnotationColorRed;

}

dropPin.leftCalloutAccessoryView = [[[UIImageView alloc

initWithImage:[UIImage imageNamed:markerImg]] autorelease];


//마커 리턴

return dropPin;

}



//어노테이션의 더보기

-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view

calloutAccessoryControlTapped:(UIControl *)control{

BranchMarker *mk = (BranchMarker *) view.annotation;

tempTelNo = nil;

//얼럿메세지 초기화

NSString *alertMessage = [mk.title stringByAppendingString:@"\n"]; 

if ([mk.bussBrAdr length] > 1) //주소

alertMessage = [[alertMessage stringByAppendingString:@"\n"]

stringByAppendingString:mk.bussBrAdr];

if ([mk.trscDrtm length] > 1) //ATM운영 시간

alertMessage = [[alertMessage stringByAppendingString:@"\nATM : "

stringByAppendingString:mk.trscDrtm]; 

NSString* telTitle = nil; //전화걸기 버튼 타이틀.

if ([mk.bussBrTelNo length] > 1){ //전화번호

alertMessage = [[alertMessage stringByAppendingString:@"\n대표전화 : "]

stringByAppendingString:mk.bussBrTelNo];


telTitle = @"전화걸기";

}

tempTelNo = mk.bussBrTelNo;

//얼럿뷰 표시

UIAlertView *confirmDiag = [[UIAlertView alloc] initWithTitle:nil

message:alertMessage delegate:self cancelButtonTitle:@"닫기" 

otherButtonTitles:telTitle, nil];


[confirmDiag show];

[confirmDiag release];

}


//어노테이션의 더보기 (얼럿뷰) 에서 버튼 클릭.

-(void)alertView:(UIAlertView *)alertView 

clickedButtonAtIndex:(NSInteger)buttonIndex{

if (buttonIndex == 1){

NSLog(@"전화걸기 : %@",tempTelNo);


if (tempTelNo != nil){

[[UIApplication sharedApplication

openURL:[NSURL URLWithString:[@"tel:" 

stringByAppendingString:tempTelNo]]];

}

} else if (buttonIndex == 0) {

NSLog(@"닫기");

}

}


#pragma mark LocationManager

//위치가 변경되었을때 호출.

-(void)locationManager:(CLLocationManager *)manager

didUpdateToLocation:(CLLocation *)newLocation 

fromLocation:(CLLocation *)oldLocation {


NSString *strInfo = [NSString 

stringWithFormat:@"didUpdateToLocation: latitude = %f, longitude = %f",

newLocation.coordinate.latitude, newLocation.coordinate.longitude];

NSLog(@"%@",strInfo);


MKCoordinateRegion region; //레젼설정

region = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 2000, 2000);

MKCoordinateRegion adjustedRegion = [mapView regionThatFits:region];

[mapView setRegion:adjustedRegion animated:YES];

//마지막으로 검색된 위치를 다른곳에서 활용하기 위하여 설정.

self.lastScannedLocation = newLocation; 


//한번 위치를 잡으면 로케이션 매니저 정지.

[self.locationManager stopUpdatingLocation];

[self getBranchDataWithLocation:self.lastScannedLocation]; //화면에 마커찍기

}


//위치를 못가져왔을때 에러 호출.


-(void)locationManager:(CLLocationManager *)manager

  didFailWithError:(NSError *)error{

NSLog(@"locationManager error!!!");

//위치를 못가져왔을땐 현재 지도에 표시된 지역기준으로 지점검색 들어간다~

[self setSearchTypeToBranch];

//에러 다이얼로그 표시.

UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"위치기반 지점찾기" message:@"현재위치를 검색할수 없습니다.\n설정 > 일반 > 위치서비스 활성화 되어있는지 확인해주세요.\n\n위치정보를 가져올수 없어도 하단의 아이콘을 통하여 현재 지도의\n영업점/ATM 위치는 검색하실수\n있습니다." delegate:nil cancelButtonTitle:nil otherButtonTitles:@"확인",nil];

[alert show];

[alert release];

}


#pragma mark reverseGeocoder

//역지오코더 검색되었을때 UILabel 역지오코딩 내용 표시

-(void)reverseGeocoder:(MKReverseGeocoder *)geocoder

didFindPlacemark:(MKPlacemark *)placemark{


    if (geoLabel != nil){

//혹시 몰라 한번 try 싸줌.

@try {

NSString *geoString = @"";

//locality 서울특별시 subLocality 송파구 thoroughfare 신천동

//지역에 따라 특정 파라메터에 값이 없을 있음. nil체크 하여 표시함.

if (placemark.locality != nil

geoString = [[geoString 

stringByAppendingString:placemark.locality

stringByAppendingString:@" "];

if (placemark.subLocality != nil)

geoString = [[geoString 

stringByAppendingString:placemark.subLocality]

stringByAppendingString:@"\n"];

if (placemark.thoroughfare != nil)

geoString = [geoString

stringByAppendingString:placemark.thoroughfare];

//아무 정보도 받아올수 없으면 나라이름이라도 표시.

if ([geoString length] < 1 && placemark.country != nil)

geoString = placemark.country;

geoLabel.text = geoString; //UILabel 표시

}

@catch (NSException * e) {

//오류 발생하면 UILabel 비워줌.

NSLog(@"reverse GeoCoding error : %@",e);

geoLabel.text = nil;

}

@finally {

}

}

}


//역지오코더 에러 발생시 그냥 로그.


-(void)reverseGeocoder:(MKReverseGeocoder *)geocoder

didFailWithError:(NSError *)error{

    NSLog(@"MKReverseGeocoder has failed.");

}


@end



4. 데이터 받아오는 액션 준비하기.

 지점 데이터는 HTTP통신으로 받아오게 된다.

예를 들어 http://111.11.11.11:8888/getBranch.do?a=123&b=456 이런식으로 URL을 호출하게 되면 서버에서 리턴값이 스트링으로 “S;10;테스트지점;02-123-4567;서울시 구로구 개봉동;....”  이런식으로 세미콜론(;) 으로 구분된 문자로 내려오게 된다.

그러면 프로그램에서 해당 스트링을 잘라서 객체에 잘 집어넣으면 된다. 

이것은 컨덴트 서버와 규격을 맞추어 프로그래밍을 해야한다.

하나은행에서 쓰이는 지점정보 서버와의 통신은 대외비이므로 지도구현과 관계없는 부분은 생략하여 정리한다.

//  BranchMapGetDataAction.h

// HTTP 통신으로 컨덴츠 서버에서 데이터를 받아서 어노테이션에 셋팅하는 액션


#import <Foundation/Foundation.h>


@interface BranchMapGetDataAction : NSObject{

NSString *searchType; //검색조건

NSString *reqLat; //요청 위도

NSString *reqLng; //요청 경도

NSString *reqRange; //요청 범위 (메타 m 단위)

}


@property (nonatomic,retain) NSString *searchType;

@property (nonatomic,retain) NSString *reqLat;

@property (nonatomic,retain) NSString *reqLng;

@property (nonatomic,retain) NSString *reqRange;


- (id)initWithSearchType:(NSString *)_searchType andReqLat:(NSString *)

_reqLat andReqLng:(NSString *)_reqLng andReqRange:(NSString*)

_reqRange; //초기화 메소드

- (NSMutableArray*)getData; //데이터를 가져오는 메소드

- (NSString*)generateGeoCode:(NSString*)str; //서버의 응답 스트링 지오코드에 콤마 붙이는 메소드.


@end



//  BranchMapGetDataAction.m


#import "BranchMapGetDataAction.h"

#import "BranchMarker.h"

#import <MapKit/MapKit.h>


@implementation BranchMapGetDataAction

@synthesize searchType,reqLat,reqLng,reqRange;


//초기화 메소드.


(id)initWithSearchType:(NSString *)_searchType 

andReqLat:(NSString *)_reqLat andReqLng:(NSString *)_reqLng 

andReqRange:(NSString*)_reqRange {


if ((self = [super init])) {

        // Custom initialization

self.searchType = _searchType;

self.reqLat = _reqLat;

self.reqLng = _reqLng;

self.reqRange = _reqRange;

    }

    return self;

}


// 결과값 받아다가 어노테이션(마커) 배열로 리턴.

- (NSMutableArray *)getData{

//스테이더스 바에 로딩 표시. (데이터 가져오는 네트워크 상태 표시)

[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

//요청타입이 널탕이면 기본적으로 지점검색으로 셋팅.

if (self.searchType == nil || [self.searchType isEqualToString:@""]){

self.searchType = @"0";

}

//요청 URL

NSString *urlString = @"http://1.1.1.1/a/b.jsp?distance=";

urlString = [[urlString stringByAppendingString:self.reqRange]

stringByAppendingString:@"&map_x="];

urlString = [[urlString stringByAppendingString:self.reqLng]

stringByAppendingString:@"&map_y="];

urlString = [[urlString stringByAppendingString:self.reqLat]

stringByAppendingString:@"&svc_type="];

urlString = [urlString stringByAppendingString:self.searchType];

NSURL *url = [NSURL URLWithString:urlString];

NSLog(@"url : %@", urlString);

//리퀘스트 객체.

NSMutableURLRequest *request = [[[NSMutableURLRequest alloc]

initWithURL:url] autorelease];

//레스폰스 객체,에러 객체 준비.

NSURLResponse *response = nil;

NSError *error = nil;

//데이터 받아오기.

NSData* receiveData = [NSURLConnection sendSynchronousRequest:request

returningResponse:&response error:&error];

//받아온 데이터 파싱.

NSString *str = [[NSString alloc] initWithData:receiveData 

encoding:0x80000000 + kCFStringEncodingDOSKorean];

str = [str stringByReplacingPercentEscapesUsingEncoding:

0x80000000 + kCFStringEncodingDOSKorean];


//NSLog(@"DATA GETTED!!! : %@",str);

//에러가 발생하였으면 에러표시.

if(error != nil) {

NSLog(@"%@", [error localizedDescription]);

UIAlertView *alert = [UIAlertView alloc];

[alert initWithTitle:@"에러" message:[NSString 

stringWithFormat:@"서버에 접속할 없습니다.\n%@",

[error localizedDescription]] delegate:self 

cancelButtonTitle:@"확인" otherButtonTitles:nil];

[alert show];

[alert release];

}


//마커배열 준비.

//받아온 스트링을 세미콜론으로 잘라서 배열로 넣어버린다.

NSArray *branchArray = [str componentsSeparatedByString:@";"]; 

NSMutableArray *returnAry = [[NSMutableArray alloc] init]; //리턴할 배열 준비.

NSLog(@"getted branch array size : %d",[branchArray count]);

@try {

//i=2 준것은 첫번째 배열엔 성공여부(S) 두번째 배열엔 받아온 지점 갯수 (int#) 이다

안쓰이므로 무시하고 세번째 배열원소부터 사용하도록한다.

for (int i=2; i<([branchArray count]-1); i+=7) { 

//마커 준비.

BranchMarker *marker = [[BranchMarker alloc] init];

// 셋팅.

marker.bussBrNm = [branchArray objectAtIndex:i];

marker.bussBrTelNo = [branchArray objectAtIndex:i+1];

marker.bussBrAdr = [branchArray objectAtIndex:i+3];

marker.bussBrAdr2 = [branchArray objectAtIndex:i+2];

marker.trscDrtm = [branchArray objectAtIndex:i+4];

//마커에 위도,경도 정보 셋팅.

MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };

region.center.latitude = [[self generateGeoCode:

[branchArray objectAtIndex:i+6]] floatValue];

region.center.longitude = [[self generateGeoCode:

[branchArray objectAtIndex:i+5]] floatValue];

region.span.longitudeDelta = 0.01f;

region.span.latitudeDelta = 0.01f;

marker.coordinate = region.center; //셋팅!

//찾아오시는길은 값이 있을때에만 셋팅.

if ([ marker.bussBrAdr length] > 1

marker.subtitle = marker.bussBrAdr;

marker.markerType = self.searchType; //마커 타입 (지점/ATM)

if ([self.searchType isEqualToString:@"0"]){

//지점이면 이름에다가 "지점" 이라는 글씨 추가로 셋팅.

marker.title = [marker.bussBrNm 

stringByAppendingString:@" 지점"];

} else {

marker.title = marker.bussBrNm;

}

//배열에 추가.

[returnAry addObject:marker];

//마커 릴리즈.

[marker release];

}

}

@catch (NSException * e) {

//가끔 컨덴츠 서버에서 오류가 데이터를 내리는 경우가 있다.에러,보정처리는 알아서~

.....삭제.....

}

@finally {

}




//검색결과가 없을때 오류 표시.

if ([returnAry count] == 0){

NSString *errorTitle = nil;

NSString *errorMsg = @"\n\n네트워크 오류일수 있으니 다른지역으로 이동, 또는 지도를 확대하여\n검색하시거나 잠시 다시 시도해주세요.";

if ([self.searchType isEqualToString:@"0"]){

errorTitle = @"영업점 검색오류";

errorMsg = [[NSString stringWithString:

@"해당 지역에 '영업점' 검색결과가\n없습니다."] stringByAppendingString:errorMsg];

} else {

errorTitle = @"ATM 검색오류";

errorMsg = [[NSString stringWithString:

@"해당 지역에 'ATM' 검색결과가\n없습니다."] stringByAppendingString:errorMsg];

}

UIAlertView *alert = [[UIAlertView alloc]initWithTitle:errorTitle

message:errorMsg delegate:nil 

cancelButtonTitle:nil

otherButtonTitles:@"확인",nil];

[alert show];

[alert release];

}

//스테이더스바 로딩 끄기.

[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

//배열 리턴.

return returnAry;

}



// 위도 경도에 콤마 붙이기. ex(37123456 -> 37.123456)

-(NSString*)generateGeoCode:(NSString*)str {

if (str != nil && [str length] >= 8) {

int lastIdx = [str length];

int middIdx = lastIdx - 6;

NSString* s1 =[str substringWithRange:

NSMakeRange (0,middIdx)]; //콤마 앞의 스트링

NSString* s2 =[str substringWithRange:

NSMakeRange (middIdx,6)]; //콤마 뒤의 스트링

NSString *output = [[s1 stringByAppendingString:@"."]

stringByAppendingString:s2]; //콤마 붙여서 리턴

return output;

}

return nil;

}


@end



5. 실행 스크린샷.

최초 실행하면 나오는 안내문구.



현재위치를 표시하며 현재위치 기준으로 영업점들을 찾아서 주루룩 찍어낸다.



현재위치 마커엔 title 로 "현재위치" 라고 셋팅 해 두었다.



지점/ATM 마커를 누르면 간단한 정보가 나온다.



간단한 정보에서 오른쪽 버튼을 누르면 상세한 정보가 나온다.



선택 지점/ATM으로 전화걸기



현위치 말고도 지도를 옮겨 원하는 지역에서 검색을 할 수도 있다.



원하는 지역으로 옮겨가서 하단의 지점/ATM 아이콘을 누르기만 하면 된다.



마지막으로 우리동네도 한번.



6. 해결하지 못한 부분


- MKMapview 의 지도화면에 특정 지점을 눌러서 뭔가 액션을 해주고 싶어 MKMapview를 상속하여 커스텀 맵뷰를 구현했는데 터치이벤트에서 오류 작렬! 그리고 줌인 줌아웃시에 오류가 난다.. ㅠ


- iOS 4부터는 스테이터스 바에 위치서비스 사용 아이콘이 나오는데 분명 LocationManager 를 stop 시켜주었는데도 아이콘이 계속 떠있다. Tweeter 어플등을 보면 현위치를 가져오고 난 뒤에는 아이콘이 사라지는것 같은데..

solution : 

mapView.showsUserLocation = YES;

이 문제였다. 현위치가 필요하지 않을때 적당한 시점에서 NO 를 넣어주면 현재위치 가져오는것을 종료하고 스테이더스바에 위치서비스 아이콘이 없어지게 된다.


- 3G 네트워크 등. 인터넷 상태가 불안정할때 처리에 오래 걸리는 문제. 데이터를 받아오는 순간에 프로그램이 정지된것 처럼 보인다. iOS 도 스레드를 돌려서 백그라운드로 돌려야 하나? 이건 다음버전에서 고민.


- 이번 글은 보기좋게 PDF파일로 첨부합니다.




2010.11.17 모근원 (Geunwon,Mo)

mokorean@gmail.com

twitter : @mokorean

http://Lomohome.com



* 추가  TIP : Google 로고 옮기기.
현재 툴바로 구글로고를 가려지게 되어있는데 이게 앱스토어에 올라갈경우 리젝사유가 된다고 한다.
그래서 바로 구글링해서 구글로고 옮기는법을 찾았다.



먼저 MKMapView 에다가 메소드를 추가할것이니 카테고리로 구현하도록 한다.
나는 클래스를 추가하였다.

//

//  BranchMapMKMapView.h

//  BranchMap

//

//  Created by Geunwon,Mo on 10. 11. 18..

//  Copyright 2010 Lomohome.com. All rights reserved.

//


#import <MapKit/MapKit.h>


@interface MKMapView (Additions) 


- (UIImageView*)googleLogo;


@end


//

//  BranchMapMKMapView.m

//  BranchMap

//

//  Created by Geunwon,Mo on 10. 11. 18..

//  Copyright 2010 Lomohome.com. All rights reserved.

//


#import "BranchMapMKMapView.h"



@implementation MKMapView (Additions)


- (UIImageView*)googleLogo {

UIImageView *imgView = nil;

for (UIView *subview in self.subviews) {

if ([subview isMemberOfClass:[UIImageView class]]) {

imgView = (UIImageView*)subview;

break;

}

}

return imgView;

}


@end


카테고리 추가후 지도를 구현하는 ViewController  (여기서는 BranchMapViewController.m)에다가 카테고리로 추가한 메소드를 뷰가 나오기전에 실행해서 구글로고의 위치를 변경하도록 한다.

#import "BranchMapGetDataAction.h"


....생략.....



////////////// Custom MapView Category start ///////////////

float _toolBarPositionY = 0.0f; //<- 이놈은 viewDidLoad 안에서 값을 셋팅한다. 현재 화면 툴바의 Y좌표값.


- (void)viewDidAppear:(BOOL)animated {

NSLog(@"view did appear");

[self relocateGoogleLogo];

}


- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {

[self relocateGoogleLogo];

}


- (void)relocateGoogleLogo {

UIImageView *logo = [mapView googleLogo];

if (logo == nil)

return;

CGRect frame = logo.frame;

frame.origin.y = _toolBarPositionY - frame.size.height - frame.origin.x;

logo.frame = frame;

}

////////////// Custom MapView Category end ///////////////



Posted by 모근원
지난 포스트를 보면 웹뷰에서 자바스크립트 alert 을 웹뷰에서 재정의 해서 썼는데
개발을 하다가 난관에 부딫혔다. 자바스크립트의 alert 말고, confirm 을 사용할때에도 재정의가 필요해졌다.

confirm 창은 특성상, '예','아니오' 버튼이 나오고 이 버튼이 눌리면 버튼에 따라 액션을 달리 취해주어야한다.

그런데 UIAlertView 를 show 하게 되면 예, 아니오 버튼과 상관없이 밑의 코드가 주~욱 실행되버려서 예,아니오의 리턴값을 받을수가 없다. (말로 표현하자니.. 이거 영..)


억지로 버튼을 누르기전까지 루프를 돌려서 지연을 시키고, UIAlertView 가 사라지는 시점에 버튼의 결과를 가지고와서 처리하는것으로 변경한 코드.
분명 더 좋은 방법이 있을것 같은데 ㅠ 못찾겠다.

*헤더부분은 생략.

//@Geunwon,Mo 2010.9.17 : UIWebView Javascript alert 위한 카테고리.

@implementation UIWebView (JavaScriptAlert)

.... 저번포스트 생략 ....

static BOOL diagStat = NO; //예,아니오 버튼의 상태를 저장할 임시 변수

- (BOOL)webView:(UIWebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame{

NSLog(@"javascript ConfirmPanel : %@",message);

UIAlertView *confirmDiag = [[UIAlertView alloc] initWithTitle:nil message:message delegate:self cancelButtonTitle:NSLocalizedString(@"Yes", @"") otherButtonTitles:NSLocalizedString(@"No", @"아니오"), nil];

[confirmDiag show];

//버튼 누르기전까지 지연.

while (confirmDiag.hidden == NO && confirmDiag.superview != nil)

[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01f]];

[confirmDiag release];

return diagStat;

}



//요놈은 UIAlertViewDelegate 를 구현하여 버튼이 눌렸을때 실행될 메소드

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{

//index 0 : YES , 1 : NO

if (buttonIndex == 0){

//return YES;

diagStat = YES;

} else if (buttonIndex == 1) {

//return NO;

diagStat = NO;

}

}

@end


동작순서는 웹뷰에서 confirm 자바스크립트 함수가 호출이 되면 카테고리로 구현한 webView: runJavaScriptConfirmPanelWithMessage 메소드가 호출이되고,
UIAlertView 로 메세지창(+예,아니오)을 띄우고 while 문을 통하여 메세지 창이 없어질때까지 루프..;;
그리고 메세지창에서 버튼을 누르면 alertView: clickedButtonAtIndex 메소드가 호출이 되고 미리 준비해둔 전역변수에 버튼에 따라 상태값을 저장.
메세지창이 닫히면서 while 루프가 끝나게 되고 전역변수의 값을 자바스크립트로 리턴. 하게된다.


* 더 좋은 방법이 있으시면 공유 부탁드립니다. ㅠㅠ
Posted by 모근원