IOS Swift Call Web Service using SOAP - ios

I have looked through the answers to how to call a web service via SOAP form swift on the internet and found some answers. I have tried to implement the code I have found in those answers but continually get a http 400 status code. I am trying to figure our what I am doing wrong.
I have distilled the problem down to a few lines of code in a view controller as seen below an the code is called when a button on the UI is pressed. The web service I am trying to call can be found at http://www.cgsapi.com/CGSWebService.asmx.
(To view the WSDL file append ?wsdl to the end of the URL.)
import UIKit
class ViewController: UIViewController {
var is_SoapMessage: String = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:cgs=\"http://www.cgsapi.com/\"><soapenv:Header/><soapenv:Body><cgs:GetSystemStatus/></soapenv:Body></soapenv:Envelope>"
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 btnClicked(sender: AnyObject)
{
var is_URL: String = "http://www.cgsapi.com/CGSWebService.asmx"
var lobj_Request = NSMutableURLRequest(URL: NSURL(string: is_URL)!)
var session = NSURLSession.sharedSession()
var err: NSError?
lobj_Request.HTTPMethod = "POST"
lobj_Request.addValue("www.cgsapi.com", forHTTPHeaderField: "Host")
lobj_Request.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
//lobj_Request.addValue(String(count(is_SoapMessage)), forHTTPHeaderField: "Content-Length")
lobj_Request.addValue("223", forHTTPHeaderField: "Content-Length")
lobj_Request.addValue("http://www.cgsapi.com/GetSystemStatus", forHTTPHeaderField: "SOAPAction")
var task = session.dataTaskWithRequest(lobj_Request, completionHandler: {data, response, error -> Void in
println("Response: \(response)")
var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Body: \(strData)")
if error != nil
{
println("Error: " + error.description)
}
})
task.resume()
}
}
Any idea why I am getting http 400 status when I call this?

So i was being silly. The main thing was that I missed setting the body of the message to the SOAP request. My updated corrected code is below:
//
// ViewController.swift
// TestWebServiceSoap
//
// Created by George M. Ceaser Jr on 6/2/15.
// Copyright (c) 2015 George M. Ceaser Jr. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
var is_SoapMessage: String = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:cgs=\"http://www.cgsapi.com/\"><soapenv:Header/><soapenv:Body><cgs:GetSystemStatus/></soapenv:Body></soapenv:Envelope>"
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 btnClicked(sender: AnyObject)
{
var is_URL: String = "http://www.cgsapi.com/CGSWebService.asmx"
var lobj_Request = NSMutableURLRequest(URL: NSURL(string: is_URL)!)
var session = NSURLSession.sharedSession()
var err: NSError?
lobj_Request.HTTPMethod = "POST"
lobj_Request.HTTPBody = is_SoapMessage.dataUsingEncoding(NSUTF8StringEncoding)
lobj_Request.addValue("www.cgsapi.com", forHTTPHeaderField: "Host")
lobj_Request.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
lobj_Request.addValue(String(count(is_SoapMessage)), forHTTPHeaderField: "Content-Length")
//lobj_Request.addValue("223", forHTTPHeaderField: "Content-Length")
lobj_Request.addValue("http://www.cgsapi.com/GetSystemStatus", forHTTPHeaderField: "SOAPAction")
var task = session.dataTaskWithRequest(lobj_Request, completionHandler: {data, response, error -> Void in
println("Response: \(response)")
var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Body: \(strData)")
if error != nil
{
println("Error: " + error.description)
}
})
task.resume()
}
}

