网络:NSURLSession 上传文件和代理的选择

本文介绍了一个iOS应用如何通过NSURLSession上传文件的过程。具体包括定义上传边界、构造上传请求、准备文件数据、实现上传任务及进度反馈等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#import "ViewController.h"
#define CZBoundary @"itcast"
// NSURLSessionDataDelegate 接收服务器返回的数据
// NSURLSessionTaskDelegate  -> NSURLSessionDelegate 上传进度以及HTTPS相当的代理
// NSURLSessionDownloadDaskDelegate 下载进度
@interface ViewController ()<NSURLSessionTaskDelegate,NSURLSessionDataDelegate>
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
@property (nonatomic, strong) NSURLSession *session; // 自定义会话
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    // NSURL
    NSURL *url = [NSURL URLWithString:@"http://localhost/post/upload.php"];

    // 创建请求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    // http请求方法使用POST
    [request setHTTPMethod:@"POST"];
    // 告诉服务器我是上传二进制数据
    [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",CZBoundary] forHTTPHeaderField:@"Content-Type"];

    // 图片路径
    NSString *path = [[NSBundle mainBundle] pathForResource:@"01.mp4" ofType:nil];

    // 图片数据
    NSData *imageData = [NSData dataWithContentsOfFile:path];

    // 拼接好的二进制数据
    NSData *uploadData = [self dataWithFileData:imageData fieldName:@"userfile" fileName:@"abc.mp4"];

    // 不使用block让代理返回进度
    [[self.session uploadTaskWithRequest:request fromData:uploadData]resume];
}

// 上传进度
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend {
    CGFloat progress = (CGFloat)totalBytesSent / totalBytesExpectedToSend;
    NSLog(@"%f",progress);
    // 回到主线程刷新UI
    dispatch_async(dispatch_get_main_queue(),^{
        self.progressView.progress = progress;
    });
}

// 接收到数据
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
    didReceiveData:(NSData *)data {
    NSLog(@"接收到数据%zd",data.length);//{}
}

// 完成了
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    NSLog(@"完成了");
}

- (void)uploadData {
    // NSURL
    NSURL *url = [NSURL URLWithString:@"http://localhost/post/upload.php"];

    // 创建请求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    // http请求方法使用POST
    [request setHTTPMethod:@"POST"];
    // 告诉服务器我是上传二进制数据
    [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",CZBoundary] forHTTPHeaderField:@"Content-Type"];

    // 图片路径
    NSString *path = [[NSBundle mainBundle] pathForResource:@"image.png" ofType:nil];

    // 图片数据
    NSData *imageData = [NSData dataWithContentsOfFile:path];

    // 拼接好的二进制数据
    NSData *uploadData = [self dataWithFileData:imageData fieldName:@"userfile" fileName:@"abc.png"];

    [[[NSURLSession sharedSession] uploadTaskWithRequest:request fromData:uploadData completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSLog(@"%@ -- %@",response,[NSJSONSerialization JSONObjectWithData:data options:0 error:NULL]);
    }] resume];
}
/**
 返回上传需要的二进制数据
 1. 文件的数据
 2. 后台给的字段名
 3. 上传的文件名
 */
- (NSData *)dataWithFileData:(NSData *)fileData fieldName:(NSString *)fieldName fileName:(NSString *)fileName {
    // 可变的二进制数据
    NSMutableData *dataM = [NSMutableData data];
    // 可变字符串用来拼接数据
    NSMutableString *strM = [NSMutableString stringWithFormat:@"--%@\r\n",CZBoundary];

    [strM appendFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\" \r\n",fieldName,fileName];

    // application/octet-stream 代表上传所有的二进制格式都支持
    [strM appendString:@"Content-Type: application/octet-stream \r\n\r\n"];

    //    NSLog(@"%@",strM);
    // 把前面一部份数据先拼接
    [dataM appendData:[strM dataUsingEncoding:NSUTF8StringEncoding]];

    // 拼接文件的二进制数据
    [dataM appendData:fileData];

    // 清空可变字符串之后,再设置内容为\r\n
    [strM setString:@"\r\n"];

    [strM appendFormat:@"--%@--",CZBoundary];

    // 把最后一部份加到二进制数据中
    [dataM appendData:[strM dataUsingEncoding:NSUTF8StringEncoding]];
    //    NSLog(@"%@",strM);
    return dataM.copy;
}

- (NSURLSession *)session {
    if (_session == nil) {
        _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
    }
    return _session;
}

@end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值