自己实现异步发送请求和图片

简介: 自己实现异步发送请求和图片

异步发送比同步发送请求有不阻塞主线程和支持多线程发送请求的好处。

异步发送请求可以抽象为标准的代理对象,具有使用方便,可扩充性强,只要你足够牛可以写出比第三方控件更牛的发送模块,由于是你自己写的,可以根据自己的意愿对请求的各种细节进行处理。这个异步发送请求处理模块也是对苹果代理具体实现的经典案例。

chttpsendAsynchronousRequest.h

#import <Foundation/Foundation.h>

@protocol chttpsendAsynchronousDelegate <NSObject>

@required
- (void)requestDidFinish:(NSString *)responseData responseType:(NSInteger)type;

@end


@interface chttpsendAsynchronousRequest : NSObject
@property (strong, nonatomic) id <chttpsendAsynchronousDelegate> pSelfView;
- (void)sendHttpRequest:(NSString*)sendString;
- (void)sendImageDataToServer:(UIImage *)image;
@end

chttpsendAsynchronousRequest.m

#import "chttpsendAsynchronousRequest.h"
#import "config.h"

@implementation chttpsendAsynchronousRequest
@synthesize pSelfView;
- (void)sendHttpRequest:(NSString*)sendString
{

    //这个是服务器的地址,暂时随便写地址,不然就把用户的服务器信息泄密了
    NSURL *serverNUSUrl = [NSURL URLWithString:@"http://120.139.148.144:8090/test/main.do"];


    NSLog(@"sendString %@",sendString);

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:serverNUSUrl
                                                           cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60];

    [request setHTTPMethod:@"POST"];

    [request setValue:@"text.html" forHTTPHeaderField:@"Content-Type"];

    NSString * sendData = sendString;
    NSData *postData = [sendData dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
    NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setHTTPBody:postData];
    [NSURLConnection
     sendAsynchronousRequest:request
     queue:[[NSOperationQueue alloc] init]
     completionHandler:^(NSURLResponse *response,
                         NSData *data,
                         NSError *error)
     {
         NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
         if ([data length] >0 && error == nil && [httpResponse statusCode] == 200)
         {
             NSString * recvStrData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
             if(nil != recvStrData)
             {
                 NSLog(@"recvStrData[%@]",recvStrData);

             }
             if (pSelfView && [pSelfView respondsToSelector:@selector(requestDidFinish:responseType:)]) {
                 [pSelfView requestDidFinish:recvStrData responseType:0];
             }

         }
         else if ([data length]  == 0 && error == nil && [httpResponse statusCode] == 200)
         {

             if (pSelfView && [pSelfView respondsToSelector:@selector(requestDidFinish:responseType:)]){
                 [pSelfView requestDidFinish:nil responseType:1];
             }

         }
         else
         {
             if (pSelfView && [pSelfView respondsToSelector:@selector(requestDidFinish:responseType:)]){
                 [pSelfView requestDidFinish:nil responseType:-1];
             }

         }
     }];

    return;
}

- (void)sendImageDataToServer:(UIImage *)image {
    //分界线的标识符
    NSString *TWITTERFON_FORM_BOUNDARY = @"AaB03x";
    NSString *urlString =  @"http://192.168.2.77:8080/GUT/IOSServer";
    NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]
                                                           cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
                                                       timeoutInterval:10];
    NSData *image2 = UIImagePNGRepresentation(image);
    NSMutableData *myRequestData=[NSMutableData data];
    [myRequestData appendData:image2];
    NSString *content=[[NSString alloc]initWithFormat:@"multipart/form-data; boundary=%@",TWITTERFON_FORM_BOUNDARY];
    [request setValue:content forHTTPHeaderField:@"Content-Type"];
    [request setValue:[NSString stringWithFormat:@"%d", [myRequestData length]] forHTTPHeaderField:@"Content-Length"];
    [request setHTTPBody:myRequestData];
    [request setHTTPMethod:@"POST"];
    //建立连接,设置代理
    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    if(conn){
        NSLog(@"连接成功");
    }

    NSHTTPURLResponse *urlResponese = nil;
    NSError *error = [[NSError alloc]init];
    NSData* resultData = [NSURLConnection sendSynchronousRequest:request   returningResponse:&urlResponese error:&error];
    NSString* result= [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
    if([urlResponese statusCode] >=200&&[urlResponese statusCode]<300){
        NSLog(@"返回结果=====%@",result);
    }


    //提示用户上传成功  需要判断返回的json
    NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"通知"
                                                   message:@"图片上传成功"
                                                  delegate:self
                                         cancelButtonTitle:@"Cancel"
                                         otherButtonTitles:nil, nil];
    [alert show];
    NSLog(@"%@",returnString);

}