Swift 5.2, XCode 12
I followed more or less the approach that George did on his self response.
I think that leaving a sample of code with the latest swift and Xcode may be helpful for some:
private func exampleSoapRequest() {
let url = URL(string: ProvidedData.urlString)!
let request = NSMutableURLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = ProvidedData.envelope.data(using: .utf8)
request.addValue(String(ProvidedData.envelope.count), forHTTPHeaderField: "Content-Length")
request.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.addValue("<PUT HERE YOUR SOAP ACTION IF NEEDED>", forHTTPHeaderField: "SOAPAction")
let task = URLSession.shared
.dataTask(with: request as URLRequest,
completionHandler: { data, response, error in
guard error == nil else {
// Handle the error
print(error)
}
guard let data = data else {
return
}
// Continue checking response or data...
})
task.resume()
}
In the ProvidedData, I just assumed you're gonna pass somehow your url and envelope.
In addition to that, if you want to have a more structured and "parameter based" envelope and you don't mind using external libraries, the solution with AEXML proposed by #Pulkit Kumar Singh is also quite interesting.

Refer to this link https://github.com/blastar/Swift-SOAP-with-Alamofire . It gives you a more structured way to deal with Soap with Almofire.
1.Using cocoa pods you can import the following pods
https://cocoapods.org/ to know how to setup cocoa pods
use_frameworks!
target 'Swift-SOAP-with-Alamofire' do
pod 'Alamofire'
pod 'SWXMLHash'
pod 'AEXML'
pod 'StringExtensionHTML'
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['CONFIGURATION_BUILD_DIR'] = '$PODS_CONFIGURATION_BUILD_DIR'
end
end
end
2.
This is just a way to implement soap through almofire which is more structured . You have to do a little task to customise according to your implementation
func getCountries(completion: (result: [Country]) -> Void) -> Void {
var result = [Country]()
let soapRequest = AEXMLDocument()
let envelopeAttributes = ["xmlns:SOAP-ENV" : "http://schemas.xmlsoap.org/soap/envelope/", "xmlns:ns1" : "http://www.webserviceX.NET"]
let envelope = soapRequest.addChild(name: "SOAP-ENV:Envelope", attributes: envelopeAttributes)
let body = envelope.addChild(name: "SOAP-ENV:Body")
body.addChild(name: "ns1:GetCountries")
let soapLenth = String(soapRequest.xmlString.characters.count)
let theURL = NSURL(string: "http://www.webservicex.net/country.asmx")
let mutableR = NSMutableURLRequest(URL: theURL!)
mutableR.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
mutableR.addValue("text/html; charset=utf-8", forHTTPHeaderField: "Content-Type")
mutableR.addValue(soapLenth, forHTTPHeaderField: "Content-Length")
mutableR.HTTPMethod = "POST"
mutableR.HTTPBody = soapRequest.xmlString.dataUsingEncoding(NSUTF8StringEncoding)
Alamofire.request(mutableR)
.responseString { response in
if let xmlString = response.result.value {
let xml = SWXMLHash.parse(xmlString)
let body = xml["soap:Envelope"]["soap:Body"]
if let countriesElement = body["GetCountriesResponse"]["GetCountriesResult"].element {
let getCountriesResult = countriesElement.text!
let xmlInner = SWXMLHash.parse(getCountriesResult.stringByDecodingHTMLEntities)
for element in xmlInner["NewDataSet"]["Table"].all {
if let nameElement = element["Name"].element {
var countryStruct = Country()
countryStruct.name = nameElement.text!
result.append(countryStruct)
}
}
}
completion(result: result)
}else{
print("error fetching XML")
}
}
}
Hope it Helps.

You can use below code to make web service call.
let url = NSURL(string: "https://www.google.com/")
var request:NSMutableURLRequest = NSMutableURLRequest(URL:url!)
var bodyData = "data=something"
request.HTTPMethod = "POST"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue())
{
(response, data, error) in
print(response)
if let HTTPResponse = response as? NSHTTPURLResponse {
let statusCode = HTTPResponse.statusCode
if statusCode == 200 {
// Yes, Do something.
}else{
print("Error")
}
}
}

