NSMutableURLRequest 在使用 NSURLSession 时发送 2 次

Posted

技术标签:

【中文标题】NSMutableURLRequest 在使用 NSURLSession 时发送 2 次【英文标题】:NSMutableURLRequest sending 2 times while using NSURLSession 【发布时间】:2016-07-19 05:09:17 【问题描述】:

我正在使用NSMutableURLRequest 在我使用时工作正常

- (void)postAsynchronousOnQueue:(NSOperationQueue*)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))completionHandler 
    NSURLRequest* request = [self createPostRequest];
    [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:completionHandler];

-(NSURLRequest*)createPostRequest 
        NSMutableURLRequest* request = [[HttpRequest requestWithRelativePath:@"/photo"] toNSMutableURLRequest];
             [request setHTTPMethod:@"POST"];
             [request setHTTPBody:[self encodeParamsForUpload]];
             return request;  

但问题是当我的应用程序处于后台模式时,它将无法运行。

这是我的HttpRequest 类方法:

+(id)requestWithRelativePath:(NSString*)docpath 
    return [[HttpRequest alloc] initWithRelativePath:docpath server:server username:email password:password];
  
-(id)initWithRelativePath:(NSString*)docpath server:(NSString*)server username:(NSString*)username password:(NSString*)password 
    if (self = [super init]) 
        docpath = [docpath stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
        _request = [self createRequestWithDocPath:docpath server:server username:username password:password];
    
    return self;


- (NSMutableURLRequest*)createRequestWithDocPath:(NSString*)docpath server:(NSString*)server username:(NSString*)username password:(NSString*)password 
    NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@%@", server, docpath]];
    NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL:url];
    [request setTimeoutInterval:120.0];
    if ((username != nil) && (password != nil))
        NSString *authStr = [NSString stringWithFormat:@"%@:%@", username, password];
        NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
        NSString *authValue = [NSString stringWithFormat:@"Basic %@", [self base64Encoding:authData]];
        [request setValue:authValue forHTTPHeaderField:@"Authorization"];
    
    return request;

从堆栈溢出,我发现NSURLSession 在后台进行 API 调用。所以我使用了NSURLSession。这是我所做的更新代码:

- (void)postAsynchronousOnQueue:(NSOperationQueue*)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))completionHandler 
    NSURLRequest* request = [self createPostRequest];
    [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:completionHandler];

-(NSURLRequest*)createPostRequest 
    NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration ephemeralSessionConfiguration];
    NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: [NSOperationQueue mainQueue]];

    NSMutableURLRequest* request = [[HttpRequest requestWithRelativePath:@"/photo"] toNSMutableURLRequest];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:[self encodeParamsForUpload]];
    //Create task
    NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) 
        //Handle your response here
        [[NSURLSession sharedSession]invalidateAndCancel];
    ];

    [dataTask resume];
    return request; 

但是,当我使用NSURLSession 时,请求发送了两次,我已经在NSMutableURLRequestline 中放置了断点,但它只调用了一次。

请帮我解决问题。

【问题讨论】:

不相关,但我会避免为每个请求创建一个新的NSURLSession。我会创建一次并为每个请求重用它。或者只使用sharedSession。我还将删除 NSURLSession 的失效,假设您以后可能会再次使用它。 【参考方案1】:

您的createPostRequest 正在创建一个请求并通过NSURLSession 提交它。但它也返回NSURLRequestpostAsynchronousOnQueue 继续提交它,这次是通过已弃用的NSURLConnection

删除NSURLConnection 代码并仅依靠NSURLSession 发出请求。


例如:

- (void)postAsynchronousOnQueue:(NSOperationQueue*)queue completionHandler:(void (^)(NSData *, NSURLResponse*, NSError*))completionHandler 
    NSURLSession *defaultSession = [NSURLSession sharedSession];

    NSMutableURLRequest* request = [[HttpRequest requestWithRelativePath:@"/photo"] toNSMutableURLRequest];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:[self encodeParamsForUpload]];

    NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) 
        //Handle your response here
        [queue addOperationWithBlock:^
            completionHandler(data, response, error);
        ];
    ];

    [dataTask resume]; 

【讨论】:

以上是关于NSMutableURLRequest 在使用 NSURLSession 时发送 2 次的主要内容,如果未能解决你的问题,请参考以下文章

使用 NSMutableURLRequest 请求

如何在注销期间取消所有 NSMutableURLRequest?

在 iOS 中使用“Body Requests”发送 NSMutableURLRequest 请求

如何使用 AFNetworking 向现有 NSMutableURLRequest 添加参数?

POST 请求未考虑 NSMutableURLRequest 超时间隔

NSMutableURLRequest 发送部分帖子正文