IOS / Objective C : Gérer les requêtes REST

avril 6th, 2012 Posted in Développement

Voici un exemple de classe permettant d’envoyer des requêtes pour l’architecture REST vers un serveur

Les requêtes REST utilisent le protocole HTTP pour le transport des données

restRequest.h

#import <Foundation/Foundation.h>

@interface restRequest : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate> {
SEL callback; // Selecteur vers la fonction de retour
id delegate; // objet cible pour l'appel de la fonction de retour
int status; // code HTTP
bool done; // true si la requête est terminée

NSMutableString *method;
NSMutableString *url;
NSMutableString *payload;

NSMutableURLRequest *request;
NSURLConnection *connection;
NSMutableData *dta;
NSMutableString *result;
}

@property (nonatomic,retain) NSMutableData *dta;

@property (nonatomic,retain) NSMutableString *method;
@property (nonatomic,retain) NSMutableString *url;
@property (nonatomic,retain) NSMutableString *payload;

@property (nonatomic,retain) NSMutableURLRequest *request;
@property (nonatomic,retain) NSURLConnection *connection;

@property (nonatomic) SEL callback;
@property (nonatomic,assign) id delegate;

@property (nonatomic) int status;
@property (nonatomic) bool done;
@property (nonatomic,retain) NSMutableString *result;

-(id)initWithCallback:(SEL)cal andDelegate:(id)dl;
-(void)start;
-(void)cancel;
@end

restRequest.m

#import "restRequest.h"

@implementation restRequest

@synthesize callback;
@synthesize delegate;

@synthesize url;
@synthesize method;
@synthesize payload;

@synthesize connection;
@synthesize request;
@synthesize dta;
@synthesize status;
@synthesize result;
@synthesize done;

-(id)initWithCallback:(SEL)cal andDelegate:(id)dl {

    self = [super init];
    if(self) {
        callback = cal; // Selecteur vers la fonction de retour
        delegate = [dl retain]; // objet cible de la fonction de retour
        status = -1; // code de retour HTTP
        done = FALSE; // indique si la requête est terminée

        dta = [[NSMutableData alloc] init]; // buffer
        url = [[NSMutableString alloc] init]; // url appelée
        method = [[NSMutableString alloc] initWithString:@"GET"]; // méthode HTTP : GET / POST / PUT, ...
        payload = [[NSMutableString alloc] init]; // contenu de la requete (Body)

        result = [[NSMutableString alloc] init]; // résultat de la requête
    }

    return self;

}
-(void)dealloc {

    [self cancel];

    done = TRUE;

    delegate = nil;
    callback = nil;

    [dta release];
    [url release];
    [method release];
    [payload release];
    [result release];

    if(request){
        [request release];
        request = nil;
    }

    [super dealloc];
}
-(void)start {

    status = 0;

    [dta setLength:0];

        [result setString:@""];
        NSString *full = [NSString stringWithFormat:@"http://%@/%@",@"http://www.url-de-base.com/",url];
        NSURL *myurl = [NSURL URLWithString:full];

        if(request){
            [request release];
            request = nil;
        }

        request = [[NSMutableURLRequest alloc] initWithURL:myurl];
        [request setHTTPMethod:method];
        if([payload length] > 0) [request setHTTPBody:[payload dataUsingEncoding:NSUTF8StringEncoding]];
        //[request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"]; // spécifie le format du contenu de la requête
        [request setTimeoutInterval:10];

        connection = [NSURLConnection connectionWithRequest:request delegate:self];
      [connection start];

}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [dta appendData:data];
}
-(void)connection:(NSURLConnection *)sconnection didFailWithError:(NSError *)error {
    NSLog(@"Error restRequest %@",[error localizedDescription]);
    [dta setLength:0];

    status = -2;

    if(delegate && [delegate respondsToSelector:callback]) [delegate performSelector:callback withObject:self];

    connection = nil;
    delegate = nil;
    callback = nil;

    done = TRUE;
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    if([response respondsToSelector:@selector(statusCode)]){
        status = [(NSURLResponseInternal *)response statusCode];
    }
}
-(void)connectionDidFinishLoading:(NSURLConnection *)sconnection {

    NSMutableString *res = [[NSMutableString alloc] initWithData:dta encoding:NSUTF8StringEncoding];
    [result setString:res];

    if(delegate && [delegate respondsToSelector:callback]){
        [delegate performSelector:callback withObject:self];
        [delegate release];
    }

    connection = nil;
    delegate = nil;
    callback = nil;
    done = TRUE;

    [res release];
}
-(void)cancel {
    if(connection){
        [connection cancel];
        connection = nil;
    }

    if(request){
        [request release];
        request = nil;
    }

    delegate = nil;
    callback = nil;
    done = TRUE;
}

@end

Pour l’utiliser :

-(void)start_request {

    restRequest *rest = [[restRequest alloc] initWithCallback:@selector(register_response:) andDelegate:self];

    [[(restRequest *)rest url] setString:@"appel/fonction.php"];
    [[(restRequest *)rest method] setString:@"PUT"];
    [[(restRequest *)rest payload] setString:@"contenu xml, json, ..."];

    [(restRequest *)rest start];

}
-(void)register_response:(restRequest *)res {

    if (res.status == 204) {
        // success
        NSString *resultat = res.result;
    }
    else if(res.status == 404){
        // document introuvable ...
    }
    else if(res.status == 500){
        // erreur interne
    }
    else if(res.status == -2){
        // impossible d'établir la connection, probablement un problème de réseau
    }

}

 

Bookmark and Share

Tags: , , , ,



No Comments Yet

You can be the first to comment!

Leave a comment