code optimization not working in ios Swift? - ios

I am using Swift and alamofire.
How can I do code optimization? This is my post and put request for different api's:
func getPDataFromURL(_ onCompletion:#escaping (Dictionary<String, Any>)-> Void)
{
let token = UserDefaults.standard.string(forKey: "UserLoginToken")
let Usertype = UserDefaults.standard.string(forKey: "Usertype")
let Userbranchid = UserDefaults.standard.string(forKey: "Userbranchid")
let UrlStraing = FETCH_Parent_Profile_URL
print(UrlStraing)
let url = URL(string: UrlStraing)!
var urlRequest = URLRequest(url:url)
urlRequest.httpMethod = "GET"
urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")
let userToken = "Token token=" + token! as String
urlRequest.addValue(userToken, forHTTPHeaderField: "Authorization")
Alamofire.request(urlRequest).responseJSON { (response:DataResponse<Any>) in
switch(response.result) {
case .success(_):
if response.result.value != nil{
print(response.result.value!)
onCompletion(response.result.value! as! Dictionary<String, Any>)
}
break
case .failure(_):
print(response.result.error!)
onCompletion(response.result.error as! Dictionary<String, Any>)
break
}
}
}
And this is my second post request for another api:
func getSDataFromURL(_ onCompletion:#escaping (Dictionary<String, Any>)-> Void) {
let token = UserDefaults.standard.string(forKey: "UserLoginToken")
let Usertype = UserDefaults.standard.string(forKey: "Usertype")
let Userbranchid = UserDefaults.standard.string(forKey: "Userbranchid")
let UrlStraing = FETCH_School_Info_URL + "branch_id=" + Userbranchid! + "&student_id=86&user_type=" + Usertype!
print(UrlStraing)
let url = URL(string: UrlStraing)!
var urlRequest = URLRequest(url:url)
urlRequest.httpMethod = "GET"
urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")
let userToken = "Token token=" + token! as String
urlRequest.addValue(userToken, forHTTPHeaderField: "Authorization")
Alamofire.request(urlRequest).responseJSON { (response:DataResponse<Any>) in
switch(response.result) {
case .success(_):
if response.result.value != nil{
print(response.result.value!)
onCompletion(response.result.value! as! Dictionary<String, Any>)
}
break
case .failure(_):
print(response.result.error!)
onCompletion(response.result.error as! Dictionary<String, Any>)
break
}
}
}
And calling function in viewcontroller like this:
func SetUpSchoolUIProfiledata() {
Common.sharedInstance.StartActivity(view: self.view)
DispatchQueue.main.async {
APIManager.sharedInstance.getSchoolProfileDataFromURL(){(userJson)->
Void in
self.stop()
let swiftyJsonVar = JSON(userJson)
print("userJson userJson userJson userJson",userJson)
print("swiftyJsonVar",swiftyJsonVar)
let message = swiftyJsonVar["message"].rawString()
let info = swiftyJsonVar["info"].rawString()!
let jsonData = info.data(using: .utf8)!
let dictionary = try? JSONSerialization.jsonObject(with: jsonData, options: []) as! Dictionary<String, Any>
self.schoolName_lbl.text = dictionary?["name"] as? String
self.add1_lbl.text = dictionary?["add_line1"] as? String
print("imgURLstring is ",self.imgURLstring)
self.SetUpProfileImage()
}
}
}
how to create single function multiple post and get requests?

You can create singleton class like this
when you want to call the web service, use this method
class DataProvider: NSObject {
class var sharedInstance:DataProvider {
struct Singleton {
static let instance = DataProvider()
}
return Singleton.instance
}
let baseUrl:String = "http://192.168.1.25:3004/api3/v3/"
func putData( parameter:[String:String], url:String, _ successBlock:#escaping ( _ response: JSON )->Void , errorBlock: #escaping (_ error: NSError) -> Void ){
let path = baseUrl + url
print(path)
print(parameter)
let headers = ["authorization": AppData().token]
Alamofire.request(path, method: .put, parameters: parameter, encoding: JSONEncoding.default, headers: headers).responseJSON { response in
switch response.result {
case .success:
if let value = response.result.value {
let json = JSON(value)
successBlock(json)
}
case .failure(let error):
errorBlock(error as NSError)
}
}
}
call like this
DataProvider.sharedInstance.putData(parameter: parameter, url: "users/account/update", { (response) in
print(response)
if response["status"].stringValue == "200" {
Utility.showMessageDialog(onController: self, withTitle: "", withMessage: response["message"].stringValue)
}
}) { (error) in
print(error)
}

Related

How to upload image data with some extra parameters to server via POST call using Swift 4.2?

My scenario, I am trying to send some parameters with Image Data to server using POST call. Here, I need to update my code Parameters to Body request, because Image base64 string huge data producing so we cant send long lenth data with it. Please update blow code how to upload image and extra parameters to Server.
apiPath = "https://............com/api/new_line?country=\(get_countryID ?? "unknown")&attachment=\("sample.png")&user_id=\(userid ?? "unknown")"
if let encodeString = apiPath.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed),
let url = URL(string: encodeString) {
let session = URLSession.shared
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue(access_key, forHTTPHeaderField: "access-key")
request.addValue(auth_token!, forHTTPHeaderField: "auth-token")
request.timeoutInterval = 10
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
guard error == nil else {return}
guard let data = data else {return}
do {
//MARK: Create json object from data
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
print(json)
// MARK: Validate status code
let status_code : Int = json["status"]! as! Int
let status_message : String = json["message"]! as! String
if (status_code != 200) {
print("ERROR:\(String(describing: status_code))")
DispatchQueue.main.async {
self.showMessageToUser(messageStr: status_message)
}
} else {
DispatchQueue.main.async {
// Show Success Alert View Controller
if self.tfData != "" { // Call Update
self.apistatus(message:Updated Successfully!")
} else {
self.apistatus(message:"Submitted Successfully!")
}
}
}
}
} catch let error {
print(error.localizedDescription)
}
})
task.resume()
}
You can try using Alamofire (https://github.com/Alamofire/Alamofire) as below.
Alamofire.upload(
multipartFormData: { multipartFormData in
multipartFormData.append(photoData, withName: "photoId", fileName: "photoId.png", mimeType: "image/png")
for (key,value) in params { //params is a dictionary of values you wish to upload
multipartFormData.append(value.data(using: .utf8)!, withName: key)
}
},
to: URL(string : urlString)!,
method: .post,
headers: getContentHeader(),
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
if response.response?.statusCode == 200 {
print("Success")
} else {
print("Failure")
}
}
case .failure(let error):
print("Failure")
}
}
)
// Iam use alamofire Method
func sendIMAGeAndParams(urlString:String,imageData:[String:[Data]],header: String,params:[String:AnyObject], success: #escaping (AnyObject) -> Void,failure: #escaping(Error) -> Void) {
let param = ["" : ""]
let url = try! URLRequest.init(url: urlString, method: .post, headers: nil)
Alamofire.upload(multipartFormData: { (formdata) in
for (key, value) in params {
formdata.append("\(value)".data(using: String.Encoding.utf8)!, withName: key)
}
for (key,value) in imageData{
for item in value{
formdata.append(item, withName: key, fileName: "image.jpeg", mimeType: "image/jpeg")
}
}
}, with: url) { (encodingResult) in
switch encodingResult{
case .success(let upload,_,_):
upload.responseJSON(completionHandler: { (response) in
switch response.result{
case .success(_):
if (response.response?.statusCode == 200){
if let value = response.result.value {
success(value as AnyObject)
print(value)
}
}
else{
let value = response.result.value as? [String:Any]
print(value as Any)
}
break
case .failure(let error):
print(error)
break
}
})
break
case .failure(let error):
print(error)
break
}
}
}

