是否有清洁的方法来处理异步HTTP请求比Objective-C的代表团? [英] Are there cleaner methods to handling async http requests than delegation in Objective-C?

查看:133
本文介绍了是否有清洁的方法来处理异步HTTP请求比Objective-C的代表团?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要建一个iPhone应用程序,在很大程度上利用了Web服务我在PHP中写道。现在我有一个文件(API.h / API.m),有它呼吁通过NSURLConnection的我的web服务的PHP函数的方法。

I'm building an iPhone app that heavily leverages a web service I wrote in php. Right now I have a file (API.h/API.m) that has methods which call php functions on my web service through NSURLConnection.

样方法:

-(void) mediaAdd:(UIImage *)image withDelegate: (id<apiRequest>) delegate;
-(void) mediaGet:(NSString *)imageURL withDelegate: (id<apiRequest>) delegate;

这些方法是通过在应用程序(由MVC模式定义控制器)控制器调用,这些方法需要在控制器为代表。

These methods are called by controllers in the app (controllers defined by the MVC pattern), and the methods take in the controller as the delegate.

一旦在API.h / API.m调用方法的请求已经完成,在API.h / API.m的NSURLConnection的委托方法时,请求完成时调用,然后调用委托方法...

Once the request from the called method in API.h/API.m has finished, the NSURLConnection delegate method in API.h/API.m that is called when the request is finished, then calls the delegate method...

-(void) serverResponse:(NSDictionary *) response fromCall:(NSString *)call;

... ...这是调用API.h / API.m方法在控制器上执行的,当然。

...which is of course executed on the controller that is calling the method in API.h/API.m.

当一个控制器需要使多个API调用我的问题,或者说混乱出现。因为我只有单一的委托方法,我通过在serverResponse方法使用调用参数不同的呼叫进行区分。

My problem, or rather disorganization arises when a controller needs to make more than one API call. Because I only have the single delegate method, I differentiate between different calls by using the call parameter in the serverResponse method.

这里是serverResponse方法的一个实例的骨架:

Here's a skeleton of an instance of the serverResponse method:

//API Delegate
-(void)serverResponse:(NSDictionary *)response fromCall:(NSString *)call {
    bool local = false;
    NSString *callbackString;
    if (local) {
        callbackString = @"http://localhost/";
    } else {
        callbackString = @"http://secret.com/";
    }
    if ([call isEqualToString:[NSString stringWithFormat:@"%@user/add",callbackString]]) {
        //user/add was called
        if (![[response objectForKey:@"status"] isEqualToString:@"fail"]) {
            if ([[response objectForKey:@"status"] isEqualToString:@"fail"]) {
                if ([[response objectForKey:@"reason"] isEqualToString:@"udid already taken"]) {
                     //UDID taken
                }
            } else {

                //UDID not taken, we're good to go



            }

        } else {
            NSLog(@"fail");
        }
    } else if([call isEqualToString:[NSString stringWithFormat:@"%@moment/get",callbackString]]){
        //moment/get was the api call
    } else if([call isEqualToString:[NSString stringWithFormat:@"%@printPictures/printPic",callbackString]]){

        //printPictures/printPic was the api call
    } else {
        NSLog(@"wrong call");
    }



}

我的问题是,我应该继续前进,并采取制作委托方法为每个API调用的暴跌?还是我这个得太多了,居然有一个非常简单的处理这个方法。也许一个设计模式或结构?

My question is, should I go ahead and take the plunge of making a delegate method for each API call? Or am I overthinking this, and there is actually a really simple method of handling this. Perhaps a design pattern or structure?

感谢您!
迈克 -

Thank you! - Mike

推荐答案

我通过与回调块单独的下载类做这种事情。控制器创建该类的一个实例,并且接收在回调的结果,在此之后,下载的类被释放。每次调用您需要创建自己的下载器类的实例,所以你并不需要跟踪哪些响应去与的呼叫。

I do this kind of thing by having a separate download class with a callback block. The controller creates an instance of the class, and receives the result in the callback, after which, the download class is deallocated. Each call you need to make creates its own instance of the Downloader class, so you don't need to keep track of which response goes with which call.

    Downloader *dl = [Downloader new];
    NSURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"...."]] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10];

    [dl downloadWithRequest:(NSURLRequest *) request completion:^(NSData *data, NSError *error) {
        if (!error ) {
            // do whatever you need to do with the raw data here
            NSLog(@"got the data");
        }else{
            NSLog(@"%@",error);
        }
    }];

下面是我实现的下载类。

Here is how I implemented the Downloader class.

typedef void(^compBlock)(NSData *data, NSError *error);

@interface Downloader : NSObject <NSURLConnectionDataDelegate>

-(void)downloadWithRequest:(NSURLRequest *) request completion:(compBlock) completion;

@end

实现文件,

@interface Downloader()
@property (copy,nonatomic) compBlock completionHandler;
@property (strong,nonatomic) NSMutableData *receivedData;
@end

@implementation Downloader

-(void)downloadWithRequest:(NSURLRequest *) request completion:(compBlock)completion {
    NSURLConnection *con = [NSURLConnection connectionWithRequest:request delegate:self];
    if (con) {
        self.receivedData = [NSMutableData new];
        self.completionHandler = completion;
    }
}


-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    self.receivedData.length = 0;
}



-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.receivedData appendData:data];
}



-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    self.completionHandler(nil, error);
}



-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
    self.completionHandler(self.receivedData, nil);
}

这篇关于是否有清洁的方法来处理异步HTTP请求比Objective-C的代表团?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