iOS开发的全新,所以我在这里感觉有些迷失。我们如何使用NSURLSession将图像上传到Web服务器(我将设置的PHP rest API)?
我已经能够将代码编写到用户能够选择图像的位置,但现在我需要将此图像发送到我的PHP网页来处理它。有关如何执行此操作的任何建议,以及让我的PHP设置来处理此类请求的最佳方法吗?
任何建议/见解将不胜感激!
答案 0 :(得分:0)
在与Web服务交互时使用的Abetter选择是AFNetworking
以下是上传图片的代码
-(void)uploadImage:(UIImage *)image{
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:@"http://server.url"]];
NSData *imageData = UIImageJPEGRepresentation(image, 0.5);
NSDictionary *parameters = @{}; // pass parameter here
AFHTTPRequestOperation *op = [manager POST:@"{SERVER_URL}" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
//do not put image inside parameters dictionary as I did, but append it!
[formData appendPartWithFileData:imageData name:paramNameForImage fileName:@"photo.jpg" mimeType:@"image/jpeg"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"Success: %@ \n%@", operation.responseString, responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@ \n%@", operation.responseString, error);
}];
[op start];
}
答案 1 :(得分:0)
NSURLSession与NSURLSessionTasks一起使用,它执行实际的HTTP调用。这些任务以异步方式工作并以块的形式提供数据,因此您需要一些对象来设置这些任务,使它们工作并等待其结果。此对象的类需要充当NSURLSessionTasks的委托,因此需要实现一些委托协议:
@interface MyUrlSessionTasksManager : NSObject <NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate>
...
@end
我有一个班级可以做到这一点。它保留了正在运行的任务列表,并累积了检索到的分块数据,直到它们完成为止。然后它将结果返回给请求者,从技术上讲,它是委托者。在初始化时,它创建并配置NSURLSession(我正在使用cookie)和一个空的任务列表:
- (id) init {
self = [super init];
if (self) {
self.runningTasks = [NSMutableDictionary dictionary];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
configuration.HTTPShouldSetCookies = YES;
configuration.HTTPCookieAcceptPolicy = NSHTTPCookieAcceptPolicyAlways;
self.session = [NSURLSession sessionWithConfiguration: configuration
delegate: self
delegateQueue: [NSOperationQueue mainQueue]];
}
return self;
}
如上所述,此类适用于报告完成结果的委托。以下是委托的定义:
@protocol MyUrlSessionTasksManagerDelegate <NSObject>
- (void) sessionTask: (NSURLSessionTask *) task completedWithError: (NSError *) error data: (NSData *) data;
@end
此类的主要方法(对于本例)是:
- (NSURLSessionTask *) startPostTaskForURL: (NSURL *) url parameters: (NSDictionary *) values {
NSURLRequest *request = [self createPostRequestWithURL:url parameters:values];
NSURLSessionTask *task = [self.session dataTaskWithRequest:request];
[self scheduleTask:task];
return task;
}
此方法采用NSURL和参数的NSDictionary,创建HTTP POST请求,使用该请求创建任务并安排任务执行。调度只是将任务放在字典“运行任务”中。使用关联的Data对象来累积收到的数据:
- (void) scheduleTask: (NSURLSessionTask *) task {
[self.runningTasks setObject:[NSMutableData data] forKey:task];
[task resume];
}
每当有任务数据时,都会调用以下TaskDelegate方法。它所做的就是在运行任务列表中查找任务,并将收到的数据附加到与Data对象相关的任务中:
- (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
NSMutableData *runningData = [self dataForTask:dataTask];
if (!runningData) {
NSLog(@"No data found for task");
}
[runningData appendData: data];
}
完成数据接收后,将调用以下TaskDelegate方法。它只是报告给它的委托,传递整个Data对象和任何错误:
- (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
[self.delegate sessionTask:task completedWithError:error data:[self dataForTask:task]];
}
使用了一些内部支持方法:
- (NSMutableData *) dataForTask: (NSURLSessionTask *) task {
return [self.runningTasks objectForKey:task];
}
- (NSString *)urlEncodedUTF8String: (NSString *) source {
return (id)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(0, (CFStringRef)source, 0,
(CFStringRef)@";/?:@&=$+{}<>,", kCFStringEncodingUTF8));
}
- (NSString *) createHttpParameters: (NSDictionary *) parameters {
NSMutableString *body = [NSMutableString string];
for (NSString *key in parameters) {
NSString *val = [parameters objectForKey:key];
if ([body length])
[body appendString:@"&"];
[body appendFormat:@"%@=%@", [self urlEncodedUTF8String: [key description]],
[self urlEncodedUTF8String: [val description]]];
}
return body;
}
- (NSURLRequest *)createPostRequestWithURL:(NSURL *)url
parameters:(NSDictionary *)parameters {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request addValue:@"application/x-www-form-urlencoded"
forHTTPHeaderField:@"Content-Type"];
NSString * httpParams = [self createHttpParameters:parameters];
[request setHTTPBody:[httpParams dataUsingEncoding:NSUTF8StringEncoding]];
return request;
}
此代码中未提供的是如何获取文件并将其转换为正确的编码,以将其作为POST主体中的参数传递。原因是这个代码是从我的一个项目中复制的,它没有使用文件上传。我仍然希望它可以帮到你。