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

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

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

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

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];
    });


}
目录
相关文章
|
Web App开发 缓存 JavaScript
如何处理页面关闭时发送HTTP请求?
在实际项目开发中,可能会遇到这样的业务问题:如何在用户离开或关闭页面时发送HTTP请求给服务端?可能有人会觉得页面都关闭了,还需要发送什么请求,完全没必要噻。但如果真有这样的业务需求落到自己的头上,那么我们应该如何来实现呢?
2241 0
如何处理页面关闭时发送HTTP请求?
|
14天前
|
XML 前端开发 JavaScript
|
Android开发
【OkHttp】OkHttp Get 和 Post 请求 ( 同步 Get 请求 | 异步 Get 请求 | 同步 Post 请求 | 异步 Post 请求 )(一)
【OkHttp】OkHttp Get 和 Post 请求 ( 同步 Get 请求 | 异步 Get 请求 | 同步 Post 请求 | 异步 Post 请求 )(一)
1084 0
|
Web App开发 JavaScript 前端开发
前端接收数据流实现图片预览效果--ajax 请求二进制流 图片 文件 XMLHttpRequest 请求并处理二进制流数据 之最佳实践
本文为转载文章 原文链接:https://www.cnblogs.com/cdemo/p/5225848.html 首先要谢谢这位大神的无私贡献!解决了我的问题也完美表达了我当时的心路历程 ajax 请求二进制流 图片 文件 XMLHttpRequest 请求并处理二进制流数据 之最佳实践 写在前面 :从提出需求到完美的解决问题,实现过程是曲折的。
8093 0
|
5月前
|
JavaScript 前端开发 网络协议
前端JS发起的请求能暂停吗?
在讨论前端JS发起的请求是否能暂停时,需要明确两个概念:什么状态可以被认为是“暂停”?以及什么是JS发起的请求?
485 1
前端JS发起的请求能暂停吗?
|
6月前
发送同步请求模块
发送同步请求模块
36 1
|
6月前
|
XML JSON 前端开发
学习Ajax使用异步对象发送请求
Ajax,全称Asynchronous JavaScript and XML(异步JavaScript和XML),是一种用于创建更好、更快以及交互性更强的Web应用程序的技术。
68 3
|
6月前
|
缓存 安全
控制浏览器发送请求采用请求方式的详细介绍
本文讲述了HTTP请求的GET和POST两种主要方式。GET请求限制参数不超过4K,参数显示在地址栏并缓存资源;POST请求能携带任意数量参数,参数隐藏在请求体,不保存资源。GET常用于超链接和表单默认提交,POST适用于文件上传、登录验证和获取实时数据等场景,因安全考虑,部分网站仅接受GET请求。可通过表单的method属性设置请求方式,默认为GET。
102 0
|
6月前
|
JSON 前端开发 JavaScript
关于我认识的请求方式
关于我认识的请求方式有三个
67 0
|
应用服务中间件 测试技术 网络安全
服务器收不到支付宝notify_url异步回调请求的问题排查
服务器收不到支付宝notify_url异步回调请求的问题排查
262 0