@end

具体的应用。

发送请求部分:

- (void) searchNotificationMethodRequest
{
    @try {

    HUD = [[MBProgressHUD alloc] initWithView:self.view];
    [self.view addSubview:HUD];

    //如果设置此属性则当前的view置于后台
    HUD.dimBackground = NO;

    //设置对话框文字
    HUD.labelText = @"请稍等...";

    //显示对话框
    [HUD showAnimated:YES whileExecutingBlock:^{
        //对话框显示时需要执行的操作
        [self myProgressTask];
        //sleep(1);
    } completionBlock:^{
        //操作执行完后取消对话框
        [HUD removeFromSuperview];
        HUD = nil;
    }];

    chttpsendAsynchronousRequest *phttpsendAsynchronousRequest = [[chttpsendAsynchronousRequest alloc] init ];
    NSString *messageString = nil;
    NSString *sendString = nil;
    //3. 构造数据
    CHeadEncode *pHeadEncode = [[CHeadEncode alloc] init ];
    messageString = [pHeadEncode headEncode : strToken : @"0x000C" : @"" : @"" : nil];
    if((nil == messageString) || (nil == strVId))
    {
        taskFlag = YES;
        dispatch_async(dispatch_get_main_queue(), ^{
            //更新UI操作
            //.....
            [self hudWasHidden:HUD];
        });
        return;

    }
    sendString = [NSString stringWithFormat:@"%@,\"body\":{\"v_id\":\"%@\"}}", messageString, strVId];
    LogInfo(@"sendString = %@", sendString);
    //4. 发送数据
    phttpsendAsynchronousRequest.pSelfView = self;
    [phttpsendAsynchronousRequest sendHttpRequest:sendString];
    sendString = nil;

    }
    @catch (NSException *exception) {
        LogError(@"NSException : %@", exception);
    }
    @finally {

    }

}

请求响应代理函数实现:

- (void)requestDidFinish:(NSString *)responseData responseType:(NSInteger)type {
    if(nil == responseData)
    {
        LogInfo(@"responseData = nil; Type:%d", type);
    }
    else
    {

        LogInfo(@"responseData: %@  Type:%d",responseData,type);
    }


    if (type == 0) {
        if(!_setState)
        {
            [self analyzeMessage:responseData];
        }
        else
        {
            [self analyzeSettingMessage:responseData];
        }

    } else {
        [self failHandle:type];
    }
}
- (void)failHandle:(NSInteger) resultCode
{

    taskFlag = YES;
    dispatch_async(dispatch_get_main_queue(), ^{
        //更新UI操作
        //.....
        [self hudWasHidden:HUD];
    });
    if(1 == resultCode)
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            //更新UI操作
            //.....
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"警告" message:@"服务器异常!" delegate:self cancelButtonTitle:@"知道了" otherButtonTitles:nil];
            [alert show];
            [theLock unlock];
            //[self hudWasHidden:HUD];

            //[self switchTaskWayBillSearchViewController];
            //return;
        });

    }
    else
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            //更新UI操作
            //.....
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"警告" message:@"网络异常!" delegate:self cancelButtonTitle:@"知道了" otherButtonTitles:nil];
            [alert show];
            [theLock unlock];
            //[self hudWasHidden:HUD];

            //[self switchTaskWayBillSearchViewController];
            //return;
        });

    }


}

具体的对响应页面的处理部分:

