异步发布请求objective-c IOS后返回解析对象

时间:2013-05-07 16:42:55

标签: ios objective-c asynchronous delegates request

我试图从JSON响应中获取解析对象并在方法中使用,当我这样做时,我可以在此方法之后使用parsedObject [self.delegate requestJSONFinishedWithParsedObject:parsedObject];我使用,但现在我想要我想要的解析对象。我的意思是调用一个方法并在返回时使用该对象。

这样的事情:

NSDictionary * parsedObject = [self.delegate responseJsonDictionary]; 在我需要它的类中使用它。

我的问题是我有一个@property (strong, nonatomic) NSMutableArray *projectsArray;,我希望在使用它之前完全填充此属性。我正在创建一个包含JSON项目的动态菜单,但是当JSON中的数据在self.projectsArray中时,我的菜单已经创建,并且json的对象没有出现。

我正在使用此幻灯片菜单:https://github.com/andrewroycarter/SlideViewController

我使用这个类来管理所有请求,它完美无缺。

RequestJSON.m

-(void) requestWithURL:(NSDictionary *)jsonDictionary :(NSString*)myURL :(NSString *)method
{


    NSURL *thisURL = [NSURL URLWithString:myURL];


    NSString *__jsonString;
    NSData *__jsonData;
    if([NSJSONSerialization isValidJSONObject:jsonDictionary])
    {
        __jsonData = [NSJSONSerialization dataWithJSONObject:jsonDictionary options:0 error:nil];
        __jsonString = [[NSString alloc]initWithData:__jsonData encoding:NSUTF8StringEncoding];
    }



    // Be sure to properly escape your url string.
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:thisURL];
    [request setHTTPMethod:method];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request addValue:@"Carlos" forHTTPHeaderField:@"User"];

    if([method isEqual: @"POST"]){
    [request setValue:[NSString stringWithFormat:@"%d", [__jsonData length]] forHTTPHeaderField:@"Content-Length"];
        [request setHTTPBody: __jsonData];

    }
    NSLog(@"llega= asdasdasd %@, %@, %@",method,jsonDictionary,myURL);

    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];


}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{

    //INicializo variable NSMutableData
    self.myConnectionData= [NSMutableData data];


    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
    NSDictionary *myResponse = [[NSDictionary alloc] init];
    myResponse=[httpResponse allHeaderFields];
    statusCode = [httpResponse statusCode];

}


- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [self.myConnectionData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    [self.delegate requestJSONFailed];
}

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

    NSError *thisError;


    NSDictionary *parsedObject = [NSJSONSerialization JSONObjectWithData:myConnectionData options:NSJSONReadingMutableContainers|NSJSONReadingAllowFragments error:&thisError];

    [self.delegate requestJSONFinishedWithParsedObject:parsedObject];
}

@end

RequestJSON.h

@protocol RequestJSONDelegate;

@interface RequestJSON : NSObject
{
    NSInteger statusCode;

}

@property (nonatomic,assign) id <RequestJSONDelegate> delegate;
@property (nonatomic, strong) NSMutableData *myConnectionData;

-(void) requestWithURL:(NSDictionary *) params:(NSString*)myURL :(NSString *)method;
-(void) requestForLogin:(NSString*)myURL :(NSString*)method :(NSString*)pass;

@end


@protocol RequestJSONDelegate

-(void) requestJSONFinishedWithParsedObject:(NSDictionary*)parsedObject;

-(void) requestJSONFailed;

@end

在我想要获取此数据的其他类中,我使用此方法

-(void) requestJSONFinishedWithParsedObject:(NSDictionary *)parsedObject{

    NSArray  *projectsObjectArray = [parsedObject objectForKey:@"projects"];
}

-(void) requestJSONFailed{}

为了启动请求,我在我的主类中使用它。

example.m

 RequestJSON *requestJSON = [ [RequestJSON alloc] init];
    [requestJSON requestWithURL:(NSDictionary *) params:url :method];
    [requestJSON setDelegate:self];

谢谢

1 个答案:

答案 0 :(得分:0)

您的请求是异步的,因此您应该处理菜单内容尚未就绪的情况,如果数据尚未就绪并显示错误,则应显示一些加载UI,如活动指示符,例如使用alertView ,如果请求失败......

所以当你在viewDidLoad或viewWillAppear中创建你的UIViewController,或者你的应用程序哪里更好时你应该检查你是否已经有数据要显示,如果没有显示你的加载UI(我希望你使用某种缓存)而不是一直要求这些数据)

实施您的协议

如果你成功了

- (void)requestJSONFinishedWithParsedObject:(NSDictionary *)parsedObject {

    //remove the loading UI
    [self removeLoadingView]; // your custom method to remove the loading UI

    // populate your data source and reload the content
    self.projectsArray = [parsedObject objectForKey:@"projects"];

    // this in case you are using a tableview for your menu
    [self.tableView reloadData];
}

如果失败

- (void)requestJSONFailed {

    //remove the loading UI
    [self removeLoadingView]; // your custom method to remove the loading UI

    // show an error feedback like an alertview
    [self showError]; // your custom method to display errors
}

这可能是一种处理加载的方法,我不建议您使用同步请求,这将停止您的UI,直到请求结束,用户体验非常糟糕