Uploading multipart image giving error ios

I am trying to create a multipart request to upload my image. But it's not working as expected. Can some one explain where I am doing wrong.
static func makeImageRequest(_ urlString: String,version:String, method:FYIHTTPMethod,formData:Data?,fileName:String, completionHandler: #escaping (_ dictionary:NSDictionary?, _ error:NSError?) -> Void ) -> URLSessionTask {
let fullURL:String = "https://" + domain + ":8243/fyi/" + version + "/" + urlString
let request = NSMutableURLRequest(url: URL(string: fullURL)!)
request.timeoutInterval = 300
request.httpMethod = method.rawValue
request.setValue("multipart/form-data;boundary=*****", forHTTPHeaderField: "Content-Type")
request.httpBody = formData
let accessToken = FYISession.sharedInstance.getAccessToken()
request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue(fileName, forHTTPHeaderField: "image")
let defaultConfigObject:URLSessionConfiguration = URLSessionConfiguration.default
let defaultSession:URLSession = URLSession(configuration: defaultConfigObject, delegate: FYIURLSessionDelegate(), delegateQueue: OperationQueue.main)
let task = defaultSession.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
guard error == nil && data != nil else {
DispatchQueue.main.async {
completionHandler(nil, error as NSError?)
}
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
var message = ""
if let dta = data{
do {
let json = try? JSONSerialization.jsonObject(with:dta, options: JSONSerialization.ReadingOptions.allowFragments) as? NSDictionary
message = json??.object(forKey: "message") as? String ?? ""
}
}
let httpError:NSError = NSError(domain: "HTTP", code: httpStatus.statusCode, userInfo: FYIConnection.userInfo(message))
DispatchQueue.main.async {
completionHandler(nil, httpError)
}
return
}
if (data != nil) {
do {
let json:NSDictionary = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) as! NSDictionary
let api_status:Bool = json.object(forKey: "api_status") as! Bool
if (api_status){
DispatchQueue.main.async {
completionHandler(json,nil)
}
}else {
let message:String = json.object(forKey: "message") as! String
let httpError:NSError = NSError(domain: FYIConnection.bundleIdentifier(), code: FYIError.apiError.rawValue, userInfo: FYIConnection.userInfo(message))
DispatchQueue.main.async {
completionHandler(nil, httpError)
}
}
} catch let jsonError as NSError {
DispatchQueue.main.async {
completionHandler(nil,jsonError)
}
}
}else {
let httpError:NSError = NSError(domain: FYIConnection.bundleIdentifier(), code: 1, userInfo: FYIConnection.userInfo(""))
DispatchQueue.main.async {
completionHandler(nil, httpError)
}
}
})
task.resume()
return task
}
And the body is
override func createBodyWithParameters(_ parameters: [String: String]?, image: UIImage?, paths: [String]?, boundary: String) -> Data {
let body = NSMutableData()
let data = UIImagePNGRepresentation(image!)
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"file\"; filename=\"" + (self.txtMobileNumber?.text ?? "") + ".png" + "\"\r\n")
body.appendString("\r\n")
body.append(data!)
body.appendString("\r\n")
body.appendString("--\(boundary)--\r\n")
return body as Data
}
Try to fix body like this:
override func createBodyWithParameters(_ parameters: [String: String]?, image: UIImage?, paths: [String]?, boundary: String) -> Data {
let body = NSMutableData()
let mimeType = "image/jpeg"
let data = UIImagePNGRepresentation(image!)
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"file\"; filename=\"" + (self.txtMobileNumber?.text ?? "") + ".png" + "\"\r\n")
body.appendString("Content-Type: \(mimeType)\r\n\r\n")
body.appendString("\r\n")
body.append(data!)
body.appendString("\r\n")
body.appendString("--\(boundary)--\r\n")
return body as Data
}
Also try to add this:
request.setValue(String(describing: formData.length), forHTTPHeaderField: "Content-Length")