- (void)analyzeMessage:(NSString *)recvData
{

    LogInfo(@"recvData[%@]",recvData);

    dispatch_async(dispatch_get_main_queue(), ^{
        //更新UI操作
        taskFlag = YES;
        [self hudWasHidden:HUD];
    });

    NSMutableDictionary *rootDic = [recvData JSONValue];


    NSDictionary *headDic = [rootDic objectForKey:@"head"];
    if(![self DecodeHeader:headDic])
    {
        [theLock unlock];
        return;
    }


    NSDictionary *bodDictionary = [rootDic objectForKey:@"body"];
    self.next_page = [bodDictionary objectForKey:@"next_page"];
    LogInfo(@"next_page : %@",self.next_page);


    NSMutableArray *bodyArr = [bodDictionary objectForKey:@"data_list"];
    NSDictionary *bodyDic = nil;
    NSUInteger  i = 0;
    for (i = 0; i < bodyArr.count; i++)
    {
        bodyDic = [bodyArr objectAtIndex:i];

        CWaringInfo *waringinfo = [[CWaringInfo alloc] init];
        NSString *feildStr = [bodyDic objectForKey:@"alarm_id"];
        if(nil == feildStr)
        {
            [theLock unlock];
            return;
        }
        else
        {

            [waringinfo setAlarm_id:feildStr];
        }
        LogInfo(@"waringinfo = [%@]", feildStr);
        feildStr = [bodyDic objectForKey:@"alarm_name"];
        if(nil == feildStr)
        {
            [theLock unlock];
            return;
        }
        else
        {
            [waringinfo setAlarm_name:feildStr];
        }
        LogInfo(@"waringinfo = [%@]", feildStr);
        feildStr = [bodyDic objectForKey:@"alarm_date"];
        if(nil == feildStr)
        {
            [theLock unlock];
            return;
        }
        else
        {
            [waringinfo setAlarm_date:feildStr];
        }
        LogInfo(@"waringinfo = [%@]", feildStr);
        feildStr = [bodyDic objectForKey:@"alarm_desc"];
        if(nil == feildStr)
        {
            [theLock unlock];
            return;
        }
        else
        {
            [waringinfo setAlarm_desc:feildStr];

        }
        LogInfo(@"waringinfo = [%@]", feildStr);

        [self.computers addObject:waringinfo];


    }



    LogInfo(@"OldTaskArray = [%@]", self.computers);
    dispatch_async(dispatch_get_main_queue(), ^{
        //更新UI操作
        //.....
        [self.tableView reloadData];
        [theLock unlock];
    });


}
目录
相关文章
|
缓存 JavaScript 前端开发
【axios】二次封装——避免重复发送请求
【axios】二次封装——避免重复发送请求
504 0
【axios】二次封装——避免重复发送请求
|
1月前
|
XML 前端开发 JavaScript
|
3月前
|
Python
8. 如何解决 Tornado 检测到了有事件(events)被发送到一个已经关闭的流(stream)。在 Tornado 中,一个流代表一个请求或响应的数据流。这个警告可能意味着在请求处理的过程中,
8. 如何解决 Tornado 检测到了有事件(events)被发送到一个已经关闭的流(stream)。在 Tornado 中,一个流代表一个请求或响应的数据流。这个警告可能意味着在请求处理的过程中,
|
6月前
|
JavaScript 前端开发 网络协议
前端JS发起的请求能暂停吗?
在讨论前端JS发起的请求是否能暂停时,需要明确两个概念:什么状态可以被认为是“暂停”?以及什么是JS发起的请求?
490 1
前端JS发起的请求能暂停吗?
|
7月前
发送同步请求模块
发送同步请求模块
41 1
|
7月前
|
XML JSON 前端开发
学习Ajax使用异步对象发送请求
Ajax,全称Asynchronous JavaScript and XML(异步JavaScript和XML),是一种用于创建更好、更快以及交互性更强的Web应用程序的技术。
75 3
|
7月前
|
缓存 安全
控制浏览器发送请求采用请求方式的详细介绍
本文讲述了HTTP请求的GET和POST两种主要方式。GET请求限制参数不超过4K,参数显示在地址栏并缓存资源;POST请求能携带任意数量参数,参数隐藏在请求体,不保存资源。GET常用于超链接和表单默认提交,POST适用于文件上传、登录验证和获取实时数据等场景,因安全考虑,部分网站仅接受GET请求。可通过表单的method属性设置请求方式,默认为GET。
129 0
|
7月前
|
存储 缓存 前端开发
如何实现设备组缓存的正确清除?——基于心跳请求和心跳响应的解决方案
如何实现设备组缓存的正确清除?——基于心跳请求和心跳响应的解决方案
83 0
|
应用服务中间件 测试技术 网络安全
服务器收不到支付宝notify_url异步回调请求的问题排查
服务器收不到支付宝notify_url异步回调请求的问题排查
283 0
axios发送请求几种方式
axios发送请求几种方式
179 0