Reputation: 4232
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
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)
}
}
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)")
}
}
Upvotes: 36
Views: 65392
Reputation: 1
import Foundation
import UIKit
class ViewModel:NSObject {
func hitPostApi(username: String, password: String, completion: @escaping (Bool) -> Void) {
let url = "https://dummyjson.com/auth/login"
guard let serviceUrl = URL(string: url) else { return }
let parameters: [String: Any] = [
"username": username,
"password": password
]
var request = URLRequest(url: serviceUrl)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: []) else {
return
}
request.httpBody = httpBody
request.timeoutInterval = 20
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let error = error {
print("Error: \(error.localizedDescription)")
completion(false)
return
}
guard let data = data else {
completion(false)
return
}
do {
let decoder = JSONDecoder()
if let loginResponse = try? decoder.decode(LoginproductModel.self, from: data) {
UserDefaults.standard.setValue(loginResponse.accessToken, forKey: "accessToken")
print("Login Successful")
print("Data",data)
print("Token", loginResponse.accessToken)
completion(true) // Notify success
} else {
print("Failed to decode login response")
completion(false)
}
}
}.resume()
}
func changeApiKey(completionHandler: @escaping(AfterLogin) -> Void) {
if let url = URL(string: "https://dummyjson.com/auth/me") {
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("text/plain",forHTTPHeaderField: "Accept")
// request.addValue("sk_d3KmPtjEtdGTjChLB0ylraAb/AWgfyR9MOxFXwgEWSZsnpoIXFVDfm1Snoak0ufRe0w=", forHTTPHeaderField: "secret_key")
// request.addValue("pk_Bvk6rVC7WxbRW2O3sy4xwCEiM+n8jdT55BQv4BA0zG4IawzpbDhTVzSvj43DcvU7cM0x", forHTTPHeaderField: "publish_key")
// request.addValue("Bearer \(String(describing: UserDefaults.standard.string(forKey: "acessToken")))", forHTTPHeaderField: "Authorization")
var token = String()
token = UserDefaults.standard.string(forKey: "accessToken") ?? ""
request.addValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard error == nil else {
print(error!)
return
}
guard let jsonData = data else { return }
do {
let decoder = JSONDecoder()
let productsResponse = try decoder.decode(AfterLogin.self, from: jsonData)
let productDetails = productsResponse
DispatchQueue.main.async {
//self.tblData = productDetails.body?.nutritionistsList
// tbale.reloadData()
}
completionHandler(productDetails)
}catch {
print(error.localizedDescription)
}
}
task.resume()
}
}
}
// usage
@IBAction func btnLogin(_ sender: UIButton) {
vIewModel.hitPostApi(username: textUername.text ?? "", password: textPassword.text ?? "") { success in
DispatchQueue.main.async {
if success {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "HomeView") as! HomeView
self.navigationController?.pushViewController(vc, animated: true)
} else {
print("Login failed")
}
}
}
}
var viewModel = ViewModel()
var model:AfterLogin?
override func viewDidLoad() {
super.viewDidLoad()
viewModel.changeApiKey {
[weak self] data in
DispatchQueue.main.sync {
self?.model = data
self?.lblName.text = "\(self?.model?.firstName ?? "") \(self?.model?.maidenName ?? "") \((self?.model?.lastName ?? ""))"
self?.lblAge.text = "\(self?.model?.age ?? 0)"
self?.lblGender.text = "\(self?.model?.gender ?? "")"
self?.lblemail.text = "\(self?.model?.email ?? "")"
self?.lblPhone.text = "\(self?.model?.phone ?? "")"
self?.lblbloodgroup.text = "\(self?.model?.bloodGroup ?? "")"
self?.lblHeight.text = "\(self?.model?.height ?? 0.0)"
self?.lblWeigt.text = "\(self?.model?.weight ?? 0.0)"
self?.lblEyeColor.text = "\(self?.model?.eyeColor ?? "")"
self?.lblHair.text = "\(self?.model?.hair?.color ?? "")"
self?.lblhairType.text = "\(self?.model?.hair?.type ?? "")"
self?.lblNAdrees.text = "\(self?.model?.address?.city ?? "")\(self?.model?.address?.state ?? "") \(self?.model?.address?.country ?? "")"
self?.lbluniversity.text = "\(self?.model?.university ?? "")"
self?.lblComdpart.text = "\(self?.model?.company?.department ?? "")"
guard let url = URL(string: "\(self?.model?.image ?? "")") else { return }
UIImage.loadFrom(url: url) { image in
self?.img.image = image
}
}
}
}
Upvotes: -1
Reputation: 1
in API Calling if you want to pass headers, params and body. also parse response data in your custom model
let Url = String(format: "https://reqres.in/api/users")
guard let serviceUrl = URL(string: Url) else { return }
let parameters = ["page" : "2"]
let body = ["email": "[email protected]", "password": "pistol"]
let headers = ["token": "123425657"]
var request = URLRequest(url: serviceUrl)
request.httpMethod = "GET"
var components = URLComponents(url: serviceUrl, resolvingAgainstBaseURL: false)
components?.queryItems = parameters.map { URLQueryItem(name: $0.key, value: $0.value) }
request.url = components?.url
do {
let jsonData = try JSONSerialization.data(withJSONObject: body, options: [])
request.httpBody = jsonData
} catch {
print("Failed to serialize body data:", error)
return
}
request.setValue("Application/json", forHTTPHeaderField: "Content-Type")
for (key, value) in headers {
request.setValue(value, forHTTPHeaderField: key)
}
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data {
do {
let decoder = JSONDecoder()
let user = try decoder.decode(User.self, from: data)
print("User:", user)
} catch {
print("Failed to decode response data:", error)
}
}
}.resume()
Upvotes: 0
Reputation: 4737
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()
}
Upvotes: 84
Reputation: 1298
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()
}
Upvotes: 0
Reputation: 8463
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)
}
}
Upvotes: 10
Reputation: 380
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()
}
Upvotes: 9
Reputation: 11
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()
}
Upvotes: 1
Reputation: 1712
Http body is missing. Example - setting string paramets as body
let paramString = String(format:"param1=%@¶m2=%@",param1,param2)
request.httpBody = paramString.data(using: String.Encoding.utf8)
here just try
request.httpBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err)
Upvotes: 2
Reputation: 797
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 :)
Upvotes: 4