How to make NSURLSession POST request in Swift

Hi I am very beginner for Swift and I am trying to make NSURLSession "Post" request sending some parameter like my below code
According to my below code response not coming from server can some one help me please
BackGroundClass:-
import UIKit
protocol sampleProtocal{
func getResponse(result:NSDictionary)
func getErrorResponse(error:NSString)
}
class BackGroundClass: NSObject {
var delegate:sampleProtocal?
func callPostService(url:String,parameters:NSDictionary){
print("url is===>\(url)")
let request = NSMutableURLRequest(URL: NSURL(string:url)!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
//Note : Add the corresponding "Content-Type" and "Accept" header. In this example I had used the application/json.
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(parameters, options: [])
let task = session.dataTaskWithRequest(request) { data, response, error in
guard data != nil else {
print("no data found: \(error)")
return
}
do {
if let json = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
print("Response: \(json)")
self.mainResponse(json)
} else {
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)// No error thrown, but not NSDictionary
print("Error could not parse JSON: \(jsonStr)")
self.eroorResponse(jsonStr!)
}
} catch let parseError {
print(parseError)// Log the error thrown by `JSONObjectWithData`
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Error could not parse JSON: '\(jsonStr)'")
self.eroorResponse(jsonStr!)
}
}
task.resume()
}
func mainResponse(result:NSDictionary){
delegate?.getResponse(result)
}
func eroorResponse(result:NSString){
delegate?.getErrorResponse(result)
}
}
ViewController:-
import UIKit
class ViewController: UIViewController,sampleProtocal {
override func viewDidLoad() {
super.viewDidLoad()
let delegate = BackGroundClass();
delegate.self;
let params = ["scancode":"KK03799-008", "UserName":"admin"] as Dictionary<String, String>
let backGround=BackGroundClass();
backGround.callPostService("url", parameters: params)
}
func getResponse(result: NSDictionary) {
print("Final response is\(result)");
}
func getErrorResponse(error: NSString) {
print("Final Eroor code is\(error)")
}
}
Swift 4 post example with json payload-
func postAction(_ sender: Any) {
let Url = String(format: "your url")
guard let serviceUrl = URL(string: Url) else { return }
let parameterDictionary = ["username" : "Test", "password" : "123456"]
var request = URLRequest(url: serviceUrl)
request.httpMethod = "POST"
request.setValue("Application/json", forHTTPHeaderField: "Content-Type")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameterDictionary, options: []) else {
return
}
request.httpBody = httpBody
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print(json)
} catch {
print(error)
}
}
}.resume()
}
Try to run this function and print the response, it is in Swift 4.0.
Here, I have prepared codable structure:
struct LoginData: Codable {
var code: Int?
var message: String?
var status: String?
var token: String?
var data: DataSet?
}
struct DataSet: Codable {
var email : String?
var contactNo : String?
var firstName : String?
var lastName: String?
var dob : String?
var gender : String?
var address: String?
var city : String?
var state : String?
var country : String?
var zip : String?
var username: String?
}
If you get your response printed correctly then pass it to your viewController.
func loginWS(parameters:[String:String], completionHandler: #escaping (Any?) -> Swift.Void) {
guard let gitUrl = URL(string: BASE_URL+ACTION_URL) else { return }
print(gitUrl)
let request = NSMutableURLRequest(url: gitUrl)
// uncomment this and add auth token, if your project needs.
// let config = URLSessionConfiguration.default
// let authString = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxMywiUGFzc3dvcmQiOiIkMmEkMTAkYVhpVm9wU3JSLjBPYmdMMUk2RU5zdU9LQzlFR0ZqNzEzay5ta1pDcENpMTI3MG1VLzR3SUsiLCJpYXQiOjE1MTczOTc5MjV9.JaSh3FvpAxFxbq8z_aZ_4OhrWO-ytBQNu6A-Fw4pZBY"
// config.httpAdditionalHeaders = ["Authorization" : authString]
let session = URLSession.shared
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.httpBody = try! JSONSerialization.data(withJSONObject: parameters, options: [])
let task = session.dataTask(with: request as URLRequest) { data, response, error in
guard let data = data else { return }
do {
// let decoder = JSONDecoder()
// here replace LoginData with your codable structure.
let gitData = try JSONDecoder().decode(LoginData.self, from: data)
print("response data:", gitData)
completionHandler(gitData)
} catch let err {
print("Err", err)
}
}.resume()
}
Here is a sample complete solution compatible with Swift 4 and Swift 5.
Endpoint to create urls
struct Endpoint {
let path: String
let queryItems: [URLQueryItem]?
}
extension Endpoint {
var url: URL? {
var components = URLComponents()
components.scheme = "https"
components.host = "YOUR_HOST"
components.path = path
components.queryItems = queryItems
return components.url
}
}
User object model for request body
struct User: Encodable {
let name: String
let surname: String
let age: Int
// this is to customise init
init(name: String,
surname: String,
age: Int) {
self.name = name
self.surname = surname
self.age = age
}
enum CodingKeys: String, CodingKey {
case name, surname, age
}
}
UserResponse model for http response comes from API
struct UserResponse: Decodable {
let message: String
let userId: String?
enum CodingKeys: String, CodingKey {
case message, userId = "user_id" // API returns userId as "user_id"
}
}
APIClient make http requests for our api
protocol APIClientProtocol: Any {
func sendUser(_ user: User, completionBlock: #escaping (_ userResponse: UserResponse?, _ error: APIClient.Error?) -> Void)
}
class APIClient: APIClientProtocol {
fileprivate let defaultSession: URLSession = {
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 10.0
configuration.timeoutIntervalForResource = 10.0
return URLSession(configuration: configuration, delegate: nil, delegateQueue: nil)
}()
public init() { }
public func uploadUser(_ user: User, completionBlock: #escaping (UserResponse?, APIClient.Error?) -> Void) {
guard let url = Endpoint(path: "/user/upload", queryItems: nil).url else {
completionBlock(nil, .brokenURL)
return
}
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = "POST"
urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")
do {
let jsonData = try JSONEncoder().encode(user)
urlRequest.httpBody = jsonData
} catch {
completionBlock(nil, .serialization(error.localizedDescription))
return
}
let task = defaultSession.dataTask(with: urlRequest) { data, urlResponse, error in
if let error = error {
completionBlock(nil, .http(error.localizedDescription))
return
}
guard let httpResponse = urlResponse as? HTTPURLResponse else {
return
}
if httpResponse.statusCode == 200 {
guard let data = data else {
return
}
do {
let userResponse = try JSONDecoder().decode(UserResponse.self, from: data)
completionBlock(userResponse, nil)
} catch let error {
completionBlock(nil, .serialization(error.localizedDescription))
}
} else {
completionBlock(nil, .http("Status failed!"))
}
}
task.resume()
}
}
extension APIClient {
enum Error: Swift.Error, Equatable {
case brokenURL
case serialization(String)
case http(String)
}
}
Post Class
func post(params : Dictionary<String, String>, url : String) {
var request = NSMutableURLRequest(URL: NSURL(string: url))
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
var err: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
println("Response: \(response)")
var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Body: \(strData)")
var err: NSError?
var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableLeaves, error: &err) as? NSDictionary
// Did the JSONObjectWithData constructor return an error? If so, log the error to the console
if(err != nil) {
println(err!.localizedDescription)
let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Error could not parse JSON: '\(jsonStr)'")
}
else {
// The JSONObjectWithData constructor didn't return an error. But, we should still
// check and make sure that json has a value using optional binding.
if let parseJSON = json {
// Okay, the parsedJSON is here, let's get the value for 'success' out of it
var success = parseJSON["success"] as? Int
println("Succes: \(success)")
}
else {
// Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Error could not parse JSON: \(jsonStr)")
}
}
})
task.resume()
}
call This Method Like This
self.post(["username":"jameson", "password":"password"], url: "http://localhost:4567/login")
Hope It Helps :)
Http body is missing. Example - setting string paramets as body
let paramString = String(format:"param1=%#&param2=%#",param1,param2)
request.httpBody = paramString.data(using: String.Encoding.utf8)
here just try
request.httpBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err)
func getData(searchString:String,completion:#escaping(Any)->Void){
let url = "https://itunes.apple.com/search?term="+searchString
URLSession.shared.dataTask(with: URL.init(string: url)!){(data,response,err) in
if let responsedata = data{
DispatchQueue.main.async {
completion(responsedata)
}
}
}.resume()
}
Try this: (Swift 4.2)
public func submitDelivery(delivery:DeliveryModal,responseCode:String,completion:#escaping SubmitCompletionBlock){
let urlString = BaseURL.getURL(urlType: .submit(responseCode))
guard let url = URL(string: urlString) else { return }
var request : URLRequest = URLRequest(url: url)
request.httpMethod = HttpMethod.post.rawValue
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
do {
let jsonData = try encoder.encode(delivery)
request.httpBody = jsonData
} catch {
print(error.localizedDescription)
completion(nil,nil,NSError.init())
}
let dataTask = URLSession.shared.dataTask(with: request) {
data,response,error in
guard let data = data else {
completion(nil,response,NSError.init())
return
}
do {
let data = try JSONDecoder().decode(DeliverySubmitResponseModal.self, from: data)
DispatchQueue.main.async {
completion(data,response,error)
}
} catch let error {
debugPrint(error.localizedDescription)
}
}
dataTask.resume()
}