*api calling for returning data type soap
swift 2.2. and above*
let urlForService = NSURL.init(string: "enter your url string")
let postString = String(format: "TokenId=%#&LoggedUserId=%#&UserDeviceId=%#", arguments: ["parameter value","parameter value","parameter value"])
do
{
let urlSession:NSURLSession = NSURLSession.sharedSession()
let urlRequest:NSMutableURLRequest = NSMutableURLRequest(URL: urlForService!)
urlRequest.HTTPShouldHandleCookies = false
urlRequest.timeoutInterval = 120 ;
urlRequest.HTTPMethod = "POST";
urlRequest.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
urlRequest.addValue("\(postString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)?.length)", forHTTPHeaderField: "Content-Length")
urlRequest.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
let session = urlSession.dataTaskWithRequest(urlRequest, completionHandler: { (data, response, errorResponse) in
if errorResponse != nil {
print(errorResponse!.localizedDescription)
}
else
{
if data != nil
{
do {
if let dictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary {
let dateformaterweb = NSDateFormatter()
dateformaterweb.dateFormat = "DD/MM/YYYY"
let tempwitnohdate = dictionary.valueForKey("AllContact") as! NSArray
for i in tempwitnohdate{
if String(i.valueForKey("Birthdate")!) != ""{
let name = String(i.valueForKey("ContactName")!)
let number = String(i.valueForKey("ContactNo")!)
let temparray = String(i.valueForKey("Birthdate")!).componentsSeparatedByString("/")
let month = temparray[1]
let day = temparray[0]
let dateweb = ([temparray[0]] + [temparray[1]]).joinWithSeparator(",")
self.usercontact.append(Utility(name: name, number: number, date: dateweb, month:Int(month)!, day:Int(day)!))
}
else{
let name = String(i.valueForKey("ContactName")!)
let number = String(i.valueForKey("ContactNo")!)
let dateweb = self.formater.stringFromDate(self.date)
self.usercontactsort.append(Utility(name: name, number: number, date: dateweb, month:13, day:32))
}
}
self.usercontactsort = self.usercontactsort.sort { $0.strName.localizedStandardCompare($1.strName) == NSComparisonResult.OrderedAscending }
self.usercontact.sortInPlace{$0.monthorder < $1.monthorder}
for i in 0...self.usercontact.count - 1{
for j in i...self.usercontact.count - 1{
if self.usercontact[i].monthorder == self.usercontact[j].monthorder && i != j{
if self.usercontact[i].dayorder > self.usercontact[j].dayorder{
let temp = self.usercontact[i]
self.usercontact[i] = self.usercontact[j]
self.usercontact[j] = temp
}
}
}
}
self.finaldata = self.usercontact + self.usercontactsort
}
self.tableview.reloadData()
}
catch {
print("Error \(error)")
}
}
}
})
session.resume()
}

