I've looked into a good number of articles on how to do a multipart/form-data POST on iOS, but none really explain what to do if there were normal parameters as well as the file upload.
NSURL *url = [NSURL URLWithString:requestString];
NSMutableURLRequest* urlRequest = [NSMutableURLRequest requestWithURL: url cachePolicy: NSURLRequestReloadIgnoringCacheData timeoutInterval:60.0];
[urlRequest setHTTPMethod:@"POST"];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[urlRequest setValue:MainHEADER forHTTPHeaderField:@"Auth"];
NSData *imageData = UIImageJPEGRepresentation(image, 0.8);
image = nil;
NSString charset = (NSString )CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
NSString *boundary = @"0xKhTmLbOuNdArY";
NSString *endBoundary = [NSString stringWithFormat:@"\r\n--%@\r\n", boundary];
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; charset=%@; boundary=%@", charset, boundary];
[urlRequest addValue:contentType forHTTPHeaderField: @"Content-Type"];
NSMutableData *tempPostData = [NSMutableData data];
// Param in body
[parameters enumerateKeysAndObjectsUsingBlock:^(NSString parameterKey, NSString parameterValue, BOOL *stop) {
[tempPostData appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[tempPostData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", parameterKey] dataUsingEncoding:NSUTF8StringEncoding]];
[tempPostData appendData:[[NSString stringWithFormat:@"%@\r\n", parameterValue] dataUsingEncoding:NSUTF8StringEncoding]];
}];
// param in body
if (imageData != nil)
{
[tempPostData appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// Sample Key Value for data
[tempPostData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", @"image"] dataUsingEncoding:NSUTF8StringEncoding]];
// [[tempPostData appendData:@"Value_Param"] dataUsingEncoding:NSUTF8StringEncoding]];
[tempPostData appendData:[endBoundary dataUsingEncoding:NSUTF8StringEncoding]];
// Sample file to send as data
[tempPostData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"image\"; filename=\"%@\"\r\n", @".jpg"] dataUsingEncoding:NSUTF8StringEncoding]];
[tempPostData appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[tempPostData appendData:imageData];
[tempPostData appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
}
[urlRequest setHTTPBody:tempPostData];
tempPostData = nil;
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse response, NSData data, NSError *error)
{
dispatch_async(dispatch_get_main_queue(), ^{
});
if (error)
{
NSLog(@"Error,%@", [error localizedDescription]);
failureBlock([error localizedDescription]);
}
else
{
NSError *errorJson;
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingMutableContainers error: &errorJson];
data = nil;
errorJson = nil;
response = nil;
error = nil;
NSLog(@"Json = %@",JSON);
dispatch_async(dispatch_get_main_queue(), ^{
successBlock(JSON);
});
JSON = nil;
}
}];
requestString = nil;
url = nil;
urlRequest = nil;
queue = nil;
This is my code working in the objective-c but i don't know how to do in the swift
I have used the multipart/form-data POST on iOS & I had written the following code and it is uploading data but not image data
I have looked the code with armofire but we need to do without it and with the session url request
I have following code which are used in my current project to upload image on server using multipart form data as we as when normal parameters.
// Create function which accept Parameters and UIImage type
// Completion block with return [String: Any] or Error
func addProfileDetails(parameters: Parameters, image: UIImage?, completion: @escaping (ProfileImageModel?, Error?) -> Void) {
// If image not nil then code with parameters and image
if image != nil {
Alamofire.upload( multipartFormData: { multipartFormData in
for (key, value) in parameters {
if let data = (value as! String).data(using: .utf8) {
multipartFormData.append(data, withName: key)
}
}
let imageData = image?.jpegData(compressionQuality: 0.5)
multipartFormData.append(imageData!, withName: "profile_image", fileName: "profileImage", mimeType: "image/jpeg")
}, to: YourUrl, headers: YourHeaders, encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.response(completionHandler: { (defaultDataResponse) in
guard let httpResponse = defaultDataResponse.response else {
completion(nil, defaultDataResponse.error)
return
}
if httpResponse.statusCode == 200 {
do {
// Decode json to my model
let genericModel = try JSONDecoder().decode(ProfileImageModel.self, from: defaultDataResponse.data!)
completion(genericModel, nil)
} catch {
completion(nil, error)
}
} else {
completion(nil, defaultDataResponse.error)
}
})
case .failure(let encodingError):
completion(nil, encodingError)
}
})
} else {
// Get you url
let baseUrl = YourUrlString
// Setup normal parameters
// This is mine, you can use yours
let dataString = "first_name=\(parameters["first_name"]!)&last_name=\(parameters["last_name"]!)&bio=\(parameters["bio"]!)&image_status=\(parameters["image_status"]!)&location=\(parameters["location"]!)&latitude=\(parameters["latitude"]!)&longitude=\(parameters["longitude"]!)"
let url = URL(string: baseUrl)! // Create url
let session = URLSession.shared // Create shared session instance
var request = URLRequest(url: url) // Create url request
request.httpMethod = "POST" // Set http method as POST
// Encode parameters using utf8
if let encodedData = dataString.data(using: .utf8) {
request.httpBody = encodedData
}
// Set content type and encoding acceptance parameters in header
request.addValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.addValue("gzip", forHTTPHeaderField: "Accept-Encoding")
request.addValue("ios", forHTTPHeaderField: "requestfrom")
if let authToken = UserDefaults.UserData.string(forKey: .authToken) {
request.addValue(authToken, forHTTPHeaderField: "authtoken")
}
// Create Session Task
let task = session.dataTask(with: request, completionHandler: { data, response, error in
// Hide progress
DispatchQueue.main.async {
AppDelegate.shared.showProgress(showHUD: .hide, message: "")
}
// Check error is nil
guard error == nil else {
completion(nil, error)
return
}
// Check data not empty
guard let data = data else {
completion(nil, nil)
return
}
do {
// Decode JSON to my ProfileImageModel model, you can use [String: Any] or model
let genericModel = try JSONDecoder().decode(ProfileImageModel.self, from: data)
completion(genericModel, nil)
} catch {
completion(nil, error)
}
})
task.resume()
}
}
I hope this will help you.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.