ios – 使用NSURLSession进行异步上传不起作用,但NSURLConnection同步

ios – 使用NSURLSession进行异步上传不起作用,但NSURLConnection同步,第1张

概述编辑: 我需要从iPhone异步上传文件到 Python服务器端进程.我想异步执行请求,以便在工作时显示繁忙的动画. 请求需要包含用户名,密码和文件作为“multipart / form-data”. 我可以使用NSURLConnection同步工作,代码如下所示:: -(void) uploadDatabase{Database *databasePath = [[Database allo 编辑:
我需要从iPhone异步上传文件到 Python服务器端进程.我想异步执行请求,以便在工作时显示繁忙的动画.

请求需要包含用户名,密码和文件作为“multipart / form-data”.

我可以使用NSURLConnection同步工作,代码如下所示::

-(voID) uploadDatabase{Database *databasePath = [[Database alloc] init];Nsstring *targetPath = [databasePath getPathToDatabaseInDirectory];NSData *dbData = [NSData dataWithContentsOffile:targetPath];Nsstring *url = @"http://mydomain.com/API/upload/";//Nsstring *username = [[NSUserDefaults standardUserDefaults] stringForKey:USERname];Nsstring *username = @"user";Nsstring *password = @"pass";NSMutableURLRequest *request = [self createRequestForUrl:url withUsername:username andPassword:password andData:dbData];NSURLResponse *response;NSError *error;NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];Nsstring *stringResult = [[Nsstring alloc] initWithData:result enCoding:NSUTF8StringEnCoding];NSLog(@"**server info %@",stringResult);}

//请求构建

-(NSMutableURLRequest*) createRequestForUrl: (Nsstring*)urlString withUsername:(Nsstring*)username andPassword:(Nsstring*)password andData:(NSData*)dbData    {NSURL *url = [NSURL URLWithString:urlString];NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60.0];[request sethttpMethod:@"POST"];Nsstring *boundary = @"BOUNDARY_STRING";Nsstring *ContentType = [Nsstring stringWithFormat:@"multipart/form-data; boundary=%@",boundary];[request addValue:ContentType forhttpheaderFIEld:@"Content-Type"];NSMutableData *body = [NSMutableData data];if(dbData != NulL){    //only send these methods when transferring data as well as username and password    [body appendData:[[Nsstring stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEnCoding:NSUTF8StringEnCoding]];    [body appendData:[[Nsstring stringWithFormat:@"Content-disposition: form-data; name=\"file\"; filename=\"dbfile\"\r\n"] dataUsingEnCoding:NSUTF8StringEnCoding]];    [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEnCoding:NSUTF8StringEnCoding]];    [body appendData:[NSData dataWithData:dbData]];}[body appendData:[[Nsstring stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEnCoding:NSUTF8StringEnCoding]];[body appendData:[[Nsstring stringWithFormat:@"Content-disposition: form-data; name=\"username\"\r\n\r\n%@",username] dataUsingEnCoding:NSUTF8StringEnCoding]];[body appendData:[[Nsstring stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEnCoding:NSUTF8StringEnCoding]];[body appendData:[[Nsstring stringWithFormat:@"Content-disposition: form-data; name=\"password\"\r\n\r\n%@",password] dataUsingEnCoding:NSUTF8StringEnCoding]];[body appendData:[[Nsstring stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEnCoding:NSUTF8StringEnCoding]];[request sethttpBody:body];return request;}

但是,当我尝试使用NSURLSession异步执行此 *** 作时,它似乎无法正常工作. NSURLSession的代码如下所示:

-(voID)uploadDatabase{    Database *databasePath = [[Database alloc] init];    Nsstring *targetPath = [databasePath getPathToDatabaseInDirectory];    NSURL *phonedbURL = [NSURL URLWithString:targetPath];    Nsstring *url = @"http://mydomain.com/API/upload/";    Nsstring *username = @"user";    Nsstring *password = @"pass";    NSMutableURLRequest *request = [self createRequestForUrl:url withUsername:username andPassword:password andData:NulL];NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];self.uploadSession = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue:Nil];NSLog(@"the url = %@",url);NSURLSessionUploadTask *uploadTask = [self.uploadSession uploadTaskWithRequest:request fromfile:phonedbURL];[uploadTask resume];}

我正在努力看到我做的不同,尽管看起来这应该有效.

是否正确使用NSURLSession进行异步请求?我是NSURLSession的新手,所以我必须为NSURLSession请求而不是NSURLConnection更改我的NSURLMutableRequest吗?

在此先感谢您的帮助!

解决方法 你是对的,如果你只想让你的请求异步,你应该退出sendSynchronousRequest.虽然我们曾经推荐过sendAsynchronousRequest,有效的iOS 9,NSURLConnection正式弃用,并且应该支持NSURLSession.

一旦开始使用NSURLSession,您可能会发现自己被它吸引了.例如,可以使用[NSURLSessionConfiguration backgroundSessionConfiguration:],然后在应用程序进入后台后上传进度. (你必须编写一些委托方法,所以为了简单起见,我已经在下面进行了一个简单的前台上传.)这只是你的业务需求的问题,抵消了新的NSURLSession功能与​​它所需的iOS 7限制.

顺便说一句,任何关于iOS / MacOS中的网络请求的对话可能都是不完整的,没有引用AFNetworking.它极大地简化了这些多部分请求的创建,并且绝对值得调查.他们也有NSURLSession支持(但我没有使用他们的会话包装器,所以不能说它).但AFNetworking毫无疑问值得您考虑.您可以享受基于委托的API的丰富功能(例如,进度更新,可取消请求, *** 作之间的依赖关系等),提供更好的控制,使用方便的方法(如sendSynchronousRequest),但不会拖过你的杂草委托方法本身.

无论如何,如果您真的对如何使用NSURLSession进行上传感兴趣,请参阅下文.

如果你想通过NSURLSession上传,那么思考就会略有转变,即将NSMutableURLRequest中的请求(及其标题)的配置与请求主体的创建(您现在在实例化时指定)分开NSURLSessionUploadTask).您现在指定为上载任务的一部分的请求正文可以是NSData,文件或流(我在下面使用NSData,因为我们正在构建一个多部分请求):

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];[request sethttpMethod:@"POST"];Nsstring *boundary = [self boundaryString];[request addValue:[Nsstring stringWithFormat:@"multipart/form-data; boundary=%@",boundary] forhttpheaderFIEld:@"Content-Type"];NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];NSData *fileData = [NSData dataWithContentsOffile:path];NSData *data = [self createBodyWithBoundary:boundary username:@"rob" password:@"password" data:fileData filename:[path lastPathComponent]];NSURLSessionUploadTask *task = [session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData *data,NSURLResponse *response,NSError *error) {    NSAssert(!error,@"%s: uploadTaskWithRequest error: %@",__FUNCTION__,error);    // parse and interpret the response `NSData` however is appropriate for your app}];[task resume];

并且发送的NSData的创建与您现有的代码非常相似:

- (NSData *) createBodyWithBoundary:(Nsstring *)boundary username:(Nsstring*)username password:(Nsstring*)password data:(NSData*)data filename:(Nsstring *)filename{    NSMutableData *body = [NSMutableData data];    if (data) {        //only send these methods when transferring data as well as username and password        [body appendData:[[Nsstring stringWithFormat:@"--%@\r\n",boundary] dataUsingEnCoding:NSUTF8StringEnCoding]];        [body appendData:[[Nsstring stringWithFormat:@"Content-disposition: form-data; name=\"file\"; filename=\"%@\"\r\n",filename] dataUsingEnCoding:NSUTF8StringEnCoding]];        [body appendData:[[Nsstring stringWithFormat:@"Content-Type: %@\r\n\r\n",[self mimeTypeForPath:filename]] dataUsingEnCoding:NSUTF8StringEnCoding]];        [body appendData:data];        [body appendData:[@"\r\n" dataUsingEnCoding:NSUTF8StringEnCoding]];    }    [body appendData:[[Nsstring stringWithFormat:@"--%@\r\n",boundary] dataUsingEnCoding:NSUTF8StringEnCoding]];    [body appendData:[[Nsstring stringWithFormat:@"Content-disposition: form-data; name=\"username\"\r\n\r\n%@\r\n",username] dataUsingEnCoding:NSUTF8StringEnCoding]];    [body appendData:[[Nsstring stringWithFormat:@"--%@\r\n",boundary] dataUsingEnCoding:NSUTF8StringEnCoding]];    [body appendData:[[Nsstring stringWithFormat:@"Content-disposition: form-data; name=\"password\"\r\n\r\n%@\r\n",password] dataUsingEnCoding:NSUTF8StringEnCoding]];    [body appendData:[[Nsstring stringWithFormat:@"--%@--\r\n",boundary] dataUsingEnCoding:NSUTF8StringEnCoding]];    return body;}

你硬编码边界和mime类型,这很好,但上面碰巧使用以下方法:

- (Nsstring *)boundaryString{    Nsstring *uuIDStr = [[NSUUID UUID] UUIDString];    // If you need to support iOS versions prior to 6,you can use    // Core Foundation UUID functions to generate boundary string    //    // adapted from http://developer.apple.com/library/ios/#samplecode/SimpleURLConnections    //    // Nsstring  *uuIDStr;    //    // CFUUIDRef uuID = CFUUIDCreate(NulL);    // assert(uuID != NulL);    //     // Nsstring  *uuIDStr = CFBrIDgingrelease(CFUUIDCreateString(NulL,uuID));    // assert(uuIDStr != NulL);    //     // CFRelease(uuID);    return [Nsstring stringWithFormat:@"Boundary-%@",uuIDStr];}- (Nsstring *)mimeTypeForPath:(Nsstring *)path{    // get a mime type for an extension using MobileCoreServices.framework    CFStringRef extension = (__brIDge CFStringRef)[path pathExtension];    CFStringRef UTI = UTTypeCreatePreferredIDentifIErForTag(kUTTagClassfilenameExtension,extension,NulL);    assert(UTI != NulL);    Nsstring *mimetype = CFBrIDgingrelease(UTTypecopyPreferredTagWithClass(UTI,kUTTagClassMIMEType));    assert(mimetype != NulL);    CFRelease(UTI);    return mimetype;}
总结

以上是内存溢出为你收集整理的ios – 使用NSURLSession进行异步上传不起作用,但NSURLConnection同步全部内容,希望文章能够帮你解决ios – 使用NSURLSession进行异步上传不起作用,但NSURLConnection同步所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/1102726.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-28
下一篇2022-05-28

发表评论

登录后才能评论

评论列表(0条)

    保存