- (BOOL)callWebService {
NSString *soapMessage = #"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:cgs=""http://www.cgsapi.com/""><soapenv:Header/><soapenv:Body><cgs:GetSystemStatus/></soapenv:Body></soapenv:Envelope>";
// SOAP request settings
NSURL *url = [NSURL URLWithString:#"http://www.cgsapi.com/CGSWebService.asmx"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSURLSession *session = [NSURLSession sharedSession];
NSError *error;
request.HTTPMethod = #"POST";
request.HTTPBody = [soapMessage dataUsingEncoding:NSUTF8StringEncoding];
[request addValue:#"www.cgsapi.com" forHTTPHeaderField:#"Host"];
[request addValue:#"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request addValue:[NSString stringWithFormat:#"%i", soapMessage.length] forHTTPHeaderField:#"Content-Length"];
[request addValue:#"http://www.cgsapi.com/GetSystemStatus" forHTTPHeaderField:#"SOAPAction"];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(#"response: %#", response);
NSString *output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"output: %#", output);
if (error !=nil) {
NSLog(#"error: %i %#", error.code, error.description);
}
}];
[task resume];
return true;
}

Related

URLSession dataTask doesn't work

im new at swift and im trying to get response from a soap services, but the dataTask in my session never get in, always skip it. I already test te urls and the soap message but i don't have any lucky. Here is my code
func servisRun(){
let soapMessage = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tem=\"http://tempuri.org/\"><soapenv:Header/><soapenv:Body><tem:LogIn><tem:user>00002403</tem:user><tem:password>123456</tem:password></tem:LogIn></soapenv:Body></soapenv:Envelope>"
let msgLength = String(describing: soapMessage.characters.count)
let url = URL(string: "http://192.168.1.171/WcfSif.Services.Login.Login.svc")
var request = URLRequest(url: url!)
request.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.addValue(msgLength, forHTTPHeaderField: "Content-Length")
request.httpMethod = "POST"
request.httpBody = soapMessage.data(using: String.Encoding.utf8, allowLossyConversion: false)
URLSession.shared.dataTask(with: request) { (data, resp, error) in
guard error == nil && data != nil else{
print("connection error or data is nill")
return
}
if resp != nil {
self.mutableData?.length = 0;
}
let mutableData : Void = NSMutableData.initialize()
print(mutableData)
let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
self.mutableData?.append(data!)
print(dataString!)
}
.resume()
let nsData = mutableData?.copy() as! NSData
let xmlParser = XMLParser(data: nsData as Data)
xmlParser.delegate = self
xmlParser.parse()
xmlParser.shouldResolveExternalEntities = true
}

How to post raw data in swift 3?

If I post raw data using Postman, response is coming. I am using this code
var dict = Dictionary<String, Any>()
dict = ["user_id" :userid as AnyObject, "type" :type as AnyObject, "complaint_id" :complaintId as AnyObject, "auth_code" : authCode as AnyObject, "isSkip" :isSkip as AnyObject]
let url:URL = URL(string: "http://development.easystartup.org/prigovo/Backend/detailed_complaint/index.php")!
let session = URLSession.shared
var postData = NSData()
do{
postData = try JSONSerialization.data(withJSONObject: dict, options: JSONSerialization.WritingOptions.prettyPrinted) as NSData!
}catch {
print("error")
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
// request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
request.setValue("\(postData.length)", forHTTPHeaderField: "Content-Length")
request.setValue("text/html", forHTTPHeaderField: "Content-Type")
request.setValue("json/application", forHTTPHeaderField: "Accept")
request.httpBody = postData as Data
let task = session.dataTask(with: request as URLRequest) {
(
data, response, error) in
guard let data = data, let _:URLResponse = response, error == nil else {
print("error")
return
}
let dataString = String(data: data, encoding: String.Encoding.utf8)
print(dataString ?? "no data")
}
task.resume()
Getting data of 0 bytes everyTime. Already tried with Alamofire but no response.
Also I tried in Objective C where I am getting response, code is :
NSURL *url = [NSURL URLWithString:urlStr];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:[NSString stringWithFormat:#"%lu", (unsigned long)postData.length] forHTTPHeaderField:#"Content-Length"];
[request setValue:#"text/html" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSError *error = nil;
NSHTTPURLResponse *response = nil;
[[NSURLConnection alloc] initWithRequest:request delegate:self];
NSData *retData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (error)
{
//error
NSLog(#"error");
return #"";
}
else
{
NSLog(#"No error");
NSString *charlieSendString = [[NSString alloc] initWithData:retData encoding:NSUTF8StringEncoding];
NSLog(#"data come : %#",charlieSendString);
return charlieSendString;
}
Posted "dict" in Log :
["complaint_id": COMBRD1, "user_id": USR9, "type": complaint_brand, "auth_code": KL1hwYrAhNVnSgT, "is_skip": 2]
var dict = Dictionary<String, Any>()
dict = ["user_id" :userid, "type" :type, "complaint_id" :complaintId,"auth_code" : authCode, "is_skip" :isSkip]
var jsonData = NSData()
// var dataString2 :String = ""
do {
jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted) as NSData
// you can now cast it with the right type
} catch {
print(error.localizedDescription)
}
let url:URL = URL(string: "http://Backend/detailed_complaint/index.php")!
let session = URLSession.shared
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("\(jsonData.length)", forHTTPHeaderField: "Content-Length")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData as Data
let task = session.dataTask(with: request as URLRequest) {
(
data, response, error) in
guard let data = data, let _:URLResponse = response, error == nil else {
print("error")
return
}
let dataString = String(data: data, encoding: String.Encoding.utf8)
print("no data",dataString ?? "no data")
}
task.resume()

How can I convert a synchronous post request to an asynchronous post request?

As it's widely known that an asynchronous post request is better since the user won't get a perception that the app has "crashed" while it's loading the long process.
However, I'm not sure where to start to convert a synchronous post request to an asynchronous post request for a Swift code.
I have this code currently:
func checkLogin () {
let username:NSString = txtUsername.text! as NSString
let password:NSString = txtPassword.text! as NSString
do {
let post:NSString = "username=\(username)&password=\(password)" as NSString
NSLog("PostData: %#",post);
let url:URL = URL(string:"https://example.com/login.php")!
let postData:Data = post.data(using: String.Encoding.ascii.rawValue)!
let postLength:NSString = String( postData.count ) as NSString
let request:NSMutableURLRequest = NSMutableURLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = postData
request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
var reponseError: NSError?
var response: URLResponse?
var urlData: Data?
do {
urlData = try NSURLConnection.sendSynchronousRequest(request as URLRequest, returning:&response)
} catch let error as NSError {
reponseError = error
urlData = nil
}
if ( urlData != nil ) {
let res = response as! HTTPURLResponse!;
NSLog("Response code: %ld", res?.statusCode);
if ((res?.statusCode)! >= 200 && (res?.statusCode)! < 300) {
let responseData:NSString = NSString(data:urlData!, encoding:String.Encoding.utf8.rawValue)!
NSLog("Response ==> %#", responseData);
let jsonData:NSDictionary = try JSONSerialization.jsonObject(with: urlData!, options:JSONSerialization.ReadingOptions.mutableContainers ) as! NSDictionary
let success:NSInteger = jsonData.value(forKey: "success") as! NSInteger
NSLog("Success: %ld", success);
if(success == 1)
{
// do something, code removed
} else {
var error_msg:NSString
if jsonData["error_message"] as? NSString != nil {
error_msg = jsonData["error_message"] as! NSString
} else {
error_msg = "Unknown Error"
}
// show alert
}
}
}
}
}
First of all don't use NSURLConnection as it's deprecated now. Instead use NSURLSession.
You can simply use like this:
let task = URLSession.shared().dataTask(with: request) {
data, response, error in
if (data) {
} else {
print("error=\(error!.localizedDescription)")
}
}
task.resume()
You need to really make a lot of changes. Use swift type, instead of NSMutableURLRequest use URLRequest use String instead of NSString instead of NSDictionary & NSArray use Swift Dictionary and Array
func checkLogin () {
let username = txtUsername.text!
let password = txtPassword.text!
let post = "username=\(username)&password=\(password)"
NSLog("PostData: %#",post);
let url:URL = URL(string:"https://example.com/login.php")!
let postData = post.data(using: .utf8)!
let postLength = String( postData.count )
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = postData
request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if error != nil {
return
}
if let jsonData = (try? JSONSerialization.jsonObject(with: data!, options: [])) as? [String:Any] {
let success = jsonData["success"] as! Int
if success == 1 {
//do something,
}
else {
//show alert
}
}
})
task.resume()
}

sendSynchronousRequest is deprecated in ios 9 [duplicate]

This question already has an answer here:
Fixing NSURLConnection Deprecation from Swift 1.2 to 2.0
(1 answer)
Closed 7 years ago.
Xcode says that sendSynchronousRequest is now deprecated.
How should I replace it?
let postData:NSData = post.dataUsingEncoding(NSASCIIStringEncoding)!
let postLength:NSString = String( postData.length )
let request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.HTTPBody = postData
request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
var response: NSURLResponse?
var urlData: NSData?
do {
urlData = try NSURLConnection.sendSynchronousRequest(request, returningResponse:&response)
} catch _ as NSError {
urlData = nil
} catch {
fatalError()
}
This is a working example,
You should use NSURLSession, with Request.
func testPost(sender: UIButton) {
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: NSURL(string: "http://localhost:8080/iOSServer/ios/helloworld/swiftCalculator")!)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
let d = "4"
let data = "x=4&y=\(d)"
request.HTTPBody = data.dataUsingEncoding(NSASCIIStringEncoding)
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if let error = error {
print(error)
}
if let data = data{
print("data =\(data)")
}
if let response = response {
print("url = \(response.URL!)")
print("response = \(response)")
let httpResponse = response as! NSHTTPURLResponse
print("response code = \(httpResponse.statusCode)")
//if you response is json do the following
do{
let resultJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions())
let arrayJSON = resultJSON as! NSArray
for value in arrayJSON{
let dicValue = value as! NSDictionary
for (key, value) in dicValue {
print("key = \(key)")
print("value = \(value)")
}
}
}catch _{
print("Received not-well-formatted JSON")
}
}
})
task.resume()
}
Notice it is not necessary to use the request. you can have a data task with URL, but I added the request because in your code, you have set some headers in the request.
Notice using the completionHandler which will be called when your server responses by http response.

How do you add headers to dataTaskWithUrl?

I have a dataTaskWithUrl:
var headers: NSDictionary = ["X-Mashape-Key": "my-secret-key" , "Accept" : "application/json"]
var stringUrl = "https://restcountries-v1.p.mashape.com/all"
stringUrl = stringUrl.stringByReplacingOccurrencesOfString(" ", withString: "+")
let url = NSURL(string: stringUrl)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url!, completionHandler: { (data, response, error) -> Void in
if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as? NSDictionary{
println(jsonResult)
}else{
println("error")
}
})
task.resume()
I want to add headers to my task.
In other words, I would like to convert this code to swift:
NSDictionary *headers = #{#"X-Mashape-Key": #"my-secret-key", #"Accept": #"application/json"};
UNIUrlConnection *asyncConnection = [[UNIRest get:^(UNISimpleRequest *request) {
[request setUrl:#"https://restcountries-v1.p.mashape.com/all"];
[request setHeaders:headers];
}] asJsonAsync:^(UNIHTTPJsonResponse *response, NSError *error) {
NSInteger code = response.code;
NSDictionary *responseHeaders = response.headers;
UNIJsonNode *body = response.body;
NSData *rawBody = response.rawBody;
}];
I am new to dataRequests. I do not understand Objective C code but I made a guess when I looked at that code. I need to use headers because I if I just try going to
https://restcountries-v1.p.mashape.com/all directly, I get an error. I had received that Objective C code from this website: https://www.mashape.com/fayder/rest-countries-v1. Any help in the right direction would be very much appreciated.
Thanks
Update for Swift 4+:
let httpUrl = "http://...."
guard let url = URL(string: httpUrl) else {
return
}
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("my-secret-key", forHTTPHeaderField: "X-Mashape-Key")
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
}
task.resume()
Old Post:
If you want to use dataTask
var stringUrl = "https://restcountries-v1.p.mashape.com/all"
stringUrl = stringUrl.stringByReplacingOccurrencesOfString(" ", withString: "+")
let url = NSURL(string: stringUrl)
let session = NSURLSession.sharedSession()
var muableRequest = NSMutableURLRequest(URL: url!)
muableRequest.setValue("application/json", forHTTPHeaderField: "Accept")
muableRequest.setValue("my-secret-key", forHTTPHeaderField: "X-Mashape-Key")
let task = session.dataTaskWithRequest(muableRequest, completionHandler: { (data, response, error) -> Void in
if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil){
println(jsonResult)
}
})
task.resume()
It's the same answer as #Leo's answer but the syntax for Swift changed a little which is why I think it's good to "update the answer a little". So this should work with Swift 3.
func get(_ url: String) {
if let url = URL(string: url) {
var request = URLRequest(url: url)
// Set headers
request.setValue("headerValue", forHTTPHeaderField: "headerField")
request.setValue("anotherHeaderValue", forHTTPHeaderField: "anotherHeaderField")
let completionHandler = {(data: Data?, response: URLResponse?, error: Error?) -> Void in
// Do something
}
URLSession.shared.dataTask(with: request, completionHandler: completionHandler).resume()
} else {
// Something went wrong
}

Resources