Nov 05

오랜만에 포스팅합니다. 최근 앱들이 늘어나면서 업데이트 등으로 분주했습니다. 아기 젖병도 소독하고 -_-;;

2일 전에 국제 전화가 왔었습니다.

최근에 심사 때문에 애플 리뷰 팀과 통화를 한 적이 있어서.. 애플인 것 같은 느낌이 들었습니다. 그래서 대수롭지 않게 생각하고 전화를 받았는데,

“안녕하세요. 애플입니다” 라고 한국 분이 말씀을 하시더니… “Make Num 을 앱 스토어의 메인 페이지에 소개하려고 하는데 Support URL에 게시판이나 제 이메일 주소를 써달라고 했습니다”.

순간 (사무실이었지만) 핸드폰을 떨어트릴 뻔했습니다. 부랴부랴 이메일을 기재하고 메일로 답변을 드렸습니다.

그리고 오늘 오전에 iTunes Store를 들어가 보니 아래와 같이 (붉은 테두리) Make Num이 Game 카테고리의 “What’s Hot”에 떴습니다.

솔직히, 작년 9월 처음 앱 개발을 하면서 만들었던 첫 앱이었고, 애착이 가서 올해 6월까지는 업데이트를 했지만, 그 이후로는 다른 앱들 때문에 거의 방치를 하고 있었습니다. 그래서 좀 부끄럽기도 하고 ^^;;;

아무튼.. “성은”을 입었습니다.

Tagged with:
Aug 23

iPhone은 NSURLRequest와 NSURLConnection 를 이용해서 http request와 response를 쉽게 처리할 수 있게 해준다.

첫 아이폰 앱이었던 Make Num을 개발할 때 http request/response를 위한 유틸 클래스를 만들었던 것을 이용해, http request로 이미지를 받아서 보여주는 것에 대해 다루는 튜토리얼이다.

Make Num 때에는 Ranking 서버에서 점수와 해당 정보를 받아오는 것을 string으로 받아올 때 사용했다.

.

App to Make in this tutorial

이번 튜토리얼에서 만들 앱은 아래 Picasa에 있는 이미지를 받아서 UIImageView에 뿌려주는 간단한 앱이다.

http://lh4.ggpht.com/_85hIOLhClFE/SpAB03RUZtI/AAAAAAAAFgs/VdhbDuH8riQ/sample.png

Simulator에서 실행시킨 모습은 아래와 같다 (싱가폴에서 찍은 사진이다. ㅋ).

그림 9 by you.

.

HttpManager

HttpManager는 URL Loading System Guide 문서를 보고 만든 Class이다.

URL을 String으로 주면, 해당 주소의 웹페이지를 읽어서 NSMutableData로 전달해준다. 이 Tutorial의 경우는 웹 페이지가 image이기 때문에 NSMutableData로 UIImage를 만들면 되고, 페이지가 문자열일 경우는 NSString을 만들어서 처리하면 될 것이다.

HttpManager를 사용하기 위해서는 Caller가 HttpManagerDelegate를 Adopt 하게 했다. Http request 시 callback 되는 method들을 처리해주기 위해서이다.

HttpManager를 들여다보자.

.

HttpManager Class 선언 부

HttpManagerDelegate를 받은 Caller를 받기 위한 delegate와 response data를 받기 위한 received data를 가지고 있다.

@protocol HttpManagerDelegate;

@interface HttpManager : NSObject {

	id  delegate;

	NSMutableData *receivedData;
}

@property (nonatomic, assign) id delegate;
@property (nonatomic, retain) NSMutableData *receivedData;

.

HttpManagerDelegate protocol

HttpManagerDelegate protocol은 http request 시 request가 완료되었을 때와 실패했을 때 callback 되는 method들을 정의하고 있다. 그 외 request 시 callback 되는 NSURLConnectionDelegate의 connection method들은 내부적으로 처리했다.

@protocol HttpManagerDelegate

