iOS使用表單流上傳檔案(圖片/文字/...)
#define HTTP_CONTENT_BOUNDARY @"----WebKitFormBoundarywpMAGHPPMfSNBkkK----"
+ (BOOL)httpPutDataWithUploadDate:(NSString *)uploadDate UserName:(NSString *)userName FilePath:(NSString *)filePath{
NSString *strUrl = [clsOtherFun getUploadCrashFileURL];
strUrl = [strUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:strUrl];
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSString *fileName = [filePath lastPathComponent];
NSMutableString *bodyStr = [[NSMutableString alloc] init];
[bodyStr appendString:[NSString stringWithFormat:@"--%@\nContent-Disposition: form-data; name=\"UploadDate\";\n\n%@\n" , HTTP_CONTENT_BOUNDARY, uploadDate]];
[bodyStr appendString:[NSString stringWithFormat:@"--%@\nContent-Disposition: form-data; name=\"UserName\";\n\n%@\n", HTTP_CONTENT_BOUNDARY, userName]];
[bodyStr appendString:[NSString stringWithFormat:@"--%@\nContent-Disposition: form-data; name=\"System\";\n\niOS\n" , HTTP_CONTENT_BOUNDARY]];
[bodyStr appendString:[NSString stringWithFormat:@"--%@\nContent-Disposition: form-data; name=\"%@\"; filename=\"%@\"\nContent-Type: %@\n\n",HTTP_CONTENT_BOUNDARY, @"file1", fileName, @"text/plain"]];
NSMutableData *httpBody = [NSMutableData data];
[httpBody appendData:[bodyStr dataUsingEncoding:NSUTF8StringEncoding]];
[httpBody appendData:data];
[httpBody appendData:[[NSString stringWithFormat:@"\n--%@",HTTP_CONTENT_BOUNDARY] dataUsingEncoding:NSUTF8StringEncoding]];
NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] init];
[urlRequest setURL:url];
[urlRequest setHTTPMethod:@"POST"];
[urlRequest setTimeoutInterval: 60000];
[urlRequest setValue:[NSString stringWithFormat:@"%@", @(httpBody.length)] forHTTPHeaderField:@"Content-Length"];
[urlRequest setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",HTTP_CONTENT_BOUNDARY] forHTTPHeaderField:@"Content-Type"];
urlRequest.HTTPBody = httpBody;
NSHTTPURLResponse *httpResponse = nil;
NSError *error = [[NSError alloc] init];
NSData *responseData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&httpResponse error:&error];
if (responseData != nil) {
// NSMutableDictionary *dict = NULL;
//IOS5自帶解析類NSJSONSerialization從response中解析出資料放到字典中
// NSString *responseStr = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];
//若狀態碼為200,則伺服器訪問成功!
if (httpResponse == nil) {
NSLog(@"url: %@\nerror_code: %@", strUrl, error);
}
if (httpResponse.statusCode != 200) {
NSLog(@"url: %@\nHTTP response: %ld", strUrl, (long)httpResponse.statusCode);
}
//若後臺返回字串“1”,則檔案上傳成功!
NSString *resultStr = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
if (httpResponse.statusCode == 200 && [resultStr isEqualToString:@"1"]) {
return YES;
}
else{
return NO;
}
NSLog(@"upload_file_resultStr: %@", resultStr);
}
return NO;
}
這是我用Safari擷取的POST請求的表單流格式,見下圖:
(因後臺伺服器提供的介面已不可訪問,故顯示的內容不太契合。若訪問正常,則“No user permission.”顯示為下圖的內容。)
上面就是需要拼接的表單流格式。注意:一定要嚴格遵循這種格式!
圖中每個框框的內容為對應引數的格式。
這時候只需要我們拼接的引數、字串格式是嚴格遵循以上格式。
上面的程式碼不免顯得臃腫,也難以通用。
下面介紹一種更為簡單便捷的方式,當然同樣基於POST請求。沒錯,主角就是AFNetworking,AFHTTPSessionManager為我們提供了
*- (NSURLSessionDataTask )POST:(NSString *)URLString
parameters:(id)parameters
constructingBodyWithBlock:(void (^)(id formData))block
progress:(nullable void (^)(NSProgress * _Nonnull))uploadProgress
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
failure:(void (^)(NSURLSessionDataTask task, NSError *error))failure*
這一方法,自從用了它,我們的程式碼處理一切都變得簡單起來。
關鍵程式碼:
AFHTTPSessionManager *session = [AFHTTPSessionManager manager];
session.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:
@"application/json",
@"text/json",
@"text/javascript",
@"text/html",
@"text/plain",
nil];
[session POST:[Utils getVerificationURL]
//我們的引數集合
parameters:@{@"UserID":userIDStr,
@"IDNumber":idNumStr,
@"RealName":realNameStr,
@"File1":fileName1,
@"File2":fileName2}
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:photoData1 name:@"File1"
fileName:fileName1 mimeType:@"image/jpeg"];
[formData appendPartWithFileData:photoData2 name:@"File2"
fileName:fileName2 mimeType:@"image/jpeg"];
}
progress:^(NSProgress * _Nonnull uploadProgress) {
NSLog(@"service progress...");
}
success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (responseObject != nil) {
// {"Code":1,"Msg":"1.成功; 3.使用者不存在或無效; 4.使用者已經完成稽核; 5.寫入資料失敗 "}
// 若後臺返回"Code"欄位為“1”,則檔案上傳成功!
NSLog(@"POST Response Code:%@", [responseObject valueForKey:@"Code"]);
//responseObject的格式已經為JSON資料格式。
if ([[responseObject valueForKey:@"Code"] integerValue] == 1){
//do you what you want.
//[session invalidateSessionCancelingTasks:YES];
}
}
}
failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"POST Error: %@", error.description);
}
];
}
文章難免會有紕漏之處,若有發現,還望各位同仁提出。讓我們共同交流,一起進步!