0

AFNetworking を使用してコンテンツをサーバーに POST する、Rails を使用した iOS アプリを構築しています。ユーザーはコメント付きの写真をアップロードできます。これは機能します。また、ユーザーがテキストだけをアップロードできるようにするオプションも必要です。これが問題です。写真とテキストを保存する方法と、テキストだけを保存する方法があります。写真を保存する方法は機能しますが、テキストを保存する方法は投稿を作成しますが、テキストは null です。写真の保存の実装は次のようになります。

- (void)savePhotoAtLocation:(CLLocation *)location
                     withBlock:(void (^)(CGFloat))progressBlock completion:(void (^)(BOOL, NSError *))completionBlock {

if (!self.content) self.content = @"";

NSDictionary *params = @{
                         @"post[content]" : self.content,
                         @"post[lat]": @(location.coordinate.latitude),
                         @"post[lng]": @(location.coordinate.longitude)

                         };

NSURLRequest *postRequest = [[APIClient sharedClient] multipartFormRequestWithMethod:@"POST"                                                                               path:@"/posts" parameters:params 
    constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
                                          {
                                              [formData appendPartWithFileData:self.photoData
                                                                          name:@"post[photo]"
                                                                      fileName:@""
                                                                      mimeType:@"image/png"];
                                          }];
    AFHTTPRequestOperation *operation = [[AFJSONRequestOperation alloc] initWithRequest:postRequest];

このメソッドは、photoData がある場合にのみ機能します。photoData がない場合、アプリはクラッシュします。文字列のみを含めることができる multipartFormRequest- に相当するものは何ですか? これは私が今持っているものです-これは投稿を作成しますが、コンテンツを返します:現在の場所で返される緯度/経度パラメータと同様に。これはポストモデルで定義されています

- (void)savePostAtLocation:(CLLocation *)location
    withBlock:(void (^)(CGFloat progress))progressBlock completion:(void (^)(BOOL success, NSError *error))completionBlock {

    if (!self.content) self.content = @"";

    NSDictionary *params = @{
                             @"post[content]" : self.content,
                             @"post[lat]" : @(location.coordinate.latitude),
                             @"post[lng]" : @(location.coordinate.longitude)
                                  };

    NSURLRequest *postRequest = [[APIClient sharedClient]requestWithMethod:@"POST" path:@"/posts" parameters:params];

    AFHTTPRequestOperation *operation = [[AFJSONRequestOperation alloc] initWithRequest:postRequest];

        [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        if (operation.response.statusCode == 200 || operation.response.statusCode == 201) {
            NSLog(@"Created, %@", responseObject);
            NSDictionary *updatedPost = [responseObject objectForKey:@"post"];
            [self updateFromJSON:updatedPost];
            [self notifyCreated];
            completionBlock(YES, nil);
        } else {
            completionBlock(NO, nil);
        }
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        completionBlock(NO, error);
        }];

    [[APIClient sharedClient] enqueueHTTPRequestOperation:operation];
}

AddPostViewController saveでは、次のように呼び出します。

- (void)save:(id)sender

{
    CLLocationManager * locationManager = [[CLLocationManager alloc] init];
    self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
    self.locationManager.distanceFilter = 80.0f;
    [locationManager startUpdatingLocation];
    [self getLocation];
    CLLocation * location = [locationManager location];

    Post *post = [[Post alloc] init];
    post.content = self.contentTextField.text;

    [self.view endEditing:YES];

    ProgressView *progressView = [ProgressView presentInWindow:self.view.window];
    if (location) {

    [post savePostAtLocation:self.locationManager.location withBlock:^(CGFloat progress) {
        [progressView setProgress:progress];
    } completion:^(BOOL success, NSError *error) {
        [progressView dismiss];
        if (success) {
            [self.navigationController popViewControllerAnimated:YES];
        } else {
            NSLog(@"ERROR: %@", error);
        }
    }];
    } else {
        NSLog(@"No Location");
    }
}

記事作成後のログです。ご覧のとおり、属性は null- であり、そうであってはなりません。

Created, {
    post =     {
        content = "<null>";
        "created_at" = "2013-07-21T18:45:12Z";
        id = 13;
        lat = "<null>";
        lng = "<null>";

    success = 1;
}

したがって、投稿が作成されたが属性が null であるという事実は、問題は単に NSURLRequest にあり、AFNetworking プロトコルを完全には実装していないが、投稿を実装する方法を見つけることができなかったと思います。 fileData を含まないリクエスト。fileData を追加しない投稿リクエストを作成するにはどうすればよいですか? どんな助けでも大歓迎です。ありがとう!

4

2 に答える 2

0

これが私がそれを機能させる方法です:post.h

+ (void)createNoteAtLocation:(CLLocation *)location
                 withContent:(NSString *)content
                       block:(void (^)(Post *post))block;

post.m

+ (void)createNoteAtLocation:(CLLocation *)location
                 withContent:(NSString *)content
                       block:(void (^)(Post *post))block
{
    NSDictionary *parameters = @{ @"post": @{
                                          @"lat": @(location.coordinate.latitude),
                                          @"lng": @(location.coordinate.longitude),
                                          @"content": content
                                          }
                                  };

    [[APIClient sharedClient] postPath:@"/posts" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
        Post *post = [[Post alloc] initWithDictionary:responseObject];
        if (block) {
            block(post);
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        if (block) {
            block(nil);
        }
    }];
}

そして最後に createPostViewController で:

- (void)save:(id)sender

{
    CLLocationManager * locationManager = [[CLLocationManager alloc] init];
    self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
    self.locationManager.distanceFilter = 80.0f;
    [locationManager startUpdatingLocation];

    [self getLocation];
    CLLocation * location = [locationManager location];


    Post *post = [[Post alloc] init];
    post.content = self.contentTextField.text;

    [self.view endEditing:YES];

    if (location) {

        [Post createNoteAtLocation:location withContent:self.contentTextField.text block:^(Post *post) {
            NSLog(@"Block: %@", post);
            [self.navigationController popViewControllerAnimated:YES];
        }];
    }
于 2013-08-02T19:37:08.913 に答える