-(void)connectionDidFail:(HttpManager*)aHttpManager;
-(void)connectionDidFinish:(HttpManager*)aHttpManager;

.

[HttpManager initWithUrl: delegate:]

HttpManager를 initWithUrl로 init 하면 바로 주어진 url의 loading을 시작한다. 즉, url에 대해서 NSURLRequest를 만들고, NSURLConnection 생성해서 loading을 시작한다. 여기서 NSString의 URL을 [NSString stringByAddingPercentEscapesUsingEncoding:]에 NSUTF8StringEncoding을 지정해서 encoding하는 것을 잊지 말아야 한다. 공백이나 특수 문자 등을 ‘%’를 써서 encoding 해준다.

-(id)initWithUrl:(NSString*)aURL delegate:(id)aDelegate {

	if( self = [super init] ) {

		// delegate
		self.delegate = aDelegate;

		// URL string을 아래와 같이 %가 필요한 곳에 붙여주는 encoding 해줘야한다.
		NSString *escapedUrl = [aURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

		// create the request
		NSURLRequest *aRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:escapedUrl]
								cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
		// create the connection with the request
		// and start loading the data
		NSURLConnection *aConnection=[[NSURLConnection alloc] initWithRequest:aRequest delegate:self];
		if (aConnection) {
			// Create the NSMutableData that will hold
			// the received data
			// receivedData is declared as a method instance elsewhere
			receivedData = [[NSMutableData data] retain];
		} else {
			// inform the user that the download could not be made
			// [todo] error
		}
	}

	return self;
}

.
[HttpManager connectionDidFinishLoading:]

HttpManager의 다른 method들은 간단하며 HttpManagerDelegate를 adopt 한 caller의 해당 method를 불러주기 위해 caller가 해당 method를 가지고 있는지 체크하는 코드를 보라고 connectionDidFinishLoading method 코드를 보여준다. Caller의 connectionDidFinishLoading method가 불리면 Caller는 HttpManager의 receivedData를 받아서 사용하면 된다.

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {

	if( [self.delegate respondsToSelector:@selector(connectionDidFail:)]) {
		[self.delegate connectionDidFinish:self];
	}

	[connection release];
	if( receivedData != nil) {
		[receivedData release];
		receivedData = nil;
	}
}

.

UI 부분 완성하기

이 번에도 IB (Interface Builder) 없이 간단하게 UI를 만들겠다.

시나리오는 아래와 같다.

1. applicationDidFinishLaunching 에서 UIImageView, UIActivityIndicatorView를 생성하고 Indicator Animation을 start한 후 HttpManager에 Picasa의 이미지를 가져오게 http request를 요청한다.

2. HttpManagerDelegate의 connectionDidFinish 가 callback 되면 HttpManager의 receivedData를 가져와서 UIImage를 만들고 UIImageView에 넣어준다.

.

URLLoadingSystem_imageAppDelegate class 선언

URLLoadingSystem_imageAppDelegate는 HttpManagerDelegate를 adopt해서 아래와 같다.

#import
#import "HttpManager.h"

@interface URLLoadingSystem_imageAppDelegate : NSObject  {
    UIWindow *window;

	UIImageView *imageView;
	UIActivityIndicatorView *indicator;

	HttpManager *httpManager;
	NSMutableData *receivedData;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) UIImageView *imageView;

-(void)getImageFrom:(NSString*)url;

@end

.

UIApplicationDelegate의 applicationDidFinishLaunching

위에서 설명한 것과 같이 UIImageView를 생성해서 UIWindow에 add하고 UIActivityIndicatorView를 생성해서 UIImageView에 add 후 animation을 시작하고 HttpManager를 picasa url로 init해서 URL Loading을  시작한다.

