我正在构建一个支持rails的ios应用程序,该应用程序使用AFNetworking将内容POST到服务器。用户可以上传带有评论的照片 - 这样可行。我也希望让用户只上传文本 - 这是我遇到麻烦的地方。我有一种方法可以保存照片和文本,另一种方法可以保存文本。保存照片方法有效,但保存文本方法创建一个帖子但文本为空。 保存照片的实现是这样的:
- (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-只允许你包含一个字符串? 这就是我现在所拥有的 - 它创建了一个post-but返回内容:以及应该与当前位置一起返回的lat / lng params。 这在后期模型中定义
- (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的post请求。如何发出不附加fileData的发布请求? 任何帮助将不胜感激。 谢谢!
答案 0 :(得分:1)
您可以复制现有方法,但不是使用appendPartWithFileData:name:fileName:mimeType:
来设置文件数据,而是可以将参数转换为数据并使用appendPartWithFormData:name:
添加它们。
答案 1 :(得分: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];
}];
}