Swift POST query issue

I am facing some problem in a POST query; please help. It always sends me a 400 Bad request response. I have checked everything thoroughly but its just not working. Please help.
Code is -
struct RegisterService {
var authToken: String = ""
var baseURL = NSURL(string: "")
func getToken(name: String, email: String, password: String, cfmpassword: String, completion: (AuthToken? -> Void)) {
let request = NSMutableURLRequest(URL: baseURL!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
let params = ["accept":"on", "cfmpassword":"\(cfmpassword)",
"email":"\(email)", "name":"\(name)", "password":"\(password)"]
as Dictionary<String, AnyObject>
do {
request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: [])
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
} catch {
print("Request Unsuccessful")
}
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
print(request)
print(data)
print(response)
if let httpResponse = response as? NSHTTPURLResponse {
switch httpResponse.statusCode {
case 200:
// 2. Create JSON object with data
do {
let jsonDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [String: AnyObject]
let authToken = AuthToken(tokenDictionary: jsonDictionary!)
completion(authToken)
} catch {
print("Fetch failed: \((error as NSError).localizedDescription)")
}
default:
print("GET request not successful. HTTP status code: \(httpResponse.statusCode)")
NSOperationQueue.mainQueue().addOperationWithBlock {
completion(nil)
}
}
} else {
print("Error: Not a valid HTTP response")
NSOperationQueue.mainQueue().addOperationWithBlock {
completion(nil)
}
}
})
task.resume()
}
}
let params = ["accept":"on", "cfmpassword":"\(cfmpassword)", "email":"\(email)", "name":"\(name)", "password":"\(password)"] as Dictionary<String, AnyObject>
let boundary:String = "---------------------------14737809831466499882746641449"
let body:NSMutableData = NSMutableData()
if params != nil
{
for (key, value) in params!
{
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString("\(value)\r\n")
}
}
body.appendString("--\(boundary)--\r\n")
request.setValue("\(body.length)", forHTTPHeaderField:"Content-Length")
request.HTTPBody = body