- (void)applicationDidFinishLaunching:(UIApplication *)application {    

    // Override point for customization after application launch
	// create UIImageView
	imageView = [[UIImageView alloc] initWithFrame:window.frame];
	[window addSubview:imageView];

	// image를 받을 때까지 indicator를 동작시킨다.
	indicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake( window.frame.size.width/2 - 20, window.frame.size.height/2-20, 40, 40)];
	indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
	[imageView addSubview:indicator];
	[indicator startAnimating];

	// 아래 url에서 이미지를 가져와서 UIImageView에 보여준다.
	[self getImageFrom:@"http://lh4.ggpht.com/_85hIOLhClFE/SpAB03RUZtI/AAAAAAAAFgs/VdhbDuH8riQ/sample.png"];

    [window makeKeyAndVisible];
}

-(void)getImageFrom:(NSString*)url {
	if( httpManager ) {
		[httpManager release];
		httpManager = nil;
	}

	httpManager = [[HttpManager alloc] initWithUrl:url delegate:self];
}

.

HttpManagerDelegate의 connectionDidFinish를 adopt

connectionDidFinish: 는 URL Loading이 완료되었을 때 callback 된다. 여기서 HttpManager의 receivedData를 가져와서 아래와 같이 UIImage를 생성해서 UIImageView에 넣어주면 완료된다.

#pragma mark HttpManagerDelegate
-(void)connectionDidFinish:(HttpManager*)aHttpManager {
	[indicator stopAnimating];

	receivedData = httpManager.receivedData;
	imageView.image = [[UIImage alloc] initWithData:receivedData];
}

.

Http Request Fail 처리

HttpManagerDelegate의 connectionDidFail은 Http Request가 실패했을 때 callback 된다. 아래와 같이 사용자에게 실패했다는 메시지를 UIAlertView로 보여준다.

-(void)connectionDidFail:(HttpManager*)aHttpManager {
	[indicator stopAnimating];

	UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:@"Fail" message:@"Couldn't connect" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] autorelease];
	[alertView show];
}

.

Source Code

이 Tutorial의 코드는 아래에서 받을 수 있다.

.

Ref 1. URL Loading System

Tagged with:
Mar 29

Make Num Korea 가 v1.1.0으로 업데이트 되었습니다.
Make Num (Sum It Up)에 비해 업데이트가 좀 늦긴 했는데, 대부분의 기능들이 모두 반영되었습니다.

이 번 업데이트의 내용은 다음과 같습니다.

- Full screen
- 랭킹 서버 모듈의 메모리 릭 제거   
- 3초 카운트다운
- 5초 알람음
- Special Thanks 추가
- 점수 정보 대문자 표기
- 세계 기록의 스크롤 문제 수정
- 네트워크 연결이 안될 경우의 경고 메시지 추가

리뷰를 원하시는 분은 메일 (gidaeyeo@gmail.com) 주시면 redeem (promotion) 코드를 보내드리겠습니다~.

IMG_0058 by you.

Tagged with:
Mar 04

US 애플 앱 스토어의 Board 카테고리에 Make Num (Sum It Up) 이 Top Paid에서 84위에 랭크 되었군요.

Board가 약 680개의 앱 뿐인 작은 카테고리이지만.. Top Paid 클릭한 화면에 나와서 자축해봅니다~
(※ Puzzle 이런 곳은 1,960개 정도의 App이 있죠…)

사실 수익은 아주 적습니다. ^^;;;

Tagged with:
Mar 03

방금 확인을 하니 애플의 심사가 끝나고 Make Num Lite (Sum It Up) 이 v1.1.1로 업데이트 되었습니다.

App Store Link

이 번 업데이트의 내용은 다음과 같습니다.

- Countdown added
  게임 시작 전에 3초 카운트 다운을 합니다.

- 5 sec alarm added
  게임 종료 5초부터 매 초 마다 알람 음을 발생시킵니다.

- Sub title (Sum It Up) added on main view
  Mac Rumor Forum의 Bessamy 님이 제안해주신 Sum It Up 을 부제로 택했습니다.

Make Num (Sum It Up) full version의 v1.1.0 update도 3일 정도 걸렸는데, lite도 금방 된 것 같습니다.

Tagged with:
preload preload preload