I have the following function to establish the connection synchronously with the sever on a particular IP and port, send a JSON request to sever and return the server's response to the calling function.
func connserv(jsonString:NSDictionary){
var abc: NSDictionary?
// This is the action performed when clicked on the Connect button on the connectivity screen
println("------------------Function connserv")
let prefs = NSUserDefaults.standardUserDefaults()
var IP: AnyObject = prefs.objectForKey("IP")!
var port: AnyObject = prefs.objectForKey("Port")!
println("IP in Connection : \(IP)")
println("port in Connection : \(port)")
prefs.synchronize()
let localizedModel = UIDevice.currentDevice().localizedModel
let model = UIDevice.currentDevice().model
let devicesystemVersion = UIDevice.currentDevice().systemVersion
println("HTTP request jsonString : \(jsonString)")
var request = NSMutableURLRequest(URL: NSURL(string: "https://\(IP):\(port)/")!)
var response: NSURLResponse?
//var request: NSURLRequest = NSURLRequest(URL: NSURL(string: "https://\(IP):\(port)/")!)
//var response: AutoreleasingUnsafeMutablePointer<NSURLResponse?>=nil
var error: NSError?
var err: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(jsonString, options: nil, error: &err)
request.HTTPMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
// send the request
println("HTTP request : \(request)")
var e: NSError?
NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &e)
debugPrintln(response)
println("response-------------------------> : \(response)")
}
When the above function executed, server does not receive any thing and gives the following error:
HTTP request : <NSMutableURLRequest: 0x7c8bb240> { URL: https://144.1.1.45:9299/ }
2015-04-07 11:16:59.661 MyApp[996:24843] NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)nil
response-------------------------> : nil
2015-04-07 11:16:59.663 MyApp[996:24600] Unknown class UIAlert in Interface Builder file.
I want to return server response (variable response) to the calling function of the connserv function. Please help me to achieve this requirement.
Related
So I have my send email function as seen below:
func email() {
let session = URLSession.shared
let request = NSMutableURLRequest(url: NSURL(string: "https://api.mailgun.net/v3/sandbox################################/messages")! as URL)
request.httpMethod = "POST"
let credentials = "api:key-################################-########-########"
request.setValue("Basic \(credentials.toBase64())", forHTTPHeaderField: "Authorization")
let data = "from: Swift Email <(test#test.com)>&to: [myemail#gmail.com,(myemail#gmail.com)]&subject:Hello&text:Testing_some_Mailgun_awesomness"
request.httpBody = data.data(using: String.Encoding.ascii)
let task = session.dataTask(with: request as URLRequest, completionHandler: {(data, response, error) in
if let error = error {
print(error)
}
if let response = response {
print("url = \(response.url!)")
print("response = \(response)")
let httpResponse = response as! HTTPURLResponse
print("response code = \(httpResponse.statusCode)")
}
})
task.resume()
}
So I guess either my API key is wrong or my request URL is wrong. To find my request URL, I went to https://app.mailgun.com/app/dashboard and then scrolled down to the Sending Domains section and copied that. To get my API key I went to https://app.mailgun.com/app/account/security/api_keys and just copied the Private API Key. I'm really not sure why I'm getting this invalid code--thank you in advance if you figure it out!
Side note: Not really sure if the data constant is set up right (in terms of missing or having too many parens), so if you could check that too that would be phenomenal.
I have a software called "paw" it helps forming REST API call for Xcode, curl, php, etc.
I don't know if this could help you
class MyRequestController {
func sendRequest(somevar: String, completion: #escaping (Books) -> Void) {
/* Configure session, choose between:
* defaultSessionConfiguration
* ephemeralSessionConfiguration
* backgroundSessionConfigurationWithIdentifier:
And set session-wide properties, such as: HTTPAdditionalHeaders,
HTTPCookieAcceptPolicy, requestCachePolicy or timeoutIntervalForRequest.
*/
let sessionConfig = URLSessionConfiguration.default
/* Create session, and optionally set a URLSessionDelegate. */
let session = URLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)
/* Create the Request:
(POST https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages)
*/
guard var URL = URL(string: "https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages") else {return}
var request = URLRequest(url: URL)
request.httpMethod = "POST"
// Headers
request.addValue("Basic YXBpOllPVVJfQVBJX0tFWQ==", forHTTPHeaderField: "Authorization")
request.addValue("multipart/form-data; charset=utf-8; boundary=__X_PAW_BOUNDARY__", forHTTPHeaderField: "Content-Type")
// Body
let bodyString = "--__X_PAW_BOUNDARY__\r\nContent-Disposition: form-data; name=\"from\"\r\n\r\n'Excited User <mailgun#YOUR_DOMAIN_NAME>'\r\n--__X_PAW_BOUNDARY__\r\nContent-Disposition: form-data; name=\"to\"\r\n\r\nYOU#YOUR_DOMAIN_NAME\r\n--__X_PAW_BOUNDARY__\r\nContent-Disposition: form-data; name=\"to\"\r\n\r\nbar#example.com\r\n--__X_PAW_BOUNDARY__\r\nContent-Disposition: form-data; name=\"subject\"\r\n\r\n'Hello'\r\n--__X_PAW_BOUNDARY__\r\nContent-Disposition: form-data; name=\"text\"\r\n\r\n'Testing some Mailgun awesomeness!'\r\n--__X_PAW_BOUNDARY__--\r\n"
request.httpBody = bodyString.data(using: .utf8, allowLossyConversion: true)
/* Start a new Task */
let task = session.dataTask(with: request, completionHandler: { (data: Data?, response: URLResponse?, error: Error?) -> Void in
if (error == nil) {
// Success
let statusCode = (response as! HTTPURLResponse).statusCode
print("URL Session Task Succeeded: HTTP \(statusCode)")
}
else {
// Failure
print("URL Session Task Failed: %#", error!.localizedDescription);
}
})
task.resume()
session.finishTasksAndInvalidate()
}
}
**** and you CALL this function a bit like this
MyRequestController().sendRequest(somevar: "something")
take a look at https://www.youtube.com/watch?v=44APgBnapag for more details
this tutorial show how to do REST API calls with Xcode, this example it scan a barcode, send the scanned code via a function that calls the API and return infos...
I want to use the URLSession to send a json data that store the detail information to the server bought from vultr. The url is the server ip address and I already set the username and password in the postParams and set the request's httpBody property. The problem is that I can't connect the server.
I thought it should be the problem that I fail to connect to the server. I just buy a server and do nothing to it. The server has a username and a password. I don't know whether I should first setup the server or if I can use it directly after finishing the purchase.
private func sendData() {
let url = URL(string: "https://xxx.xxx.xxx.xxx")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let postParams = "username=root&password=*****"
let postData = postParams.data(using: .utf8)
request.httpBody = postData
let task = URLSession.shared.uploadTask(with: request, fromFile: AppDelegate.data.filename!) { data, response, error in
if let error = error {
print("error: \(error)")
return
}
guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
print("server error")
return
}
if let mimeType = response.mimeType, mimeType == "application/json", let data = data, let dataString = String(data: data, encoding: .utf8) {
print("got data: \(dataString)")
}
}
task.resume()
}
The error message is shown as followed:
2019-09-07 21:02:46.880119+0800 HeadGaze[2241:445676] Task .<1> finished with error - code: -1004
error: Error Domain=NSURLErrorDomain Code=-1004 "Could not connect to the server." UserInfo={NSUnderlyingError=0x2807e0f30 {Error Domain=kCFErrorDomainCFNetwork Code=-1004 "(null)" UserInfo={_kCFStreamErrorCodeKey=61, _kCFStreamErrorDomainKey=1}}, NSErrorFailingURLStringKey=https://155.138.243.166/, NSErrorFailingURLKey=https://155.138.243.166/, _kCFStreamErrorDomainKey=1, _kCFStreamErrorCodeKey=61, NSLocalizedDescription=Could not connect to the server.}
I would like with an API -Key and authenticate user . I have the message " Session URL Task Succeeded : HTTP 200 " get in the Console . Unfortunately, I always get the message of the page " {" message " : " . Authorization has been denied for this request " } " . I spent hours looking for and found a solution . I ask for your help . Here is my code :
let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)
let URL = NSURL(string: "https://api.testhomepage.com/api/contact")
let request = NSMutableURLRequest(URL: URL!)
// Headers
request.addValue("ARRAffinity=259dfjiehfs315d7249df8805c7895a98c4cbd3327ffdcb82aaa16317f2e6", forHTTPHeaderField: "Cookie")
request.addValue("Basic dWVzQGp1bGl0ZafdgfvcfgeDcyZS1hZWEyLTQzYmVmMjFhNDMxZQ==", forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("api.testhomepage.com", forHTTPHeaderField: "Host")
request.addValue("//api.testhomepage.com/api/contact: POST", forHTTPHeaderField: "https")
request.HTTPMethod = "GET"
// JSON Body
/* Start a new Task */
let task = session.dataTaskWithRequest(request) { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
if (error == nil) {
// Success
let statusCode = (response as! NSHTTPURLResponse).statusCode
print("URL Session Task Succeeded: HTTP \(statusCode)")
let myURLString = "https://api.testhomepage.com/api/contact"
if let myURL = NSURL(string: myURLString) {
var error: NSError?
let myhtml = try! NSString(contentsOfURL: myURL, encoding: NSUTF8StringEncoding)
if let error = error {
print("Error : \(error)")
} else {
print("HTML : \(myhtml)")
}
} else {
print("Error: \(myURLString) doesn't seem to be a valid URL")
}
}
else {
// Failure
print("URL Session Task Failed: %#", error!.localizedDescription);
}
}
task.resume()
}
This is in the console:
URL Session Task Succeeded: HTTP 200
HTML : {"Message":"Authorization has been denied for this request."}
use request.setvalue("", forHTTPHeaderField: "") instead of request.addValue("", forHTTPHeaderField: "")
You cannot populate the Authentication header yourself, period. That header is owned by the URL loading system, and is populated based on credentials in the user's keychain.
You can learn about how to do authentication by reading the authentication chapter of URL Session Programming Guide. Note that the examples are for NSURLConnection, but the rest of the text applies to both.
Alternatively, you can store the credentials in the keychain as an Internet Password item, as described in Keychain Services Programming Guide.
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)
}
}
}
Can I return the server response from any function to its calling function using any of the Network API like AFNetworking, MKNetworkKit etc, in iPhone.
Currently I am using httpGet function of NSURLRequest. I made the following function but I am not able to return the server response to it calling function. Please help me.
func connserv(jsonString:NSDictionary) -> NSDictionary{
var abc: NSDictionary?
// This is the action performed when clicked on the Connect button on the connectivity screen
println("------------------Function connserv")
let prefs = NSUserDefaults.standardUserDefaults()
var IP: AnyObject = prefs.objectForKey("IP")!
var port: AnyObject = prefs.objectForKey("Port")!
println("IP in Connection : \(IP)")
println("port in Connection : \(port)")
prefs.synchronize()
//var learn = LearnNSURLSession()
let localizedModel = UIDevice.currentDevice().localizedModel
let model = UIDevice.currentDevice().model
let devicesystemVersion = UIDevice.currentDevice().systemVersion
println("HTTP request jsonString : \(jsonString)")
var request = NSMutableURLRequest(URL: NSURL(string: "https://\(IP):\(port)/")!)
var response: NSURLResponse?
var error: NSError?
//println("HTTP request jsonString : \(jsonString)")
var err: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(jsonString, options: nil, error: &err)
request.HTTPMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
// send the request
var learn = LearnNSURLSession()
println("HTTP request : \(request)")
learn.httpGet(request) {
(resultString, error) -> Void in
if error != nil
{
println("completion block")
}
else
{
let data = (resultString as NSString).dataUsingEncoding(NSUTF8StringEncoding)
var er: NSError?
let JSONdata: AnyObject = NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers,error: &er)!
let abc: AnyObject = NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves, error:&er)!
println("abc : \(abc)")
println("JSONdata : \(JSONdata)")
learn.callback(result: resultString, error: error)
}
}
//return abc!;
}
I do not know how your LearnNSURLSession class works, so I cannot suggest a solution with that. But here is how to find the returned headers and status, together with the returned data and any error information, from an NSURLConnection, documented here:
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.currentQueue(), completionHandler: {
response, data, error in
if let response = response as? NSHTTPURLResponse {
debugPrintln(response.allHeaderFields)
let statusCode = response.statusCode
debugPrintln("statusCode: \(statusCode): \(NSHTTPURLResponse.localizedStringForStatusCode(statusCode))")
} else { println("That's odd.") }
})
While that documentation suggests that the response is an NSURLResponse, this page makes clear that you will get a NSHTTPURLResponse which contains all the headers and status.
If you need a synchronous version, that will stop the function until it gets a result, you can use this call instead, like this:
var response:NSURLResponse?
var e: NSError?
NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &e)
debugPrintln(response)
That will allow you to return a meaningful result to the caller.