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=%#¶m2=%#",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()
}
Related
I have an error running my code. I need to represent whole information of my data requested from the URL.
But this breaks when I run.
I think the code is well done, but I don't know why this breaks when I run the app.
Probably have some error when threats the JSON.
This error:
Thread 3: Fatal error: Unexpectedly found nil while unwrapping an Optional value
import Foundation
public class UnidadeCurricularManager{
private var ucs = [UnidadeCurricular]();
init(){
//URL
let url = URL(string: "http://209.97.133.56/api/ucs")!
let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjQ2Yjg2ZDNlZDI2Y2IwOGU2NDFhZTI3NjNmMWI0ZDEwODAwZWI0M2U4YjM5MThiMTQ0YmU5YWFjMzBhNGU1ZDdhMTI4ZjA1MDI2NGNkYWZhIn0.eyJhdWQiOiIyIiwianRpIjoiNDZiODZkM2VkMjZjYjA4ZTY0MWFlMjc2M2YxYjRkMTA4MDBlYjQzZThiMzkxOGIxNDRiZTlhYWMzMGE0ZTVkN2ExMjhmMDUwMjY0Y2RhZmEiLCJpYXQiOjE1NTgzNDQ1MDIsIm5iZiI6MTU1ODM0NDUwMiwiZXhwIjoxNTg5OTY2OTAyLCJzdWIiOiIzIiwic2NvcGVzIjpbXX0.LSsn172WUQqEzUf3wzq4lxgBL8pbKGqjJCpn0iEFPFQY6DhZCtcm4jHkqTC0FFMYrAA1n87LfdBeSvcdgWFsndD6MoKHFkZViqZXlUHDeyMmT-bVs2IrNSE9kGuaRQhz1rtys2KFbB2y4lq5w2BPhokPYvLc0nTwZ7oPTZKQlJkUi80PKDMP3LMUQpilc2cSE8FGe-d1UtMYUeseivwHcNee4knjfOUIsGl7_pV4knU6DYTWL8IMXfb3GjbBTagFRWfbjeqMMvtFVdZGfTxdeVoMqSgEQlA0W20GyJ3Ox4WuZAaODk4b7Q4cudR8vmPTSjvVU-IqB6_9wvtE3HUMEwiGazQRcmFtVqBYFPVIBHFWNBsWI2AbMxR_KSA6URzF-6qydj53yRqO41E88KQiWbHy29mb8BCoNvjR4gN9F97rE9j9Xpt-EsHK6QEqBOeoJixu8srDrgmYul4nWroRU6dQsFZjfZS4Vnm1LFF-ykOo0YVY08oRcV3LQTb8TsnS3RuQzlMifEhDajBPTsVyCyW9OkkTsi3N96E1VeRhyT0S08InczXeRV_K5BMdt7tvVAEMPoR4GCcHAR5e7924WVsbl9KmJ4ituf_FdCfBKdvcmErURIlCfZRELLC_8kNaT-04CG3Vj9_LrUb6eOcJrutawh60V_ITojWAxyF2LnQ"
var request = URLRequest(url: url)
request.addValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.httpMethod = "GET"
URLSession.shared.dataTask(with: request) { (data, response , error) in
guard let data = data else {
return
}
do {
if let jsonDictionary = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? Dictionary<String,Any>
{
if let dataArray = jsonDictionary["data"] as? [[String:Any]] {
for data in dataArray {
let ucIdMapSiges = data["unidadeCurricularIdMapSiges"] as! Int
let ucNome = data["unidadeCurricularNome"] as! String
let ucSigla = data["unidadeCurricularAbreviatura"] as! String
let anoCurricularIdMapSiges = data["anoCurricularIdMapSiges"] as! Int
let periodoNome = data["unidadeCurricularAbreviatura"] as! String
let codigoEstudante = data["numeroEstudante"] as! String
let ects = data["numero_creditos"] as! Int
var uc = UnidadeCurricular (ucName: ucNome, ucSigla: ucSigla, ucIdMapSiges: ucIdMapSiges, anoCurricularIdMapSiges: anoCurricularIdMapSiges, periodoNome: periodoNome, codigoEstudante: codigoEstudante, ects: ects)
self.ucs.append(uc);
}
}
} else {
print("bad json")
}
} catch let error as NSError {
print(error)
}
}.resume()
}
func getUcs() -> Dictionary<String, [UnidadeCurricular]> {
var listaOfUcs = [String : [UnidadeCurricular]]()
for u in ucs{
if listaOfUcs[String(u.anoCurricularIdMapSiges)] != nil {
listaOfUcs[String(u.anoCurricularIdMapSiges)]!.append(u);
} else {
var ucName = [UnidadeCurricular]();
ucName.append(u);
listaOfUcs[String(u.anoCurricularIdMapSiges)] = ucName;
}
}
return listaOfUcs;
}
}
You cast
let codigoEstudante = data["numeroEstudante"] as! String
but it should be
let codigoEstudante = data["numeroEstudante"] as! Int
A better approach
do {
let res = try JSONDecoder().decode(Root.self, from: data)
print(res.data)
} catch {
print(error)
}
struct Root : Codable {
let data:[Model]
}
struct Model : Codable {
let unidadeCurricularIdMapSiges,anoCurricularIdMapSiges,numeroEstudante,numero_creditos:Int
let unidadeCurricularNome,unidadeCurricularAbreviatura:String
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let ff = UnidadeCurricularManager()
ff.getData { (res) in
print(res)
// refresh the table here
}
}
}
public class UnidadeCurricularManager{
func getData(completion:#escaping ([String:[Model]]) -> ()) {
let url = URL(string: "http://209.97.133.56/api/ucs")!
let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjQ2Yjg2ZDNlZDI2Y2IwOGU2NDFhZTI3NjNmMWI0ZDEwODAwZWI0M2U4YjM5MThiMTQ0YmU5YWFjMzBhNGU1ZDdhMTI4ZjA1MDI2NGNkYWZhIn0.eyJhdWQiOiIyIiwianRpIjoiNDZiODZkM2VkMjZjYjA4ZTY0MWFlMjc2M2YxYjRkMTA4MDBlYjQzZThiMzkxOGIxNDRiZTlhYWMzMGE0ZTVkN2ExMjhmMDUwMjY0Y2RhZmEiLCJpYXQiOjE1NTgzNDQ1MDIsIm5iZiI6MTU1ODM0NDUwMiwiZXhwIjoxNTg5OTY2OTAyLCJzdWIiOiIzIiwic2NvcGVzIjpbXX0.LSsn172WUQqEzUf3wzq4lxgBL8pbKGqjJCpn0iEFPFQY6DhZCtcm4jHkqTC0FFMYrAA1n87LfdBeSvcdgWFsndD6MoKHFkZViqZXlUHDeyMmT-bVs2IrNSE9kGuaRQhz1rtys2KFbB2y4lq5w2BPhokPYvLc0nTwZ7oPTZKQlJkUi80PKDMP3LMUQpilc2cSE8FGe-d1UtMYUeseivwHcNee4knjfOUIsGl7_pV4knU6DYTWL8IMXfb3GjbBTagFRWfbjeqMMvtFVdZGfTxdeVoMqSgEQlA0W20GyJ3Ox4WuZAaODk4b7Q4cudR8vmPTSjvVU-IqB6_9wvtE3HUMEwiGazQRcmFtVqBYFPVIBHFWNBsWI2AbMxR_KSA6URzF-6qydj53yRqO41E88KQiWbHy29mb8BCoNvjR4gN9F97rE9j9Xpt-EsHK6QEqBOeoJixu8srDrgmYul4nWroRU6dQsFZjfZS4Vnm1LFF-ykOo0YVY08oRcV3LQTb8TsnS3RuQzlMifEhDajBPTsVyCyW9OkkTsi3N96E1VeRhyT0S08InczXeRV_K5BMdt7tvVAEMPoR4GCcHAR5e7924WVsbl9KmJ4ituf_FdCfBKdvcmErURIlCfZRELLC_8kNaT-04CG3Vj9_LrUb6eOcJrutawh60V_ITojWAxyF2LnQ"
var request = URLRequest(url: url)
request.addValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.httpMethod = "GET"
URLSession.shared.dataTask(with: request) { (data, response , error) in
guard let data = data else {
return
}
// print(String(data:data,encoding: .utf8))
do {
let res = try JSONDecoder().decode(Root.self, from: data)
let dic = Dictionary(grouping: res.data, by: { String($0.anoCurricularIdMapSiges) })
completion(dic)
} catch let error as NSError {
print(error)
}
}.resume()
}
}
struct Root : Codable {
let data:[Model]
}
struct Model : Codable {
let unidadeCurricularIdMapSiges,anoCurricularIdMapSiges,numeroEstudante,numero_creditos:Int
let unidadeCurricularNome,unidadeCurricularAbreviatura:String
}
I am trying to post form-data using webservice, userName & password, but in response it's showing an error stating "Could not connect to the server.".
Please help me to send form data in the POST request.
let dict:[String:String] = ["userName": userName as! String, "password": password as! String]
do {
let jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
let url = URL(string: "(some url)")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if error != nil {
print(error!.localizedDescription)
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
let resultValue:String = parseJSON["success"] as! String;
print("result: \(resultValue)")
print(parseJSON)
}
} catch let error as NSError {
print(error)
}
}
task.resume()
} catch {
print(error.localizedDescription)
}
I've tried adding values in the request, may be some values are missing in the request formed. Please help!
Thats the POSTMAN response
my calling api class
class ApiService
{
static func getPostString(params:[String:Any]) -> String
{
var data = [String]()
for(key, value) in params
{
data.append(key + "=\(value)")
}
return data.map { String($0) }.joined(separator: "&")
}
static func callPost(url:URL, params:[String:Any], finish: #escaping ((message:String, data:Data?)) -> Void)
{
var request = URLRequest(url: url)
request.httpMethod = "POST"
let postString = self.getPostString(params: params)
request.httpBody = postString.data(using: .utf8)
var result:(message:String, data:Data?) = (message: "Fail", data: nil)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if(error != nil)
{
result.message = "Fail Error not null : \(error.debugDescription)"
}
else
{
result.message = "Success"
result.data = data
}
finish(result)
}
task.resume()
}
}
and when use it
ApiService.callPost(url: url, params: params, finish: finishPost)
and the finish function
func finishPost (message:String, data:Data?) -> Void
{
do
{
if let jsonData = data
{
let parsedData = try JSONDecoder().decode(Response.self, from: jsonData)
print(parsedData)
}
}
catch
{
print("Parse Error: \(error)")
}
}
I have tried the below REST Api with PUT method.
Here is my code,
let url = NSURL(string: "http://sampleurl")
let request = NSMutableURLRequest(URL: url!)
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "PUT"
let session = NSURLSession(configuration:NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: nil, delegateQueue: nil)
let params:[String: AnyObject] = ["deviceId" : "device_1","mobileDeviceId" : "abcd","deviceType":"ios"]
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions(), error: nil)
let dataTask = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
if error != nil {
//handle error
print("Parsed error: '\(error)'")
}
else {
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Parsed JSON: '\(jsonStr)'")
}
}
dataTask.resume()
It is not working. Please help me to find out where it is wrong.
This is a working code, I send your dictionary as a JSON formatted string to the server, and in the server, I parse the request and build another JSON object that contains the same values as the request, and send them back to the app. In the app, I parse the response and print the results:
let session = NSURLSession.sharedSession()
let url = "http://localhost:8080/yourServerGoesHere/putMethodTest"
let request = NSMutableURLRequest(URL: NSURL(string: url)!)
request.HTTPMethod = "PUT"
let params:[String: AnyObject] = ["deviceId" : "device_1","mobileDeviceId" : "abcd","deviceType":"ios"]
do{
request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions())
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if let response = response {
let nsHTTPResponse = response as! NSHTTPURLResponse
let statusCode = nsHTTPResponse.statusCode
print ("status code = \(statusCode)")
}
if let error = error {
print ("\(error)")
}
if let data = data {
do{
let jsonData = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions())
let deviceId = jsonData["deviceId"] as! String
let mobileDeviceId = jsonData["mobileDeviceId"] as! String
let deviceType = jsonData["deviceType"] as! String
print (" deviceId= \(deviceId), mobileDeviceId= \(mobileDeviceId), deviceType= \(deviceType)")
}catch _ {
print ("the response is not well JSON formatted")
}
}
})
task.resume()
}catch _ {
print ("Oops something happened buddy")
}
If you want to try, this is the Java web service code:
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
#Path("/putMethodTest")
#PUT
#Consumes(MediaType.TEXT_PLAIN)
public Response putMethodTest(String requestString) {
JSONObject requestJSON = new JSONObject(requestString);
String deviceId = requestJSON.getString("deviceId");
String mobileDeviceId = requestJSON.getString("mobileDeviceId");
String deviceType = requestJSON.getString("deviceType");
JSONObject response = new JSONObject();
response.put("deviceId", deviceId);
response.put("mobileDeviceId", mobileDeviceId);
response.put("deviceType", deviceType);
return Response.ok().entity(response.toString()).build();
}
Define the put function like this :
//
// Put request
//
static func put(path: String, accessToken: Bool, data: Dictionary<String, AnyObject>, finish: (accessTokenX:String, data: JSON) -> ()) {
apiRequest("PUT", path: path, accessToken: accessToken, contentType: nil, data: data) { (accessTokenX:String, data: AnyObject) in
dispatch_async(dispatch_get_main_queue(), {
finish(accessTokenX:accessTokenX, data: JSON(data))
})
}
}
An example of use :
//
// Update informations of the profile
//
static func accountUpdate(profile: [String: AnyObject], finish: (accessTokenX:String, data: JSON) -> ()) {
let dataProfile = ["profile": profile]
API.put("/users/profile", accessToken: true, data: dataProfile) { accessTokenX, data in finish(accessTokenX:accessTokenX, data: data)
}
}
Try this!!!
http://jamesonquave.com/blog/making-a-post-request-in-swift/
func data_request()
{
let url:NSURL = NSURL(string: url_to_request)!
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
let paramString = "data=Hello"
request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)
let task = session.dataTaskWithRequest(request) {
(
let data, let response, let error) in
guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
print("error")
return
}
let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print(dataString)
}
task.resume()
}
I'm trying to use Swift to make a GET call to a REST API, and have tried to follow numerous tutorials, but can't figure it out. Either because I cannot figure out how to translate all the Obj-C to Swift, or because half of the methods n' such are deprecated. Does anyone know how to make the call, and parse returned JSON data?
Swift 5 & 4
let params = ["username":"john", "password":"123456"] as Dictionary<String, String>
var request = URLRequest(url: URL(string: "http://localhost:8080/api/1/login")!)
request.httpMethod = "POST"
request.httpBody = try? JSONSerialization.data(withJSONObject: params, options: [])
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
print(response!)
do {
let json = try JSONSerialization.jsonObject(with: data!) as! Dictionary<String, AnyObject>
print(json)
} catch {
print("error")
}
})
task.resume()
You can do like this :
var url : String = "http://google.com?test=toto&test2=titi"
var request : NSMutableURLRequest = NSMutableURLRequest()
request.URL = NSURL(string: url)
request.HTTPMethod = "GET"
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: error) as? NSDictionary
if (jsonResult != nil) {
// process jsonResult
} else {
// couldn't load JSON, look at error
}
})
EDIT : For people have problem with this maybe your JSON stream is an
array [] and not an object {} so you have to change jsonResult to
NSArray instead of NSDictionary
I think the NSURLSession api fits better in this situation. Because if you write swift code your project target is at least iOS 7 and iOS 7 supports NSURLSession api. Anyway here is the code
let url = "YOUR_URL"
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)) { data, response, error in
// Handle result
}.resume()
Here is the complete code for REST API requests using NSURLSession in swift
For GET Request
let configuration = NSURLSessionConfiguration .defaultSessionConfiguration()
let session = NSURLSession(configuration: configuration)
let urlString = NSString(format: "your URL here")
print("get wallet balance url string is \(urlString)")
//let url = NSURL(string: urlString as String)
let request : NSMutableURLRequest = NSMutableURLRequest()
request.URL = NSURL(string: NSString(format: "%#", urlString) as String)
request.HTTPMethod = "GET"
request.timeoutInterval = 30
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let dataTask = session.dataTaskWithRequest(request) {
(let data: NSData?, let response: NSURLResponse?, let error: NSError?) -> Void in
// 1: Check HTTP Response for successful GET request
guard let httpResponse = response as? NSHTTPURLResponse, receivedData = data
else {
print("error: not a valid http response")
return
}
switch (httpResponse.statusCode)
{
case 200:
let response = NSString (data: receivedData, encoding: NSUTF8StringEncoding)
print("response is \(response)")
do {
let getResponse = try NSJSONSerialization.JSONObjectWithData(receivedData, options: .AllowFragments)
EZLoadingActivity .hide()
// }
} catch {
print("error serializing JSON: \(error)")
}
break
case 400:
break
default:
print("wallet GET request got response \(httpResponse.statusCode)")
}
}
dataTask.resume()
For POST request ...
let configuration = NSURLSessionConfiguration .defaultSessionConfiguration()
let session = NSURLSession(configuration: configuration)
let params = ["username":bindings .objectForKey("username"), "provider":"walkingcoin", "securityQuestion":securityQuestionField.text!, "securityAnswer":securityAnswerField.text!] as Dictionary<String, AnyObject>
let urlString = NSString(format: “your URL”);
print("url string is \(urlString)")
let request : NSMutableURLRequest = NSMutableURLRequest()
request.URL = NSURL(string: NSString(format: "%#", urlString)as String)
request.HTTPMethod = "POST"
request.timeoutInterval = 30
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(params, options: [])
let dataTask = session.dataTaskWithRequest(request)
{
(let data: NSData?, let response: NSURLResponse?, let error: NSError?) -> Void in
// 1: Check HTTP Response for successful GET request
guard let httpResponse = response as? NSHTTPURLResponse, receivedData = data
else {
print("error: not a valid http response")
return
}
switch (httpResponse.statusCode)
{
case 200:
let response = NSString (data: receivedData, encoding: NSUTF8StringEncoding)
if response == "SUCCESS"
{
}
default:
print("save profile POST request got response \(httpResponse.statusCode)")
}
}
dataTask.resume()
I hope it works.
edited for swift 2
let url = NSURL(string: "http://www.test.com")
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
print(NSString(data: data!, encoding: NSUTF8StringEncoding))
}
task.resume()
Swift 4 - GET request
var request = URLRequest(url: URL(string: "http://example.com/api/v1/example")!)
request.httpMethod = "GET"
URLSession.shared.dataTask(with: request, completionHandler: { data, response, error -> Void in
do {
let jsonDecoder = JSONDecoder()
let responseModel = try jsonDecoder.decode(CustomDtoClass.self, from: data!)
print(responseModel)
} catch {
print("JSON Serialization error")
}
}).resume()
Don't forget to configure App Transport Security Settings to add your domain to the exceptions and allow insecure http requests if you're hitting endpoints without using HTTPS.
You can use a tool like http://www.json4swift.com/ to autogenerate your Codeable Mappings from your JSON responses.
In swift 3.3 and 4. I crated APIManager class with two public methods. Just pass required parameter, api name and request type. You will get response then pass it to the closure.
import UIKit
struct RequestType {
static let POST = "POST"
static let GET = "GET"
}
enum HtttpType: String {
case POST = "POST"
case GET = "GET"
}
class APIManager: NSObject {
static let sharedInstance: APIManager = {
let instance = APIManager()
return instance
}()
private init() {}
// First Method
public func requestApiWithDictParam(dictParam: Dictionary<String,Any>, apiName: String,requestType: String, isAddCookie: Bool, completionHendler:#escaping (_ response:Dictionary<String,AnyObject>?, _ error: NSError?, _ success: Bool)-> Void) {
var apiUrl = “” // Your api url
apiUrl = apiUrl.appendingFormat("%#", apiName)
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let url = URL(string: apiUrl)!
let HTTPHeaderField_ContentType = "Content-Type"
let ContentType_ApplicationJson = "application/json"
var request = URLRequest.init(url: url)
request.timeoutInterval = 60.0
request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalCacheData
request.addValue(ContentType_ApplicationJson, forHTTPHeaderField: HTTPHeaderField_ContentType)
request.httpMethod = requestType
print(apiUrl)
print(dictParam)
let dataTask = session.dataTask(with: request) { (data, response, error) in
if error != nil {
completionHendler(nil, error as NSError?, false)
} do {
let resultJson = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:AnyObject]
print("Request API = ", apiUrl)
print("API Response = ",resultJson ?? "")
completionHendler(resultJson, nil, true)
} catch {
completionHendler(nil, error as NSError?, false)
}
}
dataTask.resume()
}
// Second Method
public func requestApiWithUrlString(param: String, apiName: String,requestType: String, isAddCookie: Bool, completionHendler:#escaping (_ response:Dictionary<String,AnyObject>?, _ error: NSError?, _ success: Bool)-> Void ) {
var apiUrl = "" // Your api url
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
var request: URLRequest?
if requestType == "GET" {
apiUrl = String(format: "%#%#&%#", YourAppBaseUrl,apiName,param)
apiUrl = apiUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
print("URL=",apiUrl)
let url = URL(string: apiUrl)!
request = URLRequest.init(url: url)
request?.httpMethod = "GET"
} else {
apiUrl = String(format: "%#%#", YourAppBaseUrl,apiName)
apiUrl = apiUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
print("URL=",apiUrl)
let bodyParameterData = param.data(using: .utf8)
let url = URL(string: apiUrl)!
request = URLRequest(url: url)
request?.httpBody = bodyParameterData
request?.httpMethod = "POST"
}
request?.timeoutInterval = 60.0
request?.cachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalCacheData
request?.httpShouldHandleCookies = true
let dataTask = session.dataTask(with: request!) { (data, response, error) in
if error != nil {
completionHendler(nil, error as NSError?, false)
} do {
if data != nil {
let resultJson = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:AnyObject]
print("Request API = ", apiUrl)
print("API Response = ",resultJson ?? "")
completionHendler(resultJson, nil, true)
} else {
completionHendler(nil, error as NSError?, false)
}
} catch {
completionHendler(nil, error as NSError?, false)
}
}
dataTask.resume()
}
}
// Here is example of calling Post API from any class
let bodyParameters = String(format: "appid=%#&appversion=%#","1","1")
APIManager.sharedInstance.requestApiWithUrlString(param: bodyParameters, apiName: "PASS_API_NAME", requestType: HtttpType.POST.rawValue, isAddCookie: false) { (dictResponse, error, success) in
if success {
if let dictMessage = dictResponse?["message"] as? Dictionary<String, AnyObject> {
// do you work
}
} else {
print("Something went wrong...")
}
}
}
/// Or just use simple function
func dataRequest() {
let urlToRequest = "" // Your API url
let url = URL(string: urlToRequest)!
let session4 = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "POST"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
let paramString = "data=Hello"
request.httpBody = paramString.data(using: String.Encoding.utf8)
let task = session4.dataTask(with: request as URLRequest) { (data, response, error) in
guard let _: Data = data, let _: URLResponse = response, error == nil else {
print("*****error")
return
}
if let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue) {
print("****Data: \(dataString)") //JSONSerialization
}
}
task.resume()
}
Swift 3.0
let request = NSMutableURLRequest(url: NSURL(string: "http://httpstat.us/200")! as URL)
let session = URLSession.shared
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = session.dataTask(with: request as URLRequest, completionHandler: {data, response, error -> Void in
if error != nil {
print("Error: \(String(describing: error))")
} else {
print("Response: \(String(describing: response))")
}
})
task.resume()
Swift 4
Create an app using Alamofire with Api Post method
Install pod file -pod 'Alamofire', '~> 4.0' for Swift 3 with Xcode 9
Create Webservices.swift class, import Alamofire
Design storyBoard ,Login View
insert following Code for the ViewControllerClass
import UIKit
class ViewController: UIViewController {
#IBOutlet var usernameTextField: UITextField!
#IBOutlet var passwordTextField: UITextField!
var usertypeStr :String = "-----------"
var loginDictionary : NSDictionary?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func loginButtonClicked(_ sender: Any) {
WebServices.userLogin(userName: usernameTextField.text!, password: passwordTextField.text!,userType: usertypeStr) {(result, message, status )in
if status {
let loginDetails = result as? WebServices
self.loginDictionary = loginDetails?.loginData
if self.loginDictionary?["status"] as? String == "error"
{
self.alertMessage(alerttitle: "Login Error", (self.loginDictionary?["message"] as? String)!)
} else if self.loginDictionary?["status"] as? String == "ok" {
self.alertMessage(alerttitle: "", "Success")
}else {
self.alertMessage(alerttitle: "", (self.loginDictionary?["message"] as? String)!)
}
} else {
self.alertMessage(alerttitle: "", "Sorry")
}
}
}
func alertMessage(alerttitle:String,_ message : String){
let alertViewController = UIAlertController(title:alerttitle, message:message, preferredStyle: .alert)
alertViewController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alertViewController, animated: true, completion: nil)
}
}
Insert Following Code For WebserviceClass
import Foundation
import Alamofire
class WebServices: NSObject {
enum WebServiceNames: String {
case baseUrl = "https://---------------"
case UserLogin = "------------"
}
// MARK: - Login Variables
var loginData : NSDictionary?
class func userLogin(userName: String,password : String,userType : String, completion : #escaping (_ response : AnyObject?, _ message: String?, _ success : Bool)-> ()) {
let url = WebServiceNames.baseUrl.rawValue + WebServiceNames.UserLogin.rawValue
let params = ["USER": userName,"PASS":password,"API_Key" : userType]
WebServices.postWebService(urlString: url, params: params as [String : AnyObject]) { (response, message, status) in
print(response ?? "Error")
let result = WebServices()
if let data = response as? NSDictionary {
print(data)
result.loginData = data
completion(result, "Success", true)
}else {
completion("" as AnyObject?, "Failed", false)
}
}
}
//MARK :- Post
class func postWebService(urlString: String, params: [String : AnyObject], completion : #escaping (_ response : AnyObject?, _ message: String?, _ success : Bool)-> Void) {
alamofireFunction(urlString: urlString, method: .post, paramters: params) { (response, message, success) in
if response != nil {
completion(response as AnyObject?, "", true)
}else{
completion(nil, "", false)
}
}
}
class func alamofireFunction(urlString : String, method : Alamofire.HTTPMethod, paramters : [String : AnyObject], completion : #escaping (_ response : AnyObject?, _ message: String?, _ success : Bool)-> Void){
if method == Alamofire.HTTPMethod.post {
Alamofire.request(urlString, method: .post, parameters: paramters, encoding: URLEncoding.default, headers: nil).responseJSON { (response:DataResponse<Any>) in
print(urlString)
if response.result.isSuccess{
completion(response.result.value as AnyObject?, "", true)
}else{
completion(nil, "", false)
}
}
}else {
Alamofire.request(urlString).responseJSON { (response) in
if response.result.isSuccess{
completion(response.result.value as AnyObject?, "", true)
}else{
completion(nil, "", false)
}
}
}
}
//Mark:-Cancel
class func cancelAllRequests()
{
Alamofire.SessionManager.default.session.getTasksWithCompletionHandler { dataTasks, uploadTasks, downloadTasks in
dataTasks.forEach { $0.cancel() }
uploadTasks.forEach { $0.cancel() }
downloadTasks.forEach { $0.cancel() }
}
}
}
swift 4
USE ALAMOFIRE in our App plz install pod file
pod 'Alamofire', '~> 4.0'
We can Use API for Json Data -https://swapi.co/api/people/
Then We can create A networking class for Our project- networkingService.swift
import Foundation
import Alamofire
typealias JSON = [String:Any]
class networkingService{
static let shared = networkingService()
private init() {}
func getPeople(success successblock: #escaping (GetPeopleResponse) -> Void)
{
Alamofire.request("https://swapi.co/api/people/").responseJSON { response in
guard let json = response.result.value as? JSON else {return}
// print(json)
do {
let getPeopleResponse = try GetPeopleResponse(json: json)
successblock(getPeopleResponse)
}catch{}
}
}
func getHomeWorld(homeWorldLink:String,completion: #escaping(String) ->Void){
Alamofire.request(homeWorldLink).responseJSON {(response) in
guard let json = response.result.value as? JSON,
let name = json["name"] as? String
else{return}
completion(name)
}
}
}
Then Create NetworkingError.swift class
import Foundation
enum networkingError : Error{
case badNetworkigStuff
}
Then create Person.swift class
import Foundation
struct Person {
private let homeWorldLink : String
let birthyear : String
let gender : String
let haircolor : String
let eyecolor : String
let height : String
let mass : String
let name : String
let skincolor : String
init?(json : JSON) {
guard let birthyear = json["birth_year"] as? String,
let eyecolor = json["eye_color"] as? String,
let gender = json["gender"] as? String,
let haircolor = json["hair_color"] as? String,
let height = json["height"] as? String,
let homeWorldLink = json["homeworld"] as? String,
let mass = json["mass"] as? String,
let name = json["name"] as? String,
let skincolor = json["skin_color"] as? String
else { return nil }
self.homeWorldLink = homeWorldLink
self.birthyear = birthyear
self.gender = gender
self.haircolor = haircolor
self.eyecolor = eyecolor
self.height = height
self.mass = mass
self.name = name
self.skincolor = skincolor
}
func homeWorld(_ completion: #escaping (String) -> Void) {
networkingService.shared.getHomeWorld(homeWorldLink: homeWorldLink){ (homeWorld) in
completion(homeWorld)
}
}
}
Then create DetailVC.swift
import UIKit
class DetailVC: UIViewController {
var person :Person!
#IBOutlet var name: UILabel!
#IBOutlet var birthyear: UILabel!
#IBOutlet var homeworld: UILabel!
#IBOutlet var eyeColor: UILabel!
#IBOutlet var skinColor: UILabel!
#IBOutlet var gender: UILabel!
#IBOutlet var hairColor: UILabel!
#IBOutlet var mass: UILabel!
#IBOutlet var height: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
print(person)
name.text = person.name
birthyear.text = person.birthyear
eyeColor.text = person.eyecolor
gender.text = person.gender
hairColor.text = person.haircolor
mass.text = person.mass
height.text = person.height
skinColor.text = person.skincolor
person.homeWorld{(homeWorld) in
self.homeworld.text = homeWorld
}
}
}
Then Create GetPeopleResponse.swift class
import Foundation
struct GetPeopleResponse {
let people : [Person]
init(json :JSON) throws {
guard let results = json["results"] as? [JSON] else { throw networkingError.badNetworkigStuff}
let people = results.map{Person(json: $0)}.flatMap{ $0 }
self.people = people
}
}
Then Our View controller class
import UIKit
class ViewController: UIViewController {
#IBOutlet var tableVieww: UITableView!
var people = [Person]()
#IBAction func getAction(_ sender: Any)
{
print("GET")
networkingService.shared.getPeople{ response in
self.people = response.people
self.tableVieww.reloadData()
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
guard segue.identifier == "peopleToDetails",
let detailVC = segue.destination as? DetailVC,
let person = sender as AnyObject as? Person
else {return}
detailVC.person = person
}
}
extension ViewController:UITableViewDataSource{
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return people.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = people[indexPath.row].name
return cell
}
}
extension ViewController:UITableViewDelegate{
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "peopleToDetails", sender: people[indexPath.row])
}
}
In our StoryBoard
plz Connect with our View with another one using segue with identifier -peopleToDetails
Use UITableView In our First View
Use UIButton For get the Data
Use 9 Labels in our DetailVc
Very simple 100% working , tested
var url : String = "https://restcountries.eu/rest/v2/all"
URLSession.shared.dataTask(with: NSURL(string: url) as! URL) { data, response, error in
// Handle result
let response = String (data: data!, encoding: String.Encoding.utf8)
print("response is \(response)")
do {
let getResponse = try JSONSerialization.jsonObject(with: data!, options: .allowFragments)
print(getResponse)
let countryArray = getResponse as! NSArray
print(countryArray)
let country1 = countryArray[0] as! [String:Any]
let name = country1["name"] as! String
print(name)
} catch {
print("error serializing JSON: \(error)")
}
}.resume()
}
If you're working in Swift 3, the syntax changes. The example here worked for me and has a good explanation of the steps: https://grokswift.com/simple-rest-with-swift/
This is the code from that tutorial:
let todoEndpoint: String = "https://jsonplaceholder.typicode.com/todos/1"
guard let url = URL(string: todoEndpoint) else {
print("Error: cannot create URL")
return
}
let urlRequest = URLRequest(url: url)
let task = session.dataTask(with: urlRequest) {
(data, response, error) in
// check for any errors
guard error == nil else {
print("error calling GET on /todos/1")
print(error!)
return
}
// make sure we got data
guard let responseData = data else {
print("Error: did not receive data")
return
}
// parse the result as JSON, since that's what the API provides
do {
guard let todo = try JSONSerialization.jsonObject(with: responseData, options: [])
as? [String: Any] else {
print("error trying to convert data to JSON")
return
}
// now we have the todo
// let's just print it to prove we can access it
print("The todo is: " + todo.description)
// the todo object is a dictionary
// so we just access the title using the "title" key
// so check for a title and print it if we have one
guard let todoTitle = todo["title"] as? String else {
print("Could not get todo title from JSON")
return
}
print("The title is: " + todoTitle)
} catch {
print("error trying to convert data to JSON")
return
}
}
task.resume()
Swift 5
API call method
//Send Request with ResultType<Success, Error>
func fetch(requestURL:URL,requestType:String,parameter:[String:AnyObject]?,completion:#escaping (Result<Any>) -> () ){
//Check internet connection as per your convenience
//Check URL whitespace validation as per your convenience
//Show Hud
var urlRequest = URLRequest.init(url: requestURL)
urlRequest.cachePolicy = .reloadIgnoringLocalCacheData
urlRequest.timeoutInterval = 60
urlRequest.httpMethod = String(describing: requestType)
urlRequest.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
urlRequest.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept")
//Post URL parameters set as URL body
if let params = parameter{
do{
let parameterData = try JSONSerialization.data(withJSONObject:params, options:.prettyPrinted)
urlRequest.httpBody = parameterData
}catch{
//Hide hude and return error
completion(.failure(error))
}
}
//URL Task to get data
URLSession.shared.dataTask(with: requestURL) { (data, response, error) in
//Hide Hud
//fail completion for Error
if let objError = error{
completion(.failure(objError))
}
//Validate for blank data and URL response status code
if let objData = data,let objURLResponse = response as? HTTPURLResponse{
//We have data validate for JSON and convert in JSON
do{
let objResposeJSON = try JSONSerialization.jsonObject(with: objData, options: .mutableContainers)
//Check for valid status code 200 else fail with error
if objURLResponse.statusCode == 200{
completion(.success(objResposeJSON))
}
}catch{
completion(.failure(error))
}
}
}.resume()
}
Use of API call method
func useOfAPIRequest(){
if let baseGETURL = URL(string:"https://postman-echo.com/get?foo1=bar1&foo2=bar2"){
self.fetch(requestURL: baseGETURL, requestType: "GET", parameter: nil) { (result) in
switch result{
case .success(let response) :
print("Hello World \(response)")
case .failure(let error) :
print("Hello World \(error)")
}
}
}
}
Api Call using Model Class
let urlString = "http://--.154.--.78/------/index.php?route=api/coupon/all"
let url = URL(string: urlString)
var request = URLRequest(url: url!)
request.httpMethod = "GET"
URLSession.shared.dataTask(with:request) { (data, response, error) in
if error != nil {
print(error)
} else {
do {
let parsedDictionaryArray = try JSONSerialization.jsonObject(with: data!) as! [String:AnyObject]
print(parsedDictionaryArray)
if let arry = parsedDictionaryArray["data"] as? [[String:AnyObject]] {
for dic in arry {
let name = dic["name"]
let descriptionData = dic["description"]
self.modelReference.append(model(name: name as! String, descriptionStr: descriptionData as! String))
print(name!)
}
}
} catch let error as NSError {
print(error)
}
}
}.resume()
create a variable and connect with model class
var modelReference = [model]()
create a model class New -> swift class
import Foundation
class model : NSObject{
var name : String
var descriptionStr: String
init(name : String, descriptionStr: String)
{
self.name = name
self.descriptionStr = descriptionStr
}
}
then we can connect with our table view objects
let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCellID")as! TableViewCell
cell.listName.text = modelReference[indexPath.row].name
let headers = [
"cache-control": "no-cache",
"postman-token": "6f8a-12c6-87a1-ac0f25d6385a"
]
let request = NSMutableURLRequest(url: NSURL(string: "Your url string")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if error == nil && data != nil {
do {
// Convert NSData to Dictionary where keys are of type String, and values are of any type
let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:AnyObject]
print(json)
//do your stuff
// completionHandler(true)
} catch {
// completionHandler(false)
}
}
else if error != nil
{
//completionHandler(false)
}
}).resume()
}
func getAPICalling(mainUrl:String) {
//create URL
guard let url = URL(string: mainUrl) else {
print("Error: cannot create URL")
return
}
//create request
let urlRequest = URLRequest(url: url)
// create the session
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
// make the request
let task = session.dataTask(with: urlRequest) {
(data, response, error) in
// check for any errors
guard error == nil else {
print("error calling GET")
print(error!.localizedDescription)
return
}
// make sure we got data
guard let responseData = data else {
print("error: did not receive data")
return
}
// convert Data in JSON && parse the result as JSON, since that's what the API provides
do {
guard let object = try JSONSerialization.jsonObject(with: responseData, options: [])
as? [String: Any] else {
print("error trying to convert data to JSON")
return
}
//JSON Response
guard let todoTitle = object["response"] as? NSDictionary else {
print("Could not get todo title from JSON")
return
}
//Get array in response
let responseList = todoTitle.value(forKey: "radioList") as! NSArray
for item in responseList {
let dic = item as! NSDictionary
let str = dic.value(forKey: "radio_des") as! String
self.arrName.append(str)
print(item)
}
DispatchQueue.main.async {
self.tblView.reloadData()
}
} catch {
print("error trying to convert data to JSON")
return
}
}
task.resume()
}
Usage:
getAPICalling(mainUrl:"https://dousic.com/api/radiolist?user_id=16")
class ApiManager: NSObject {
static func callGetDataApi(url: String,completion: #escaping([[String: Any]])-> Void) {
guard let url = URL(string: ApiName.baseUrl+url ) else { return }
var request = URLRequest(url: url)
request.httpMethod = "GET"
URLSession.shared.dataTask(with:request) { (data, response, error) in
if error != nil {
print(error ?? "")
} else {
do {
let arry = try JSONSerialization.jsonObject(with: data!) as! [[String:AnyObject]]
print(arry)
DispatchQueue.main.async {
completion(arry)
}
} catch let error as NSError {
print(error)
}
}
}.resume()
}
}
I read The Programming Language Swift by Apple in iBooks, but cannot figure out how to make an HTTP request (something like cURL) in Swift. Do I need to import Obj-C classes or do I just need to import default libraries? Or is it not possible to make an HTTP request based on native Swift code?
You can use URL, URLRequest and URLSession or NSURLConnection as you'd normally do in Objective-C. Note that for iOS 7.0 and later, URLSession is preferred.
Using URLSession
Initialize a URL object and a URLSessionDataTask from URLSession. Then run the task with resume().
let url = URL(string: "http://www.stackoverflow.com")!
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
guard let data = data else { return }
print(String(data: data, encoding: .utf8)!)
}
task.resume()
Using NSURLConnection
First, initialize a URL and a URLRequest:
let url = URL(string: "http://www.stackoverflow.com")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
Then, you can load the request asynchronously with:
NSURLConnection.sendAsynchronousRequest(request, queue: OperationQueue.main) {(response, data, error) in
guard let data = data else { return }
print(String(data: data, encoding: .utf8)!)
}
Or you can initialize an NSURLConnection:
let connection = NSURLConnection(request: request, delegate:nil, startImmediately: true)
Just make sure to set your delegate to something other than nil and use the delegate methods to work with the response and data received.
For more detail, check the documentation for the NSURLConnectionDataDelegate protocol
Testing on an Xcode playground
If you want to try this code on a Xcode playground, add import PlaygroundSupport to your playground, as well as the following call:
PlaygroundPage.current.needsIndefiniteExecution = true
This will allow you to use asynchronous code in playgrounds.
Check Below Codes :
1. SynchonousRequest
Swift 1.2
let urlPath: String = "YOUR_URL_HERE"
var url: NSURL = NSURL(string: urlPath)!
var request1: NSURLRequest = NSURLRequest(URL: url)
var response: AutoreleasingUnsafeMutablePointer<NSURLResponse?>=nil
var dataVal: NSData = NSURLConnection.sendSynchronousRequest(request1, returningResponse: response, error:nil)!
var err: NSError
println(response)
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataVal, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary
println("Synchronous\(jsonResult)")
Swift 2.0 +
let urlPath: String = "YOUR_URL_HERE"
let url: NSURL = NSURL(string: urlPath)!
let request1: NSURLRequest = NSURLRequest(URL: url)
let response: AutoreleasingUnsafeMutablePointer<NSURLResponse?>=nil
do{
let dataVal = try NSURLConnection.sendSynchronousRequest(request1, returningResponse: response)
print(response)
do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(dataVal, options: []) as? NSDictionary {
print("Synchronous\(jsonResult)")
}
} catch let error as NSError {
print(error.localizedDescription)
}
}catch let error as NSError
{
print(error.localizedDescription)
}
2. AsynchonousRequest
Swift 1.2
let urlPath: String = "YOUR_URL_HERE"
var url: NSURL = NSURL(string: urlPath)!
var request1: NSURLRequest = NSURLRequest(URL: url)
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var err: NSError
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
println("Asynchronous\(jsonResult)")
})
Swift 2.0 +
let urlPath: String = "YOUR_URL_HERE"
let url: NSURL = NSURL(string: urlPath)!
let request1: NSURLRequest = NSURLRequest(URL: url)
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse?, data: NSData?, error: NSError?) -> Void in
do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
print("ASynchronous\(jsonResult)")
}
} catch let error as NSError {
print(error.localizedDescription)
}
})
3. As usual URL connection
Swift 1.2
var dataVal = NSMutableData()
let urlPath: String = "YOUR URL HERE"
var url: NSURL = NSURL(string: urlPath)!
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: true)!
connection.start()
Then
func connection(connection: NSURLConnection!, didReceiveData data: NSData!){
self.dataVal?.appendData(data)
}
func connectionDidFinishLoading(connection: NSURLConnection!)
{
var error: NSErrorPointer=nil
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataVal!, options: NSJSONReadingOptions.MutableContainers, error: error) as NSDictionary
println(jsonResult)
}
Swift 2.0 +
var dataVal = NSMutableData()
let urlPath: String = "YOUR URL HERE"
var url: NSURL = NSURL(string: urlPath)!
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: true)!
connection.start()
Then
func connection(connection: NSURLConnection!, didReceiveData data: NSData!){
dataVal.appendData(data)
}
func connectionDidFinishLoading(connection: NSURLConnection!)
{
do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(dataVal, options: []) as? NSDictionary {
print(jsonResult)
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
4. Asynchonous POST Request
Swift 1.2
let urlPath: String = "YOUR URL HERE"
var url: NSURL = NSURL(string: urlPath)!
var request1: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request1.HTTPMethod = "POST"
var stringPost="deviceToken=123456" // Key and Value
let data = stringPost.dataUsingEncoding(NSUTF8StringEncoding)
request1.timeoutInterval = 60
request1.HTTPBody=data
request1.HTTPShouldHandleCookies=false
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var err: NSError
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
println("AsSynchronous\(jsonResult)")
})
Swift 2.0 +
let urlPath: String = "YOUR URL HERE"
let url: NSURL = NSURL(string: urlPath)!
let request1: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request1.HTTPMethod = "POST"
let stringPost="deviceToken=123456" // Key and Value
let data = stringPost.dataUsingEncoding(NSUTF8StringEncoding)
request1.timeoutInterval = 60
request1.HTTPBody=data
request1.HTTPShouldHandleCookies=false
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse?, data: NSData?, error: NSError?) -> Void in
do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
print("ASynchronous\(jsonResult)")
}
} catch let error as NSError {
print(error.localizedDescription)
}
})
5. Asynchonous GET Request
Swift 1.2
let urlPath: String = "YOUR URL HERE"
var url: NSURL = NSURL(string: urlPath)!
var request1: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request1.HTTPMethod = "GET"
request1.timeoutInterval = 60
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var err: NSError
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
println("AsSynchronous\(jsonResult)")
})
Swift 2.0 +
let urlPath: String = "YOUR URL HERE"
let url: NSURL = NSURL(string: urlPath)!
let request1: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request1.HTTPMethod = "GET"
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse?, data: NSData?, error: NSError?) -> Void in
do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
print("ASynchronous\(jsonResult)")
}
} catch let error as NSError {
print(error.localizedDescription)
}
})
6. Image(File) Upload
Swift 2.0 +
let mainURL = "YOUR_URL_HERE"
let url = NSURL(string: mainURL)
let request = NSMutableURLRequest(URL: url!)
let boundary = "78876565564454554547676"
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST" // POST OR PUT What you want
let session = NSURLSession(configuration:NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: nil, delegateQueue: nil)
let imageData = UIImageJPEGRepresentation(UIImage(named: "Test.jpeg")!, 1)
var body = NSMutableData()
body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
// Append your parameters
body.appendData("Content-Disposition: form-data; name=\"name\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("PREMKUMAR\r\n".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)
body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition: form-data; name=\"description\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("IOS_DEVELOPER\r\n".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)
body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
// Append your Image/File Data
var imageNameval = "HELLO.jpg"
body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition: form-data; name=\"profile_photo\"; filename=\"\(imageNameval)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Type: image/jpeg\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(imageData!)
body.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
request.HTTPBody = body
let dataTask = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
if error != nil {
//handle error
}
else {
let outputString : NSString = NSString(data:data!, encoding:NSUTF8StringEncoding)!
print("Response:\(outputString)")
}
}
dataTask.resume()
Another option is the Alamofire lib that offers Chainable Request / Response methods.
https://github.com/Alamofire/Alamofire
Making a Request
import Alamofire
Alamofire.request(.GET, "http://httpbin.org/get")
Response Handling
Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
.response { request, response, data, error in
print(request)
print(response)
print(error)
}
Swift 4 and above : Data Request using URLSession API
// create the url
let url = URL(string: "https://jsonplaceholder.typicode.com/todos/1")! //change the url
// create the session object
let session = URLSession.shared
// now create the URLRequest object using the url object
let request = URLRequest(url: url)
// create dataTask using the session object to send data to the server
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 {
//create json object from data
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
print(json)
}
} catch let error {
print(error.localizedDescription)
}
})
task.resume()
Swift 4 and above, Decodable and Result enum
// APIError enum which shows all possible Network errors
enum APIError: Error {
case networkError(Error)
case dataNotFound
case jsonParsingError(Error)
case invalidStatusCode(Int)
case badURL(String)
}
// Result enum to show success or failure
enum Result<T> {
case success(T)
case failure(AppError)
}
// dataRequest which sends request to given URL and convert to Decodable Object
func dataRequest<T: Decodable>(with url: String, objectType: T.Type, completion: #escaping (Result<T>) -> Void) {
// create the url with NSURL
guard let dataURL = URL(string: url) else {
completion(.failure(APIError.badURL(url))
return
}
// create the session object
let session = URLSession.shared
// now create the URLRequest object using the url object
let request = URLRequest(url: dataURL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60)
// create dataTask using the session object to send data to the server
let task = session.dataTask(with: request, completionHandler: { data, response, error in
guard error == nil else {
completion(Result.failure(APIError.networkError(error!)))
return
}
guard let data = data else {
completion(Result.failure(AppError.dataNotFound))
return
}
do {
// create decodable object from data
let decodedObject = try JSONDecoder().decode(objectType.self, from: data)
completion(Result.success(decodedObject))
} catch let error {
completion(Result.failure(APIError.jsonParsingError(error as! DecodingError)))
}
})
task.resume()
}
example:
//if we want to fetch todo from placeholder API, then we define the ToDo struct and call dataRequest and pass "https://jsonplaceholder.typicode.com/todos/1" string url.
struct ToDo: Decodable {
let id: Int
let userId: Int
let title: String
let completed: Bool
}
dataRequest(with: "https://jsonplaceholder.typicode.com/todos/1", objectType: ToDo.self) { (result: Result) in
switch result {
case .success(let object):
print(object)
case .failure(let error):
print(error)
}
}
// this prints the result:
ToDo(id: 1, userId: 1, title: "delectus aut autem", completed: false)
Basic Swift 3+ Solution
guard let url = URL(string: "http://www.stackoverflow.com") else { return }
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else { return }
print(NSString(data: data, encoding: String.Encoding.utf8.rawValue))
}
task.resume()
Using URLSession + Swift 5
Just adding to cezar's answer, if you want to make web request using Apple's URLSession class, there are multiple way to do the task
Simple GET Request with URL
Simple GET Request with URL and Parameters
Simple GET Request with URL with Error Handlings
Simple POST Request with URL, Parameters with Error Handlings
1. Simple GET Request with URL
func simpleGetUrlRequest()
{
let url = URL(string: "https://httpbin.org/get")!
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
guard let data = data else { return }
print("The response is : ",String(data: data, encoding: .utf8)!)
//print(NSString(data: data, encoding: String.Encoding.utf8.rawValue) as Any)
}
task.resume()
}
Note : Make sure You must add "NSAppTransportSecurity" key in pList for http requests
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
2. Simple GET Request with URL and Parameters
func simpleGetUrlWithParamRequest()
{
let url = URL(string: "https://www.google.com/search?q=peace")!
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
if error != nil || data == nil {
print("Client error!")
return
}
guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
print("Server error!")
return
}
print("The Response is : ",response)
}
task.resume()
}
3. Simple GET Request with URL with Error Handlings
func simpleGetUrlRequestWithErrorHandling()
{
let session = URLSession.shared
let url = URL(string: "https://httpbin.org/get")!
let task = session.dataTask(with: url) { data, response, error in
if error != nil || data == nil {
print("Client error!")
return
}
guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
print("Server error!")
return
}
guard let mime = response.mimeType, mime == "application/json" else {
print("Wrong MIME type!")
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: [])
print("The Response is : ",json)
} catch {
print("JSON error: \(error.localizedDescription)")
}
}
task.resume()
}
4. Simple POST Request with URL, Parameters with Error Handlings.
func simplePostRequestWithParamsAndErrorHandling(){
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 30
configuration.timeoutIntervalForResource = 30
let session = URLSession(configuration: configuration)
let url = URL(string: "https://httpbin.org/post")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let parameters = ["username": "foo", "password": "123456"]
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
} catch let error {
print(error.localizedDescription)
}
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
if error != nil || data == nil {
print("Client error!")
return
}
guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
print("Oops!! there is server error!")
return
}
guard let mime = response.mimeType, mime == "application/json" else {
print("response is not json")
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: [])
print("The Response is : ",json)
} catch {
print("JSON error: \(error.localizedDescription)")
}
})
task.resume()
}
Your suggestions are appreciated!!
Swift 3.0
Through a small abstraction
https://github.com/daltoniam/swiftHTTP
Example
do {
let opt = try HTTP.GET("https://google.com")
opt.start { response in
if let err = response.error {
print("error: \(err.localizedDescription)")
return //also notify app of failure as needed
}
print("opt finished: \(response.description)")
//print("data is: \(response.data)") access the response of the data with response.data
}
} catch let error {
print("got an error creating the request: \(error)")
}
Details
Xcode 9.2, Swift 4
Xcode 10.2.1 (10E1001), Swift 5
Info.plist
NSAppTransportSecurity
Add to the info plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Alamofire Sample
Alamofire
import Alamofire
class AlamofireDataManager {
fileprivate let queue: DispatchQueue
init(queue: DispatchQueue) { self.queue = queue }
private func createError(message: String, code: Int) -> Error {
return NSError(domain: "dataManager", code: code, userInfo: ["message": message ])
}
private func make(session: URLSession = URLSession.shared, request: URLRequest, closure: ((Result<[String: Any]>) -> Void)?) {
Alamofire.request(request).responseJSON { response in
let complete: (Result<[String: Any]>) ->() = { result in DispatchQueue.main.async { closure?(result) } }
switch response.result {
case .success(let value): complete(.success(value as! [String: Any]))
case .failure(let error): complete(.failure(error))
}
}
}
func searchRequest(term: String, closure: ((Result<[String: Any]>) -> Void)?) {
guard let url = URL(string: "https://itunes.apple.com/search?term=\(term.replacingOccurrences(of: " ", with: "+"))") else { return }
let request = URLRequest(url: url)
make(request: request) { response in closure?(response) }
}
}
Usage of Alamofire sample
private lazy var alamofireDataManager = AlamofireDataManager(queue: DispatchQueue(label: "DataManager.queue", qos: .utility))
//.........
alamofireDataManager.searchRequest(term: "jack johnson") { result in
print(result.value ?? "no data")
print(result.error ?? "no error")
}
URLSession Sample
import Foundation
class DataManager {
fileprivate let queue: DispatchQueue
init(queue: DispatchQueue) { self.queue = queue }
private func createError(message: String, code: Int) -> Error {
return NSError(domain: "dataManager", code: code, userInfo: ["message": message ])
}
private func make(session: URLSession = URLSession.shared, request: URLRequest, closure: ((_ json: [String: Any]?, _ error: Error?)->Void)?) {
let task = session.dataTask(with: request) { [weak self] data, response, error in
self?.queue.async {
let complete: (_ json: [String: Any]?, _ error: Error?) ->() = { json, error in DispatchQueue.main.async { closure?(json, error) } }
guard let self = self, error == nil else { complete(nil, error); return }
guard let data = data else { complete(nil, self.createError(message: "No data", code: 999)); return }
do {
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
complete(json, nil)
}
} catch let error { complete(nil, error); return }
}
}
task.resume()
}
func searchRequest(term: String, closure: ((_ json: [String: Any]?, _ error: Error?)->Void)?) {
let url = URL(string: "https://itunes.apple.com/search?term=\(term.replacingOccurrences(of: " ", with: "+"))")
let request = URLRequest(url: url!)
make(request: request) { json, error in closure?(json, error) }
}
}
Usage of URLSession sample
private lazy var dataManager = DataManager(queue: DispatchQueue(label: "DataManager.queue", qos: .utility))
// .......
dataManager.searchRequest(term: "jack johnson") { json, error in
print(error ?? "nil")
print(json ?? "nil")
print("Update views")
}
Results
I have done HTTP Request Both methods GET & POST with JSON Parsing this way:
on viewDidLoad():
override func viewDidLoad() {
super.viewDidLoad()
makeGetRequest()
makePostRequest()
}
func makePostRequest(){
let urlPath: String = "http://www.swiftdeveloperblog.com/http-post-example-script/"
var url: NSURL = NSURL(string: urlPath)!
var request: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
var stringPost="firstName=James&lastName=Bond" // Key and Value
let data = stringPost.dataUsingEncoding(NSUTF8StringEncoding)
request.timeoutInterval = 60
request.HTTPBody=data
request.HTTPShouldHandleCookies=false
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: error) as? NSDictionary
if (jsonResult != nil) {
// Success
println(jsonResult)
let message = jsonResult["Message"] as! NSString
println(message)
}else {
// Failed
println("Failed")
}
})
}
func makeGetRequest(){
var url : String = "http://api.androidhive.info/contacts/"
var request : NSMutableURLRequest = NSMutableURLRequest()
request.URL = NSURL(string: url)
request.HTTPMethod = "GET"
request.timeoutInterval = 60
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: error) as? NSDictionary
if (jsonResult != nil) {
// Success
println(jsonResult)
let dataArray = jsonResult["contacts"] as! NSArray;
for item in dataArray { // loop through data items
let obj = item as! NSDictionary
for (key, value) in obj {
println("Key: \(key) - Value: \(value)")
let phone = obj["phone"] as! NSDictionary;
let mobile = phone["mobile"] as! NSString
println(mobile)
let home = phone["home"] as! NSString
println(home)
let office = phone["office"] as! NSString
println(office)
}
}
} else {
// Failed
println("Failed")
}
})
}
Done
You can use Just, a python-requests style HTTP library.
Some example of sending HTTP request with Just:
// synchronous GET request with URL query a=1
let r = Just.get("https://httpbin.org/get", params:["a":1])
// asynchronous POST request with form value and file uploads
Just.post(
"http://justiceleauge.org/member/register",
data: ["username": "barryallen", "password":"ReverseF1ashSucks"],
files: ["profile_photo": .URL(fileURLWithPath:"flash.jpeg", nil)]
) { (r)
if (r.ok) { /* success! */ }
}
In both cases, the result of a request r can be accessed in ways similar to python-request:
r.ok // is the response successful?
r.statusCode // status code of response
r.content // response body as NSData?
r.text // response body as text?
r.json // response body parsed by NSJSONSerielization
You can find more examples in this playground
Using this library in synchronous mode in a playground is the closest thing to cURL one can get in Swift.
I am calling the json on login button click
#IBAction func loginClicked(sender : AnyObject) {
var request = NSMutableURLRequest(URL: NSURL(string: kLoginURL)) // Here, kLogin contains the Login API.
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
var err: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(self.criteriaDic(), options: nil, error: &err) // This Line fills the web service with required parameters.
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
var err1: NSError?
var json2 = NSJSONSerialization.JSONObjectWithData(strData.dataUsingEncoding(NSUTF8StringEncoding), options: .MutableLeaves, error:&err1 ) as NSDictionary
println("json2 :\(json2)")
if(err) {
println(err!.localizedDescription)
}
else {
var success = json2["success"] as? Int
println("Success: \(success)")
}
})
task.resume()
}
Here, I have made a seperate dictionary for the parameters.
var params = ["format":"json", "MobileType":"IOS","MIN":"f8d16d98ad12acdbbe1de647414495ec","UserName":emailTxtField.text,"PWD":passwordTxtField.text,"SigninVia":"SH"]as NSDictionary
return params
}
// You can add your own sets of parameter here.
KISS answer:
URLSession.shared.dataTask(with: URL(string: "https://google.com")!) {(data, response, error) in
print(String(data: data!, encoding: .utf8))
}.resume()
In Swift 4.1 and Xcode 9.4.1.
JSON POST approach example. To check internet connection add Reachability.h & .m files from https://developer.apple.com/library/archive/samplecode/Reachability/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007324-Intro-DontLinkElementID_2
func yourFunctionName {
//Check internet connection
let networkReachability = Reachability.forInternetConnection()
let networkStatus:Int = (networkReachability?.currentReachabilityStatus())!.rawValue
print(networkStatus)
if networkStatus == NotReachable.rawValue {
let msg = SharedClass.sharedInstance.noNetMsg//Message
//Call alert from shared class
SharedClass.sharedInstance.alert(view: self, title: "", message: msg)
} else {
//Call spinner from shared class
SharedClass.sharedInstance.activityIndicator(view: self.view)//Play spinner
let parameters = "Your parameters here"
var request = URLRequest(url: URL(string: url)!)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
print("URL : \(request)")
request.httpBody = parameters.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data, error == nil else { // check for fundamental networking error
//Stop spinner
SharedClass.sharedInstance.stopActivityIndicator() //Stop spinner
//Print error in alert
SharedClass.sharedInstance.alert(view: self, title: "", message: "\(String(describing: error!.localizedDescription))")
return
}
SharedClass.sharedInstance.stopActivityIndicator() //Stop spinner
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
do {
let response = try JSONSerialization.jsonObject(with: data, options: []) as? [String: AnyObject]
print(response!)
//Your code here
} catch let error as NSError {
print(error)
}
}
task.resume()
}
}
If you have interest to use this function in SharedClass
//My shared class
import UIKit
class SharedClass: NSObject {
static let sharedInstance = SharedClass()
func postRequestFunction(apiName: String , parameters: String, onCompletion: #escaping (_ success: Bool, _ error: Error?, _ result: [String: Any]?)->()) {
var URL = "your URL here/index.php/***?"
URL = URL.replacingOccurrences(of: "***", with: apiName)
var request = URLRequest(url: URL(string: URL)!)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
print("shared URL : \(request)")
request.httpBody = parameters.data(using: .utf8)
var returnRes:[String:Any] = [:]
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
onCompletion(false, error, nil)
} else {
guard let data = data else {
onCompletion(false, error, nil)
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode == 200 {
do {
returnRes = try JSONSerialization.jsonObject(with: data, options: []) as! [String : Any]
onCompletion(true, nil, returnRes)
} catch let error as NSError {
onCompletion(false, error, nil)
}
} else {
onCompletion(false, error, nil)
}
}
}
task.resume()
}
private override init() {
}
And finally call this function like this....
SharedClass.sharedInstance.postRequestFunction(apiName: "Your API name", parameters: parameters) { (success, error, result) in
print(result!)
if success {
//Your code here
} else {
print(error?.localizedDescription ?? "")
}
}
Here are start to finish instructions to make an HTTP request with Swift on Linux.
First create a SwiftPM package
mkdir swift-http && cd swift-http && swift package init --type executable
Then replace the contents of ./Sources/swift-http/main.swift
with the code below:
import Foundation
import FoundationNetworking
let sema = DispatchSemaphore(value: 0)
URLSession.shared.dataTask(with: URL(string: "http://numbersapi.com/42")!) {(data, response, error) in
print(String(data: data!, encoding: .utf8) ?? String(describing: error))
sema.signal()
}.resume()
sema.wait()
Then run the code
swift run
Output example:
[6/6] Build complete!
42 is the answer to the Ultimate Question of Life, the Universe, and Everything.
Note: the DispatchSemaphore is used so that our program doesn't exit before getting a response.
You could have also done something like this:
import Foundation
import FoundationNetworking
var done = false
URLSession.shared.dataTask(with: URL(string: "http://numbersapi.com/42")!) {(data, response, error) in
print(String(data: data!, encoding: .utf8) ?? String(describing: error))
done = true
}.resume()
while !done { Thread.sleep(forTimeInterval: 1) }
A simple Swift 2.0 approach to making a HTTP GET request
The HTTP request is asynchronous so you need a way to get the returned value from the HTTP Request. This approach uses Notifiers and is spread over two classes.
The example is to check the username and password for an identifier token using the website http://www.example.com/handler.php?do=CheckUserJson&json= That is the file is called handler.php and has a switch statement on the do parameter to get a RESTful approach.
In the viewDidLoad we setup the NotifierObserver, set up the json and make the call to the getHTTPRequest function. It will return to the function checkedUsernameAndPassword with the returned parameter from the http request.
override func viewDidLoad() {
super.viewDidLoad()
// setup the Notification observer to catch the result of check username and password
NSNotificationCenter.defaultCenter().addObserver(self, selector: "checkedUsernameAndPassword:", name: CHECK_USERNAME_AND_PASSWORD, object: nil)
let username = GlobalVariables.USER_NAME
let password = GlobalVariables.PASSWORD
// check username and password
if let jsonString = Utility.checkUsernameAndPasswordJson(username, password:password){
print("json string returned = \(jsonString)")
let url = CHECKUSERJSON+jsonString
// CHECKUSERJSON = http://www.example.com/handler.php?do=CheckUserJson&json=
// jsonString = {\"username\":\"demo\",\"password\":\"demo\"}"
// the php script handles a json request and returns a string identifier
Utility.getHTTPRequest(url,notifierId: CHECK_USERNAME_AND_PASSWORD)
// the returned identifier is sent to the checkedUsernaeAndPassword function when it becomes availabel.
}
}
There are two static functions in Utility.swift first to encode the json and then to do the HTTP call.
static func checkUsernameAndPasswordJson(username: String, password: String) -> String?{
let para:NSMutableDictionary = NSMutableDictionary()
para.setValue("demo", forKey: "username")
para.setValue("demo", forKey: "password")
let jsonData: NSData
do{
jsonData = try NSJSONSerialization.dataWithJSONObject(para, options: NSJSONWritingOptions())
let jsonString = NSString(data: jsonData, encoding: NSUTF8StringEncoding) as! String
return jsonString
} catch _ {
print ("UH OOO")
return nil
}
}
and the Http request
static func getHTTPRequest (url:String , notifierId: String) -> Void{
let urlString = url
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config, delegate: nil, delegateQueue: nil)
let safeURL = urlString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
if let url = NSURL(string: safeURL){
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "GET"
request.timeoutInterval = 60
let taskData = session.dataTaskWithRequest(request, completionHandler: {
(data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
if (data != nil) {
let result = NSString(data: data! , encoding: NSUTF8StringEncoding)
sendNotification (notifierId, message: String(result), num: 0)
}else{
sendNotification (notifierId, message: String(UTF8String: nil), num: -1) }
})
taskData.resume()
}else{
print("bad urlString = \(urlString)")
}
}
The sendNotification function completes the circle. Notice that in teh Observer there is a ":" at the end of the selector string. This allows the notification to carry a payload in userInfo. I give this a String and an Int.
static func sendNotification (key: String, message:String?, num: Int?){
NSNotificationCenter.defaultCenter().postNotificationName(
key,
object: nil,
userInfo: (["message": message!,
"num": "\(num!)"])
)
}
Note that using HTTP is oldFashioned, prefer HTTPS see How do I load an HTTP URL with App Transport Security enabled in iOS 9?
Update :- Xcode 13.0 & Swift 5+
GET HTTP REQUEST
let url = URL(string: "URL HERE")! //PUT Your URL
var request = URLRequest(url: url)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let safeData = data,
let response = response as? HTTPURLResponse,
error == nil else { // check for fundamental networking error
print("error", error ?? "Unknown error")
delegate?.onError(error!)
return
}
guard (200 ... 299) ~= response.statusCode else { // check for http errors
print("statusCode should be 2xx, but is \(response.statusCode)")
print("response = \(response)")
return
}
let responseString = String(data: safeData, encoding: .utf8)
print("Response String = \(responseString)")
}
task.resume()
var post:NSString = "api=myposts&userid=\(uid)&page_no=0&limit_no=10"
NSLog("PostData: %#",post);
var url1:NSURL = NSURL(string: url)!
var postData:NSData = post.dataUsingEncoding(NSASCIIStringEncoding)!
var postLength:NSString = String( postData.length )
var request:NSMutableURLRequest = NSMutableURLRequest(URL: url1)
request.HTTPMethod = "POST"
request.HTTPBody = postData
request.setValue(postLength, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
var reponseError: NSError?
var response: NSURLResponse?
var urlData: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&reponseError)
if ( urlData != nil ) {
let res = response as NSHTTPURLResponse!;
NSLog("Response code: %ld", res.statusCode);
if (res.statusCode >= 200 && res.statusCode < 300)
{
var responseData:NSString = NSString(data:urlData!, encoding:NSUTF8StringEncoding)!
NSLog("Response ==> %#", responseData);
var error: NSError?
let jsonData:NSDictionary = NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers , error: &error) as NSDictionary
let success:NSInteger = jsonData.valueForKey("error") as NSInteger
//[jsonData[#"success"] integerValue];
NSLog("Success: %ld", success);
if(success == 0)
{
NSLog("Login SUCCESS");
self.dataArr = jsonData.valueForKey("data") as NSMutableArray
self.table.reloadData()
} else {
NSLog("Login failed1");
ZAActivityBar.showErrorWithStatus("error", forAction: "Action2")
}
} else {
NSLog("Login failed2");
ZAActivityBar.showErrorWithStatus("error", forAction: "Action2")
}
} else {
NSLog("Login failed3");
ZAActivityBar.showErrorWithStatus("error", forAction: "Action2")
}
it will help you surely
//Here is an example that worked for me
//Swift function that post a request to a server with key values
func insertRecords()
{
let usrID = txtID.text
let checkin = lblInOut.text
let comment = txtComment.text
// The address of the web service
let urlString = "http://your_url/checkInOut_post.php"
// These are the keys that your are sending as part of the post request
let keyValues = "id=\(usrID)&inout=\(checkin)&comment=\(comment)"
// 1 - Create the session by getting the configuration and then
// creating the session
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config, delegate: nil, delegateQueue: nil)
// 2 - Create the URL Object
if let url = NSURL(string: urlString){
// 3 - Create the Request Object
var request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
// set the key values
request.HTTPBody = keyValues.dataUsingEncoding(NSUTF8StringEncoding);
// 4 - execute the request
let taskData = session.dataTaskWithRequest(request, completionHandler: {
(data:NSData!, response:NSURLResponse!, error:NSError!) -> Void in
println("\(data)")
// 5 - Do something with the Data back
if (data != nil) {
// we got some data back
println("\(data)")
let result = NSString(data: data , encoding: NSUTF8StringEncoding)
println("\(result)")
if result == "OK" {
let a = UIAlertView(title: "OK", message: "Attendece has been recorded", delegate: nil, cancelButtonTitle: "OK")
println("\(result)")
dispatch_async(dispatch_get_main_queue()) {
a.show()
}
} else {
// display error and do something else
}
} else
{ // we got an error
println("Error getting stores :\(error.localizedDescription)")
}
})
taskData.resume()
}
}
PHP Code to get the key values
$empID = $_POST['id'];
$inOut = $_POST['inout'];
$comment = $_POST['comment'];
Here's a very simple Swift 4 example in a playground:
import UIKit
// run asynchronously in a playground
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
// create a url
let url = URL(string: "http://www.stackoverflow.com")
// create a data task
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil {
print("there's a problem")
}
print(String(data: data!, encoding: String.Encoding.utf8) ?? "")
}
//running the task w/ resume
task.resume()
For XCUITest to stop the test finishing before the async request completes use this (maybe reduce the 100 timeout):
func test_api() {
let url = URL(string: "https://jsonplaceholder.typicode.com/posts/42")!
let exp = expectation(description: "Waiting for data")
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
guard let data = data else { return }
print(String(data: data, encoding: .utf8)!)
exp.fulfill()
}
task.resume()
XCTWaiter.wait(for: [exp], timeout: 100)
}
An example for a sample "GET" request is given below.
let urlString = "YOUR_GET_URL"
let yourURL = URL(string: urlstring)
let dataTask = URLSession.shared.dataTask(with: yourURL) { (data, response, error) in
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers)
print("json --- \(json)")
}catch let err {
print("err---\(err.localizedDescription)")
}
}
dataTask.resume()