'네트워크'에 해당되는 글 1건

  1. 2012.10.05 Multipart를 이용한 POST데이터 전송

출처 : http://blog.naver.com/legendx/40133323323


모바일 네트워크에서 서버로 보내는 자료는 일반적으로 문자열이지만 간혹 이미지를 전송해야 하는 경우가 있다.

Content-Type을 Multipart로 설정하면 byte 전송이 가능한데, 이 때 이미지를 서버로 전송할 수 있다.

Multipart를 구현한 지는 몇달 되었다. 그 때 당시 검색할 땐 Multipart로 이미지 전송하는 글들을 볼 수 있있지만, 문자열과 혼합된 여러 자료를 넘기는 방법은 소개되지 않았던 것으로 안다.

물론 시간이 지난 지금에서야 방법이 소개되었는지는 모르겠지만, 같은 고민을 하는 이들에게

작은 도움이 되고자 포스팅하려 한다.


Multipart는 말 그대로 여러 유형의 데이터를 전송할 때 사용되는 Content-Type 중 하나다.

본인도 본래는 서버로 문자열만 전송하다가 이미지를 전송하게 되어 사용하게 되었다.

Obj-C에서는 NSURLConnection으로 보내기로 한다.

NSString urlString = @"http://localhost/multipart.php";

NSString boundary = @"SpecificString";

NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];

[request setURL:[NSURL URLWithString:urlString]];

[request setCachePolicy:NSURLRequestUseProtocolCachePolicy];

[request setHTTPMethod:@"POST"];

NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];

[request addValue:contentType forHTTPHeaderField: @"Content-Type"];

// 여기까지가 서버에 접속하기 위한 기본 설정이다.


위 소스를 보자. urlString은 URL 객체로, 전송할 목적지 주소를 적어주면 된다.

문자열로 boundary를 초기화하고 있는데, 이 때 사용되는 문자열은 어떠한 것이든 상관 없다.

이 문자열은 넘겨지는 각 인자를 구분하기 위한 구분자이다.

request는 서버로 요청하기 위한 값들을 갖게 된다.

contentType은 보는바와 같이 multipart/form-data로 정해주면 되고, boundary를 설정해주는데

아까 정해놓은 문자열 boundary를 사용하면 되겠다.

자주색으로 되어있는 곳만 자신의 실정에 맞게 수정하자.

위와 같이 했다면 전송할 준비는 마친 것이다. 아래부터 전송할 인자를 설정한다.

NSMutableData *body = [NSMutableData data];


[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"no\"\r\n\r\n%d", no] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"table_name\"\r\n\r\n%@", tableName] dataUsingEncoding:NSUTF8StringEncoding]];

//여기까지가 문자열을 보내는 소스이다.


위 소스에서 파란색은 서버단에서 받을 때 사용하는 Key다. PHP로 치자면

$_POST["이 곳에 들어갈"]; Key 인 것이다.

한 마디로, 넘어온 자료들을 식별하는 이름이라고 하자.

자주색은 실제 넘길 값이다. 말 그대로 서버로 넘기고 싶은 자료(변수)를 넣어주면 된다.

위에 보면 boundary 앞에 --을 붙였는데, --boundary 가 하나의 인자를 감싸는 형태로 추가된다. 하나의 인자 위 아래에 boundary가 있어서 boundary를 만나는 것으로 인자의 시작과 끝을 알 수 있는 것이다.

만약 boundary를 "0090090"으로 정하였다면

--0090090 이 문자열이 각 인자를 위 아래에서 감싸는 것이다.

위 내용에서 \r\n은 줄바꿈 문자이다.


위의 내용을 해석해보면

(줄바꿈)

--SpecificString

(줄바꿈)

Content-Disposition: form-data; name="no"

(줄바꿈)

(줄바꿈)

16

(줄바꿈)

--SpecificString

(줄바꿈)

Content-Disposition: form-data; name="table_name"

(줄바꿈)

(줄바꿈)

test

...이하 줄임...

이런식으로 될 것이다.

위에서 문자열을 넘기는 법에 대해 알아보았다. 이어서 아래의 소스를 사용하면 이미지도 같이 전송할 수 있다.

NSData *imageData = UIImageJPEGRepresentation([photoButtonimageForState:UIControlStateNormal], 0.8);

[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"image\"; filename=\"%@\"\r\n", @"image.jpg"] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[NSData dataWithData:imageData]];

[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[request setHTTPBody:body];

파란색 image는 역시 서버에서 사용할 변수명이고, 자주색 image.jpg는 서버 변수에 저장될 값이다.(여기선 파일명)

자주색 photoButton은 전송할 이미지이다. 자료형은 UIImage이고, 전송하고자 하는 파일명으로 UIImage 객체를 생성하여 사용하면 된다.

자주색 0.8은 JPEG의 품질로, 0~1까지 있으니 편한대로 사용하시기 바란다.

위의 boundary는 이 전의 boundary들과 다르다. 바로 뒤에 --이 붙는다는 것이다. boundary 뒤에 --이 붙음으로써 인자 나열이 끝났음을 알린다.

이하 소스는 그대로 사용해도 무방하다.

사실 소스는 이해하고 사용하는 것이 중요한데, 소스 전체를 설명드리지 못하는 점 양해 부탁드린다. 여러분의 검색능력을 본인은 믿는다.

여기까지가 문자와 이미지를 POST로 함께 넘기는 방법이다. 설정이 끝났으니 서버로 전송해보자.

NSData *urlData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

단 한 줄이지만 매우 중요하다. 지금까지 설정한 request를 실어서 보내는 명령어이다. 서버와의 통신이 마무리되면 서버에서 보낸 결과값을 urlData에 받는 것이다.

이 데이터를 문자열로 활용하려면

NSString *returnString = [[NSString alloc] initWithData:urlData encoding:NSUTF8StringEncoding];

로 NSData를 NSString으로 변환하여 사용할 수 있다.

그리고 모든 처리가 끝나면 release를 꼭 해주자. request도 alloc하긴 했지만 autorelease임을 명심하자.

[returnString release];

iPhone에서의 POST로 Multipart를 전송하는 방법은 Android보다 짧아보이고 쉽게도 보인다. 하지만 본인이 처음 도전한 것은 Obj-C로 Multipart를 전송하는 법이었고, 당시엔 어려웠다. 그래도 이 소스 덕분에 Android에서 고생하지 않을 수 있었다.

예제를 통해서 Multipart를 전송하는 법에 대해 알아보았다.

본인도 체계적으로 네크워크를 배운 것은 아니지만 검색을 통하여 많이 배운다.

여러분도 검색해서 복붙만 하지 마시고 소스를 이해해서 스스로의 것으로 만들려는 노력이 필요하다.

'iPhone Dev' 카테고리의 다른 글

날짜관련  (0) 2012.12.27
UIActivityIndicatorView 사용  (0) 2012.10.05
테이블뷰 헤더 폰트정보  (0) 2012.10.05
컴파일시 ARC적용 안되게 하기  (0) 2012.10.05
웹페이지 호출  (0) 2012.10.05
Posted by 떡공이
,