|
iPhone - HTTP POST, avagy fájlok továbbítása szerverre
Előfordulhat, hogy fájlokat - leginkább képeket - kell továbbítani szerverre. Erre a legmegfelelőbb a HTTP protokoll POST metódusa, ám ez nem is annyira egyszerű annak, aki nem ismeri a POST metódus teljes működését. Ezen segít az itt közölt osztály forráskódja, illetve a felhasználás be mutatása. Segítségével könnyen és gyorsan megoldható a feladat.
Először hozzunk létre egy úgy fájlt, melynek őse az NSObject legyen, a neve legyen mondjuk Post. Nézzük, mi kerüljön a Post.m fájlba:
#import <Foundation/Foundation.h>
@interface Post : NSObject {
NSMutableData *receivedData, *body;
NSString *boundary, *contentType;
NSURL *url;
}
- (void)setURL:(NSString *)urlString;
- (void)addData:(NSString *)name value:(NSString *)value;
- (void)addPicture:(NSString *)name filename:(NSString *)filename data:(NSData *)data;
- (void)send;
@end
Lássuk a Post.m fájlt:
#import "Post.h"
#import "MyAppDelegate.h"
@implementation Post
- (id)init
{
self = [super init];
if (self) {
receivedData=[[NSMutableData alloc] init];
boundary = [[NSString alloc] initWithString:@"----1010101010"];
contentType = [[NSString alloc] initWithFormat:@"multipart/form-data; boundary=%@",boundary];
if (body!=nil) [body release];
body = [[NSMutableData alloc] init];
}
return self;
}
- (void)setURL:(NSString *)urlString {
url = [[NSURL alloc] initWithString:urlString];
}
- (void)addData:(NSString *)name value:(NSString *)value {
[body appendData:[[NSString stringWithFormat:@"--%@", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name="%@"", name] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[value dataUsingEncoding:NSUTF8StringEncoding]];
}
- (void)addPicture:(NSString *)name filename:(NSString *)filename data:(NSData *)data {
[body appendData:[[NSString stringWithFormat:@"--%@", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name="%@"; filename="%@"", name, filename] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Type: image/jpeg" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:data];
}
- (void)send {
[receivedData setLength:0];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request addValue:contentType forHTTPHeaderField: @"Content-Type"];
[body appendData:[[NSString stringWithFormat:@"--%@--",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
[request addValue:[NSString stringWithFormat:@"%d", body.length] forHTTPHeaderField: @"Content-Length"];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
NSLog(@"Response Recieved");
NSLog(@"Response Code: %i",[response statusCode]);
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
NSLog(@"%@", data);
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[connection release];
NSLog(@"Connection failed! Error - %@", [error localizedDescription]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
MyAppDelegate *appDelegate=(MyAppDelegate*)[[UIApplication sharedApplication] delegate];
[appDelegate sentToServer];
NSLog(@"%@", receivedData);
[connection release];
}
@end
Az init függvényben inicializáljuk az objektumot, beállítjuk az adatok elválasztásához szükséges boundary-t (ez egy tetszőleges string, az elején és a végén a - jeleknek viszont jelentősége van). A setURL függvényben tudjuk megadni annak a PHP, Java, vagy egyéb szerveroldali szkriptnek címét, ahova küldeni fogjuk az adatokat, képeket. Az addData függvénnyel az input mezők nevét és ertékét, míg az addPicture függvénnyel a képet tudjuk rögzíteni az objektumban. A képet nem UIImage-ként, hanem NSData-ként fogjuk átadni, az alább leírt módon. Az adatok elküldését a send függvénnyel tudjuk elindítani.
Az osztályban találhatóak delegált metódusok is, ezek a visszajelzést teszik lehetővé. Röviden a didReceiveResponse függvény akkor hívódik meg, mikor válaszol a szerver, innen lehet megtudni, milyen válaszkódot adott. Ha minden rendben megy, enenk értéke 200. A didReceiveData akkor hívódik meg, mikor egy adat érkezik, ennek annyi jelentősége van, hogy itt tudjuk összegyűjteni, ha több részletben érkezik a válasz. Ha a didFailWithError függvény fut, akkor baj van, valami nem működik. Legvégül elindul a connectionDidFinishLoading függvény, innen tudunk visszaszólni, hogy minden rendben, lehet eltüntetni a forgó-morgót :-), mehet tovább a program.
És akkor legvégül nézzük, hogyan lehet meghívni az egészet:
- (void)postToServer {
Post *post=[[Post alloc] init];
[post setURL:serverPath];
[post addData:@"title" value:title.text];
[post addData:@"message" value:message.text];
NSData *photoData = [NSData dataWithContentsOfFile:jpgPath];
[post addPicture:@"picture" filename:@"upload.jpg" data:photoData];
[post send];
[post release];
}
- (void)sentToServer {
// Itt lehet lezárni a folyamatot
}
A jpgPath a képfájl tényleges helye az iPhone fájlrendszerében. Ennek meghatározása tanfolyamunk témája, így erre nem térnék ki. Az addPicture függvény első paramétere a mezőnevet, a második a kép "eredeti" nevét, jelenti, a harmadik értelemszerűen a képadat.
Ha tetszett a cikk, lájkold, osszd meg Facebook-on és Twitteren, és akkor lesznek további hasznos tutorialok is! Ha van ötleted, miről írjunk, írd meg!
  Rusznyák Gábor
|