Hi guys below is my code im using at the moment im making a pos system and talk to a merchant and return talks to a pin pad .
the problem i have is that when i do a purchase for the first time it works 100 percent i get a response from the service
. but when i do another purchase and it does the call nothing happens .
im wondering if the task inst done yet . i dont know whats going on any help
only way i can do another call is by restarting the app
func pinPad(Total:Int,echoData:Int64,retrievalReferenceNumber:Int64, cardAcceptorTerminalId:Int64,cardAcceptorIdCode:Int64) -> String
{
getdata()
var status:String = ""
let Message = "<?xml version='1.0' encoding='utf-8'?>"
var is_URL: String = "http://\(ipcon):\(portcon)/merchant/service"
var session = URLSession.shared
var lobj_Request = NSMutableURLRequest(url: NSURL(string: is_URL)! as URL)
var task: URLSessionTask? = nil
var err: NSError?
lobj_Request.httpMethod = "POST"
lobj_Request.httpBody = Message.data(using: String.Encoding.utf8)
lobj_Request.addValue("http://\(ipcon):\(portcon)", forHTTPHeaderField: "Host")
lobj_Request.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
// lobj_Request.addValue(String(count(Message)), forHTTPHeaderField: "Content-Length")
//lobj_Request.addValue("223", forHTTPHeaderField: "Content-Length")
lobj_Request.addValue("http://\(ipcon):\(portcon)/merchant/service", forHTTPHeaderField: "SOAPAction")
print("helo: \(lobj_Request)")
if nil != task{
task!.cancel()
task = nil
}
let sem = DispatchSemaphore(value: 0)
task = session.dataTask(with: lobj_Request as URLRequest){ data, response, error in
if error != nil{
return
}else{
let strData = NSString(data: (data)!, encoding: String.Encoding.utf8.rawValue) as! String
print("Body: \(strData)")
let xml = SWXMLHash.config {
config in
config.shouldProcessLazily = true
}.parse(strData)
if(xml["S:Envelope"]["S:Body"]["responseCode"].element?.text != nil)
{
status = xml["S:Envelope"]["S:Body"]["responseCode"].element!.text
}
else{
status = xml["S:Envelope"]["S:Body"]["ns2:responseCode"].element!.text
}
sem.signal()
}
}
task?.resume()
sem.wait()
session.invalidateAndCancel()
return status
}
Related
I am getting German language string in api response. It is like :
{ address = "Walliser Str. R?ckhaltebeckenBremen";
companyName = "Fressnapf Bad T\U00f6lz";
}
I need to display these strings into a uilabel in proper German language.
My question is how to encode these string into proper form?? Or is it something needs to be done from server side??
Code that I am using for api call:
let url = URL(string: "\(globalURL)/apiName")
var request = URLRequest(url: url!)
request.timeoutInterval = 30
let body = try? JSONSerialization.data(withJSONObject: parameterField)
request.addValue(apiKey, forHTTPHeaderField: "x-api-key")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = body
let task = URLSession.shared.dataTask(with: request){(data,response,error)in
guard let dataResponse = data,
error == nil else {
print(error?.localizedDescription as Any)
var jsonResponse : NSMutableDictionary = NSMutableDictionary()
jsonResponse.setValue(false, forKey: "success")
jsonResponse.setValue(error?.localizedDescription as! String, forKey: "message")
completion(jsonResponse)
return
}
do{
var jsonResponse : NSDictionary!
jsonResponse = try JSONSerialization.jsonObject(with: dataResponse, options: .allowFragments)as? NSDictionary
print(jsonResponse)
completion(jsonResponse)
} catch let parsingError {
print("an error occurred parsing json data : \(parsingError)")
}
}
task.resume ()
Thanks!!!
i created soap web services and trying to connect actually it was working before updating xcode after update it occurred a few mistakes ass you see below. Any idea how can i fix it! Thank you.
Try this without ConnectionDataDelegate
func servisRun(xml:String!){
let soapMessage = xml
let msgLength = String(describing: soapMessage?.characters.count)
let url = URL(string: "http....")
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)
let session = URLSession.shared
let task = session.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)
}
task.resume()
let xmlParser = XMLParser(data: mutableData as Data)
xmlParser.delegate = self
xmlParser.parse()
xmlParser.shouldResolveExternalEntities = true
}
The method fails to return a value got from a GET request where variable res can be printed in the task section, but fails to return it in the end.
func lookUpTheWord(word:String) -> NSDictionary {
var res = NSDictionary()
let urlString = "https://wordsapiv1.p.mashape.com/words/" + word
if let url = NSURL(string:urlString) {
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "GET"
request.addValue("this is a key", forHTTPHeaderField: "X-Mashape-Key")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
print("\(error)")
return
}
res = self.toJson(data!)
print(res) //it works here
}
task.resume()
}
return res //res becomes nil
}
That is because you're returning the variable res before it has been assigned. You'll notice that the res that isn't nil is printed after the one that is after it. This is because the HTTP request doesn't happen instantly - code after it is executed before it is finished, therefore it is called "asynchronous".
If you want to use the variable acquired in the HTTP request, use a closure as a parameter in your function and call it when the request is finished. Example:
func lookUpTheWord(word:String, completion: (NSDictionary->Void)) {
var res = NSDictionary()
let urlString = "https://wordsapiv1.p.mashape.com/words/" + word
if let url = NSURL(string:urlString) {
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "GET"
request.addValue("this is a key", forHTTPHeaderField: "X-Mashape-Key")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
res = self.toJson(data!)
completion(res)
}
}
task.resume()
}
}
Used like this:
lookUpTheWord("word") { res in
print(res)
}
I keep getting this error which I don't know how to resolve!
I'm trying to parse access token from a web API and for that I've set up post request.
Somehow it's throwing an error on 'responseString' line.
import UIKit
import Foundation
class ViewController: UIViewController, NSURLConnectionDelegate {
#IBOutlet var userName: UITextField!
#IBOutlet var password: UITextField!
#IBAction func submit(sender: AnyObject) {
let postString = "username=" + userName.text + "&password=" + password.text + "&grant_type=password";
let data: NSData = postString.dataUsingEncoding(NSUTF8StringEncoding)!
let base64LoginString = data.base64EncodedStringWithOptions(nil)
let postLength=NSString(format: "%ld", data.length)
let url = NSURL(string: "http://www.myurl.com/Token")
let request = NSMutableURLRequest(URL: url!);
request.HTTPMethod = "POST"
request.HTTPBody = data
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.addValue(base64LoginString, forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {data, response, error in
if error != nil {
println("error = \(error)")
return
}
//print out response object
println("******* response = \(response)")
//print out response body // THIS LINE THROWS STATUS CODE 400 ERROR
let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
println("******* response data = \(responseString)")
var err: NSError?
var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &err) as? NSDictionary
if let parseJSON = json {
var token = parseJSON["access_token"] as? String
println("token: \(token)")
}
}
task.resume()
}
This is the error
******* response = <NSHTTPURLResponse: 0x7ff1eb4496d0> { URL: https://www.myurl.com/Token } { status code: 400, headers {
"Cache-Control" = "no-cache";
"Content-Length" = 34;
"Content-Type" = "application/json;charset=UTF-8";
Date = "Mon, 10 Aug 2015 20:16:14 GMT";
Expires = "-1";
Pragma = "no-cache";
"X-Powered-By" = "ASP.NET";
} }
Your error seems to be incorrect usage of basic auth format. It should be like this:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
where
QWxhZGRpbjpvcGVuIHNlc2FtZQ==
is username:password in base64
So in your case it is like this :
let postString = userName.text + ":" + password.text ;
let data: NSData = postString.dataUsingEncoding(NSUTF8StringEncoding)!
let base64LoginString = data.base64EncodedStringWithOptions(nil)
let postLength=NSString(format: "%ld", data.length)
let url = NSURL(string: "http://www.myurl.com/Token")
let request = NSMutableURLRequest(URL: url!);
request.HTTPMethod = "POST"
request.HTTPBody = ""
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.addValue("Basic " + base64LoginString, forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("0", forHTTPHeaderField: "Content-Length")
btw it would be a lot easier to find your error if you provide your api url
The error code 400 says that the server doesn't understand for request, maybe the request is malformed. This is very likely a client side issue. However, I've written a simple python http server, and used the code above (with only change to the URL entry point), everything works. I strongly suggest that you should check the API documentation on the backend and find out why your backend server doesn't recognize your request. Your client side code seems correct.
Try this on your own:
Create myserver.py, and add the following lines to it:
from flask import Flask, request
app = Flask(__name__)
#app.route('/Token', methods=['POST'])
def hello_world():
print(request.form)
return 'Hello World!'
if __name__ == '__main__':
app.run()
Run this python script from terminal, and change http://www.myurl.com to http://127.0.0.1:5000, you'll see that the request gets through, and the server can correctly parse your username password, etc.
It's always a good idea to try to setup your own local web server to mock the backend during debugging/development according to backend API specification.
try this one
//first make json object.you can use your object for this one.
let JSONObject: [String : AnyObject] = [
"DeviceHash" : UUIDValue,
"DeviceName" : deviceNameValue!,
"SerialKey": serialKeyValue!,
]
if NSJSONSerialization.isValidJSONObject(JSONObject) {
var request: NSMutableURLRequest = NSMutableURLRequest()
let url = "Your Url"
var err: NSError?
request.URL = NSURL(string: url)
request.HTTPMethod = "POST"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
do {
request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(JSONObject, options: NSJSONWritingOptions())
print(JSONObject)
} catch {
print("bad things happened")
}
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue()) {(response, data, error) -> Void in
let httpResponse = response as! NSHTTPURLResponse
if error != nil {
print("error")
}else {
print(response)
}
}
}
I have a function which posts a dictionary back to the server and return the status code or error content when there's an error. It works fine sometimes, while the rest of the time the completion section is skipped.
func postData(url: String, query: NSDictionary) ->NSObject? {
var error: NSError?
var result: NSObject? = nil
let dest = NSURL("http://myUrl.com")
let request = NSMutableURLRequest(URL: dest!)
request.HTTPMethod = "POST"
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(query, options: NSJSONWritingOptions.allZeros, error: &err)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){
data, response, error in
if(error != nil){
println(error)
result = error
return
}
result = (response as! NSHTTPURLResponse).statusCode
return
}
task.resume()
return result
}
I referred to NSURLSession dataTaskWithRequest not being called, and knew that it may caused by executing time lag. However, since I need the status code (which returns nil so far) to determine the actions to do after the post, I'm wondering how I could solve this problem?
Your method is async method,you can not get return from this.
You can pass in a block to handle your action with return
func postData(url: String, query: NSDictionary,finished:(NSObject)->()) {
var error: NSError?
var result: NSObject? = nil
let dest = NSURL("http://myUrl.com")
let request = NSMutableURLRequest(URL: dest!)
request.HTTPMethod = "POST"
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(query, options: NSJSONWritingOptions.allZeros, error: &err)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){
data, response, error in
if(error != nil){
println(error)
result = error
return
}
finished((response as! NSHTTPURLResponse).statusCode)
}
task.resume()
}
Then use it
postData(url, dic) { (object:NSObject) -> () in{
//use here
}