How to send an image as POST in web service swift

var urlString = ""
let url = NSURL(string: urlString)
let theRequest = NSMutableURLRequest(URL: url!)
theRequest.HTTPMethod = "POST"
let parameters = []
var err:NSError!
do{
theRequest.HTTPBody = try NSJSONSerialization.dataWithJSONObject(parameters, options: [])
}
catch let error as NSError{
err = error
theRequest.HTTPBody = nil
}
theRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
theRequest.addValue("application/json", forHTTPHeaderField: "Accept")
Here I am using a 3rd party class library for a signature . How can I POST it to webservices in the form an image?
Simple example for you:
//create session
var urlSession : NSURLSession!
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
urlSession = NSURLSession(configuration: configuration)
func updateUserDetails(image : UIImage? , dictUserDetails: [String: String?] ,completionClosure: (repos :NSDictionary) ->()) {
let request = NSMutableURLRequest(URL: NSURL(string:"Your URL" )!)
request.HTTPMethod = "POST"
let boundary = generateBoundaryString()
let token = getUserToken() as String
request.addValue("Token " + token, forHTTPHeaderField: "Authorization") // add token if you need
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
guard image != nil else {
request.HTTPBody = createBodyWithParameters(dictUserDetails, filePathKey: "profile_pic", imageDataKey: nil, boundary: boundary)
let postDataTask = self.urlSession.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if (error != nil) {
print(error!.localizedDescription)
}
if (data != nil) {
if let jsonResult: NSDictionary = (try? NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)) as? NSDictionary
{
completionClosure(repos: jsonResult)
}
else
{
completionClosure(repos: NSDictionary())
}
} else {
completionClosure(repos: NSDictionary())
}
})
postDataTask.resume()
return
}
let imageData = UIImageJPEGRepresentation(image!, 0.3)
request.HTTPBody = createBodyWithParameters(dictUserDetails, filePathKey: "profile_pic", imageDataKey: imageData, boundary: boundary)
let postDataTask = self.urlSession.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if (error != nil) {
print(error!.localizedDescription)
}
if (data != nil) {
if let jsonResult: NSDictionary = (try? NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)) as? NSDictionary
{
completionClosure(repos: jsonResult)
}
else
{
completionClosure(repos: NSDictionary())
}
} else {
completionClosure(repos: NSDictionary())
}
})
postDataTask.resume()
}
Helper Functions:
//Generate boundary
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().UUIDString)"
}
//create body
func createBodyWithParameters(parameters: [String: String?]?, filePathKey: String?, imageDataKey: NSData?, boundary: String) -> NSData {
let body = NSMutableData()
if parameters != nil {
for (key, value) in parameters! {
if value != nil {
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString("\(value!)\r\n")
}
}
}
if imageDataKey != nil
{
let filename = "user-profile.jpg"
let mimetype = "image/jpg"
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n")
body.appendString("Content-Type: \(mimetype)\r\n\r\n")
body.appendData(imageDataKey!)
body.appendString("\r\n")
body.appendString("--\(boundary)--\r\n")
}
return body
}
Now you can use it this way:
updateUserDetails(yourImage, dictUserDetails: [
//parameters example
"date_of_birth": birthDate,
"first_name": firstName,
"last_name" : lastName,
"email" : email,
"phone_number" : phoneNumber,
"address" : address,
"martial_status" : userMaritialStatus
], completionClosure: { (repos) -> () in
print(repos)
})
Hope it will help.
You did not say which third party library you are using, so you can use Alamofire for it, using this code:
Alamofire.upload(
.POST,
"your_API_URL_here",
multipartFormData: { multipartFormData in
if let _ = image {
if let imageData = UIImageJPEGRepresentation(image!, 1.0) {
multipartFormData.appendBodyPart(data: imageData, name: "file", fileName: "file.jpeg", mimeType: "image/jpeg")
} else {
print(image)
}
}
}, encodingCompletion: {
encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseJSON { response in
switch response.result {
case .Success:
print("Success")
case .Failure(let error):
print(error)
}
}
case .Failure(let encodingError):
print(encodingError)
}
}
)
}
} catch _ {
}

Resources