文章首次整理發(fā)布個人博客一之筆:iOS中AFN表單提交
AFN 幾乎可以成為iOS開發(fā),網(wǎng)絡(luò)請求的終結(jié)者了技健,極大的方便了我們在開發(fā)中的網(wǎng)絡(luò)請求,我們在此基礎(chǔ)上都會做自己的一層或者多層封裝亩冬,盡可能使調(diào)用API更加方便务冕;即便如此,我們還是會遇到各種各樣的問題翘贮,比如415赊窥,3840,不支持的數(shù)據(jù)格式text/plain等等狸页。接下來锨能,就在最近,遇到了芍耘,需要“表單上傳”的API址遇;
表單FORM
Form(表單)對于每個WEB開發(fā)人員來說,應(yīng)該是再熟悉不過的東西了斋竞,通常也多用于Web中倔约,這里,我們不展開FROM的討論窃页,如果感興趣的話,可以看看這篇文章复濒,比較詳細了脖卖;
對于移動端來說,用的比較少巧颈;移動端常用的數(shù)據(jù)格式:@"application/json",@"text/json“畦木;
表單上傳圖片
最初接觸這個表單上傳是在APP中的圖片上傳,也就是砸泛,如何用AFN進行文件上傳十籍;搜了一下蛆封,搜到了如下文章:
1.iOS利用AFN框架來上傳圖片功能;
2.iOS開發(fā)之使用AFN上傳圖片;
以上兩篇文章基本就能解決上傳資源到公司服務(wù)器了;簡言之勾栗,就是下面的代碼
// images:圖片對象數(shù)組
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain", @"multipart/form-data", @"application/json", @"text/html", @"image/jpeg", @"image/png", @"application/octet-stream", @"text/json", nil];
[manager POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
for (int i = 0; i < images.count; i++) {
UIImage *image = images[i];
NSData *imageData = UIImagePNGRepresentation(image);
// 在網(wǎng)絡(luò)開發(fā)中惨篱,上傳文件時,是文件不允許被覆蓋围俘,文件重名
// 要解決此問題砸讳,
// 可以在上傳時使用當(dāng)前的系統(tǒng)事件作為文件名
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
// 設(shè)置時間格式
[formatter setDateFormat:@"yyyyMMddHHmmss"];
NSString *dateString = [formatter stringFromDate:[NSDate date]];
NSString *fileName = [NSString stringWithFormat:@"%@.png", dateString];
/*
*該方法的參數(shù)
1. appendPartWithFileData:要上傳的照片[二進制流]
2. name:對應(yīng)網(wǎng)站上[upload.php中]處理文件的字段(比如upload)
3. fileName:要保存在服務(wù)器上的文件名
4. mimeType:上傳的文件的類型
*/
[formData appendPartWithFileData:imageData name:@"fs" fileName:fileName mimeType:@"image/png"];
}
} progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (self.successBlock) {
self.successBlock(responseObject);
}
[[LXNetworkHandler sharedInstance] removeItem:self];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"上傳失敗: %@", error);
if (self.failureBlock) {
self.failureBlock(error);
}
else {
}
}];
POST 表單上傳
網(wǎng)上關(guān)于iOS表單POST請求的比較少,能谷歌到最多的就是界牡,文件上傳簿寂,API基本沒有的,我就嘗試著修改了下上面圖片上傳的封裝宿亡,因為常遂,本質(zhì)上都是表單上傳大的數(shù)據(jù),也就嘗試了一下挽荠,AFN是支持表單上傳的克胳;最初遇到這個問題,問了下Android同事咋處理的坤按,他自己拼的表單格式毯欣,也是厲害了,這里給個Android的參考:
OC這邊臭脓,就是對圖片上傳的接口修改下酗钞,拼接的參數(shù),代碼如下:
需要注意的是:我們后臺要求来累,這個items,是個json字符串砚作,因此,不能直接對數(shù)據(jù)上傳嘹锁,需要利用系統(tǒng)的方法葫录,序列化處理下:
- [NSJSONSerialization dataWithJSONObject:items options:NSJSONWritingPrettyPrinted error:&error];
完整的代碼如下:
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain", @"multipart/form-data", @"application/json", @"text/html", @"image/jpeg", @"image/png", @"application/octet-stream", @"text/json", nil];
[manager POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:items options:NSJSONWritingPrettyPrinted error:&error];
[formData appendPartWithFormData:jsonData name:@"items"];
} progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (self.successBlock) {
self.successBlock(responseObject);
}
[[LXNetworkHandler sharedInstance] removeItem:self];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"上傳失敗: %@", error);
if (self.failureBlock) {
self.failureBlock(error);
}
else {
}
[[LXNetworkHandler sharedInstance] removeItem:self];
}];
以上就是利用POST請求,封裝表單上傳的應(yīng)用领猾,歡迎留言討論米同;謝謝!