2012-08-26 43 views
1

我正在使用AFNetworking将图像和几个参数一起上传到PHP脚本(使用CodeIgniter构建),该脚本将接收图像,将文件名和参数放入数据库并移动图像到永久的位置。AFNetworking上传图像间歇性地工作

这里的对象 - 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('[email protected]', '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-Code中得到的错误信息:

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似乎允许不同大小的图像很好...但大或小,它可能只会在第二次尝试。

的思考?

+0

您很可能犯了一个错误 - 但是,如果没有看到代码,任何人都能够帮助您? – vikingosegundo

+0

相关问题:http://stackoverflow.com/questions/4359531/nsmutableurlrequest-and-request-body-stream-exhausted-error – Felix

+0

这是发生在模拟器还是只在设备上?设备上是否有足够的磁盘空间? setUploadProgressBlock中的代码是否正在执行? – Felix

回答

3

我正在使用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]; 
+0

我真的希望这会工作。这正是你如何使用它?我的构建失败的这个错误:“没有可见的@接口的'NSData'声明选择器'base64EncodeString'” – d2burke

+1

https://github.com/m1entus/WCMientus/tree/master/WCMientus/External/Base64 - 不要忘记添加-fno-objc-arc – mientus

+0

而你必须在服务器上解码base64:http://php.net/manual/en/function.base64-decode.php – mientus

0

前段时间我有类似的错误。这是由于“Content-Length”http头部的值与实际身体大小之间的不匹配造成的。这个错误很微妙。发生这种情况是因为我使用字符串长度作为内容大小,并且当字符串在UTF-8编码中有双字节字符时,这些字符串长度为1,但是对于帖子主体大小,则为2。检查您的POST正文大小v/s“内容长度”。

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

+0

我现在要试试这个!感谢Felz。 – d2burke

+0

当我在这上面...有没有办法隐式设置内容长度? – d2burke

+0

内容长度由AFNetworking设置,它应该是正确的!我已阅读AFNetworking代码... – Felix

0

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

你可以做[[AFHTTPRequestOperation alloc] initWithRequest:...],然后用直属性存取器(operation.completionBlock =^{...})或-setCompletionBlockWithSuccess:failure:来设置completionBlock。请记住,请求完成下载后,完成块会执行。

至于multipart表单块,-appendWithFileData:mimeType:name也被删除了一会儿。你想要的方法是-appendPartWithFileData:name:fileName:mimeType :.

做出这两个改变,一切都应该工作。

+0

appendPartWithFileData:name:fileName:mimeType:这是上面列出的确切方法,否?我不确定你的建议是什么改变:( – d2burke