1

私はAFNetworkingを使用して、いくつかのパラメーターとともに画像をPHPスクリプト(CodeIgniterで構築)にアップロードします。PHPスクリプトは、画像を受け取り、ファイル名とパラメーターをデータベースに配置し、画像を永続的な場所に移動します。

これが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-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では、さまざまなサイズの画像を問題なく使用できるようですが、大小を問わず、おそらく2回目の試行でのみ機能します。

考え?

4

3 に答える 3

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];
于 2012-09-01T18:44:22.613 に答える
0

しばらく前に同様のエラーが発生しました。これは、「Content-Length」httpヘッダーの値と実際の本文のサイズが一致しないことが原因でした。エラーは微妙でした。これは、コンテンツサイズとして文字列の長さを使用していて、UTF-8エンコーディングで文字列に2バイト文字が含まれている場合に、文字列の長さは1、ポストの本文のサイズは2になるために発生しました。POST本体のサイズv/s「Content-Length」を確認してください。

シミュレーターでアプリを実行しているネットワークをスニッフィングして、この奇妙なネットワークエラーをデバッグします。HTTPScoopが好きです。

于 2012-08-28T14:52:58.483 に答える
0

まず、AFNetworkingの最新バージョンがダウンロードされていることを確認します。

[[AFHTTPRequestOperation alloc] initWithRequest:...]を実行してから、ストレートプロパティアクセサー(operation.completionBlock = ^ {...})または-setCompletionBlockWithSuccess:failure:のいずれかを使用してcompletionBlockを設定できます。完了ブロックは、リクエストのダウンロードが完了した後に実行されることに注意してください。

マルチパートフォームブロックに関しては、-appendWithFileData:mimeType:nameもしばらく前に削除されました。必要なメソッドは-appendPartWithFileData:name:fileName:mimeType:です。

これらの2つの変更を行うと、すべてが機能するはずです。

于 2012-09-03T11:51:51.537 に答える