AF网络上传图像间歇性工作


AFNetworking upload image working intermittently

我正在使用AFNetworking将图像和一些参数上传到PHP脚本(使用CodeIgniter构建),该脚本将接收图像,将文件名和参数放入数据库,并将图像移动到永久位置。

这是Obj-C:

NSURL *url = [NSURL URLWithString:@"http://my_api_endpoint"];
NSData *imageToUpload = UIImageJPEGRepresentation(_mainMedia, .25f);
NSDictionary *params = [[NSDictionary alloc]initWithObjectsAndKeys:
                        _topicText.text,@"Topic",
                        @"1",@"Category",
                        @"1",@"Creator",
                        nil];
AFHTTPClient *client= [AFHTTPClient clientWithBaseURL:url];
NSString *timeStamp = [NSString stringWithFormat:@"%0.0f.jpg", [[NSDate date] timeIntervalSince1970]];
NSMutableURLRequest *request = [client multipartFormRequestWithMethod:@"POST" path:@"apidebate/debates" parameters:params constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
    [formData appendPartWithFileData: imageToUpload name:@"MainMedia" fileName:timeStamp mimeType:@"image/jpeg"];
}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSString *response = [operation responseString];
    NSLog(@"response: [%@]",response);
    [self dismissViewControllerAnimated:YES completion:nil];
    [self.delegate createTopicViewControllerDidCreate:self];
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
    if([operation.response statusCode] == 403){
        NSLog(@"Upload Failed");
        return;
    }
    NSLog(@"error: %@", [operation error]);
    [self dismissViewControllerAnimated:YES completion:nil];
    [self.delegate createTopicViewControllerDidCreate:self];
}];
[operation setUploadProgressBlock:^(NSInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
    NSLog(@"Sent %lld of %lld bytes", totalBytesWritten, totalBytesExpectedToWrite);
    float width = totalBytesWritten / totalBytesExpectedToWrite;
}];
[operation start];

这是PHP:

//CONTROLLER FROM API
function debates_post()
{
mail('myemailaddress@gmail.com', 'Test', 'Posted');
$tmp_dir = "images/posted/";
if(isset($_FILES['MainMedia'])){
    $SaniFileName = preg_replace('/[^a-zA-Z0-9-_'.]/','', basename($_FILES['MainMedia']['name']));
    $file = $tmp_dir . $SaniFileName;
    move_uploaded_file($_FILES['MainMedia']['tmp_name'], $file);
}
else
    $SaniFileName = NULL;
$data = array('Topic'=>$this->post('Topic'), 'MainMedia'=>$this->post('MainMedia'), 'Category'=>$this->post('Category'), 'Creator'=>$this->post('Creator'));
$insert = $this->debate->post_debate($this->post('Topic'), $SaniFileName, $this->post('Category'), $this->post('Creator'));
if($insert){
    $message = $this->db->insert_id();
}
else{
    $message = 'Insert failed';
}
$this->response($message, 200);
}
//MODEL
function post_debate($Topic=NULL, $MainMedia='', $Category=NULL, $Creator=NULL){
$MainMedia = ($MainMedia)?$MainMedia:'';
$data = array(
                'Topic' => $Topic,
                'MainMedia' => $MainMedia,
                'Category' => $Category,
                'Creator' => $Creator,
                'Created' => date('Y-m-d h:i:s')
            );
return $this->db->insert('debate_table', $data);
}

我目前的问题是,从iOS上传的操作很少完成,而且没有完成的模式。我可以添加大的或小的照片,或者根本不添加照片,只需参数,它可以在20%的时间内工作。当它失败时,这是我在X代码中得到的错误消息:

2012-08-26 01:52:10.698 DebateIt[24215:907] error: Error Domain=NSURLErrorDomain 
Code=-1021 "request body stream exhausted" UserInfo=0x1dd7a0d0 
{NSErrorFailingURLStringKey=http://my_api_url, 
NSErrorFailingURLKey=http://my_api_url,
NSLocalizedDescription=request body stream exhausted, 
NSUnderlyingError=0x1e8535a0 "request body stream exhausted"}

这到底是什么?

我有一个基本的HTML表单,我将相同的图像发布到相同的端点,它每次都适用于任何大小的图像。iOS似乎允许不同大小的图像。。。但无论大小,它可能只会在第二次尝试时起作用。

想法?

我也在使用AFNetworking上传图像,我对此没有任何问题,可能是因为我使用base64对图像数据进行编码?

NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                               token, @"token",
                               [UIImageJPEGRepresentation(image, 0.8) base64EncodedString],@"photo",
                               nil];
NSMutableURLRequest *request = [self.httpClient requestWithMethod:@"POST"
                                                             path:@"/user/upload/photo.json"
                                                       parameters:params];

我不久前也遇到过类似的错误。这是由于"Content-Length"http标头的值与实际正文大小不匹配造成的。这个错误很微妙。发生这种情况是因为我使用字符串长度作为内容大小,当字符串在UTF-8编码中具有双字节字符时,这些字符的长度为字符串长度的1,但为文章正文大小的2。检查POST正文大小v/s"内容长度"。

我用在模拟器中运行应用程序的网络嗅探来调试这个奇怪的网络错误。我喜欢HTTPScoop。

首先,确保下载了最新版本的AFNetworking。

您可以执行[[AFHTTPRequestOperation alloc]initWithRequest:…]然后使用直接属性访问器(operation.completionBlock=^{…})或-setCompletionBlockWithSuccess:failure:设置completionBlock。请记住,完成块在请求完成下载后执行。

至于多部分表单块,-appendWithFileData:mimeType:name不久前也被删除了。您想要的方法是-appendPartWithFileData:name:fileName:mimeType:。

做出这两个改变,一切都会好起来的。