Getting 200 response, but not showing json value - json

I have wrote a networking request using the "wordsapi", and I am getting a 200 status, but the response I am receiving is not in json.
My code builds, and runs I just need the response in json.
let wordsAPI =
"https://wordsapiv1.p.mashape.com/words/money/synonyms"
let wordsAPIEndPoint = NSURL(string: wordsAPI)
let request = NSMutableURLRequest(url: wordsAPIEndPoint! as
URL)
request.setValue("mapkey", forHTTPHeaderField: "X-Mashape-Key")
request.httpMethod = "GET"
let session = URLSession.shared
let synonymResponse = session.dataTask(with: request as
URLRequest) { (data, response, error) -> Void in
if let resp = response as? HTTPURLResponse {
print(resp)
}
}
synonymResponse.resume()
//response I am receiving
{ Status Code: 200, Headers {
"Accept-Ranges" = (
bytes
);
"CF-RAY" = (
"4d4d9aacabdccf5c-IAD"
);
Connection = (
"keep-alive"
);
"Content-Length" = (
30
);
"Content-Type" = (
"application/json; charset=utf-8"
);Date = (
"Fri, 10 May 2019 17:24:00 GMT"
);
I need my response to be in json for the synonyms of whatever value I set as my endpoint. In this case it is "money"

You need to use the data var in completion that contains the received json data
let wordsAPI = "https://wordsapiv1.p.mashape.com/words/money/synonyms"
let wordsAPIEndPoint = URL(string: wordsAPI)
var request = URLRequest(url: wordsAPIEndPoint!)
request.setValue("mapkey", forHTTPHeaderField: "X-Mashape-Key")
request.httpMethod = "GET"
URLSession.shared.dataTask(with: request) { (data, response, error) -> Void in
guard let data = data else { return }
let res = try! JSONDecoder().decode(Root.self,from:data)
print(res.synonyms)
}.resume()
struct Root:Codable {
let word:String
let synonyms:[String]
}

Related

JSON data extraction in swift

I am using the following code:
let string = "https://wordsapiv1.p.mashape.com/words/?
hasDetails=examples&page=1"
let url = NSURL(string: string)
let request = NSMutableURLRequest(url: url! as URL)
request.setValue("KEY", forHTTPHeaderField: "X-Mashape-Key")
request.httpMethod = "GET"
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest) { (data, response, error) -> Void in
if let resp = response as? HTTPURLResponse {
let json = try? JSONSerialization.jsonObject(with: data!, options: [])
print(json)
}
}
task.resume()
And the following is printed by the 'print(json)' line of code:
Optional({
query = {
limit = 100;
page = 1;
};
results = {
data = (
".22 caliber",
".38 caliber",
a,
"a bit",
"a cappella",
"a couple of",
"a few",
"a great deal",
"a little",
"a lot",
"a posteriori",
"a priori",
"a trifle",
aah,
abacinate,
abaft,
abandon,
abandoned,
abandonment,
abasement,
abashed,
"abatable nuisance",
abate,
abatement,
abaxial,
abbreviated,
abdicable,
abdicate,
abdominal,
"abdominal breathing",
abduct,
aberrant,
aberrate,
abhor,
abhorrent,
"abide by",
abiding,
abject,
abjectly,
abjure,
ablated,
ablative,
ablaze,
able,
"able-bodied",
ablutionary,
abnegate,
abnegation,
abnormal,
abnormally,
aboard,
abolish,
abolition,
abominable,
abominably,
abomination,
aboral,
aboriginal,
abort,
abortive,
abound,
abounding,
about,
"about-face",
above,
"above all",
aboveboard,
aboveground,
abrasive,
abreast,
abridge,
abridged,
abroach,
abroad,
abrupt,
abscessed,
abscond,
abseil,
absence,
absent,
absently,
absentminded,
absolute,
absolutely,
absoluteness,
absolve,
absolved,
absorb,
absorbed,
absorbent,
absorptance,
absorption,
abstain,
abstemious,
abstemiously,
abstinent,
abstract,
abstractive,
abstruse,
abstrusely
);
total = 21753;
};
})
The problem is that I need to get just the data that I want from this i.e. the words.
How do I now get the data from this that I want? i.e. an array of all the words returned (from ".22 caliber" to abstrusely)
I like to use the SwiftyJson cocoapod, as its much easier to read and understand than JSONDecoder (but of course, that would work too):
import SwiftyJson
let string = "https://wordsapiv1.p.mashape.com/words/?hasDetails=examples&page=1"
let url = NSURL(string: string)
let request = NSMutableURLRequest(url: url! as URL)
request.setValue("KEY", forHTTPHeaderField: "X-Mashape-Key")
request.httpMethod = "GET"
let session = URLSession.shared
var wordArray : [String] = []
let task = session.dataTask(with: request as URLRequest) { (data, response, error) -> Void in
if let resp = response as? HTTPURLResponse {
let json : JSON = JSON(data!)
for word in json["results"]["data"] { //There's probably a way to cast directly to a [String] here instead but I'm not sure.
wordArray.append(word)
}
}
}
task.resume()

HTTP Authentication request with Campaign Monitor in Swift

I am trying to post user data to Campaign Monitor when they sign up in my app. Can anyone help me add the authorisation to the request. I currently get this error:
Optional("{\"Code\":50,\"Message\":\"Must supply a valid HTTP Basic
Authorization header\"}")
my code:
let parameters = [ "FirstName1": "test",
"SecondName": "test",
"email": "test#test.com"
]
let clientID = "52bb93ac4d9a3f261abcda0123456789"
let url = URL(string: "https://api.createsend.com/api/v3.2/clients.json")!
var request = URLRequest(url: url)
request.httpMethod = "Post"
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
} catch let error {
print(error.localizedDescription)
}
// add the API Key to the request / security
request.setValue(clientID, forHTTPHeaderField: "username") // IS THIS RIGHT??
// THiS WAS HOW I CREATED CORRECT AUTHORIZATION
let APIKey = "0069b38c27b3e44de0234567891011"
let listID = "5e61fde130969d561dc0234567891011"
let url = URL(string: "https://api.createsend.com/api/v3.2/subscribers/\(listID).json")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
// add the API Key to the request / security
let loginString = "\(APIKey)"
let loginData = loginString.data(using: String.Encoding.utf8)
let base64LoginString = loginData!.base64EncodedString()
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
} catch let error {
print(error.localizedDescription)
}
// THEN CAN SET UP THE SESSION
let session = URLSession(configuration: .default)
let task = session.dataTask(with: request) {
(data, response, error) in
if error != nil {
print("Error is: \(String(describing: error))")
}
if let response = response {
let nsHTTPResponse = response as! HTTPURLResponse
let statusCode = nsHTTPResponse.statusCode
print("status code = \(statusCode)")
}
if let data = data {
let postResponse = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: postResponse))")
}
}
task.resume()
In this line:
// add the API Key to the request / security
request.setValue(clientID, forHTTPHeaderField: "username") // IS THIS RIGHT??
It's not correct, even they told you why. You need a Basic Auth Header
For POST requests in Swift, generally you have to set the following:
request.setValue("Basic " + clientID, forHTTPHeaderField: "Authorization") // is clientID your access token?
Good luck

how to make HTTPRequest with json in swift

I am making an ios application. I am new to swift and not able to understand my code. can anyone please help me to understand what is going on with my code.
This is login application on adding email id if the email exist it should go to next view controller and if not then it should give error. I am getting difficulty in understanding my code .
Here is my code:
class checkLoginViewController: UIViewController {
#IBOutlet weak var checkUsernametextfield: UITextField!
#IBAction func checkUsernameButton(_ sender: UIButton) {
print("Clicked On SUbmit !!!!")
//Read Value from Text
let email = checkUsernametextfield.text
let myUrl = URL(string: "http://192.168.0.117/rest/signup.php");
var request = URLRequest(url:myUrl!)
request.httpMethod = "POST"// Compose a query string
let postString = "email=\(String(describing: email))";
request.httpBody = postString.data(using: String.Encoding.utf8);
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
if error != nil
{
print("error=\(String(describing: error))")
return
}
// You can print out response object
print("response = \(String(describing: response))")
//Let's convert response sent from a server side script to a NSDictionary object:
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
// Now we can access value of First Name by its key
let emailValue = parseJSON["email"] as? String
print("email: \(String(describing: emailValue))")
}
} catch {
print(error)
}
}
task.resume()
Output:
Clicked On SUbmit !!!! response = Optional( { URL: http://192.168.0.117/rest/signup.php } { Status
Code: 200, Headers {
Connection = (
"Keep-Alive"
);
"Content-Length" = (
61
);
"Content-Type" = (
"application/json"
);
Date = (
"Mon, 12 Mar 2018 06:35:58 GMT"
);
"Keep-Alive" = (
"timeout=5, max=100"
);
Server = (
"Apache/2.4.27 (Ubuntu)"
); } }) email: nil
Maybe try this. Hope it works.
let url = URL(string:"http://192.168.0.117/rest/signup.php")
let parameters = ["email": checkUsernametextfield.text]
var request = URLRequest(url : url!)
request.httpMethod = "POST"
request.httpBody = try? JSONSerialization.data(withJSONObject:parameters, options: [])
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let session = URLSession.shared
session.dataTask(with: request, completionHandler: { (data, response, error) in
if let data = data {
do {
let json = try? JSONSerialization.jsonObject(with: data, options: []) as! Dictionary<String, Any>
if let json = json {
print("HERE SHOULD BE YOUR JSON \(json)")
}
}
} else {
print("Error \(String(describing: error?.localizedDescription))")
}
}).resume()
Here is way to send request.
enter code here
static func downloadConfig(url:URL, completion:#escaping (_ sucess:Bool , _ jsonObject: [String: String]?)->() ) {
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded",
forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let postString = "id=13&name=Jack"
request.httpBody = postString.data(using: .utf8)
URLSession.shared.dataTask(with: request) { (data,response,error) in
if let data = data ,let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200 {
do {
if let todoJSON = try JSONSerialization.jsonObject(with: data, options: []) as? [String: String]{
completion(true,todoJSON)
}
else
{
completion(false,nil)
}
}
catch {
//erro parsing
completion(false,nil)
}
}
else
{
completion(false,nil)
}
}.resume()
}
use this download json function in this way.
//Download Json File
let base_url = "base_url"
let urlstr = String.init(format: "%#", base_url)
let url = URL(string: urlstr)
GameUtil.downloadConfig(url: url!) {
(sucess: Bool , jsonObject: [String:String]?) in
if sucess , jsonObject != nil
{
self.configJson = jsonObject!
}
}

How to send a POST request through Swift?

I have my controller like this -
def create
if (#user = User.find_by_email(params[:email])) && #user.valid_password?(params[:password])
render json: #user.as_json(only: [:email,:authentication_token]),status: :created
else
render json:('Unauthorized Access')
end
end
When I use Postman to make this request, I choose Body, and form data and adds in the email and password. And this WORKS
How to use swift to do the same? This is what I have tried
let url = URL(string: "http://localhost:3000/api/v1/user_serialized/")
let config = URLSessionConfiguration.default
let request = NSMutableURLRequest(url: url!)
request.httpMethod = "POST"
let bodyData = "email=Test#test.com&password=Test1234"
request.httpBody = bodyData.data(using: String.Encoding.utf8);
let session = URLSession(configuration: config)
let task = session.dataTask(with: url! as URL, completionHandler: {(data, response, error) in
let json = JSON(data:data!)
debugPrint(json)
})
task.resume()
I have made a Custom HTTP class where we can sent url, parameter and we will get Data from API. Below is the class.
import Foundation
//HTTP Methods
enum HttpMethod : String {
case GET
case POST
case DELETE
case PUT
}
class HttpClientApi: NSObject{
//TODO: remove app transport security arbitary constant from info.plist file once we get API's
var request : URLRequest?
var session : URLSession?
static func instance() -> HttpClientApi{
return HttpClientApi()
}
func makeAPICall(url: String,params: Dictionary<String, Any>?, method: HttpMethod, success:#escaping ( Data? ,HTTPURLResponse? , NSError? ) -> Void, failure: #escaping ( Data? ,HTTPURLResponse? , NSError? )-> Void) {
request = URLRequest(url: URL(string: url)!)
logging.print("URL = \(url)")
if let params = params {
let jsonData = try? JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
request?.setValue("application/json", forHTTPHeaderField: "Content-Type")
request?.httpBody = jsonData//?.base64EncodedData()
//paramString.data(using: String.Encoding.utf8)
}
request?.httpMethod = method.rawValue
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 30
configuration.timeoutIntervalForResource = 30
session = URLSession(configuration: configuration)
//session?.configuration.timeoutIntervalForResource = 5
//session?.configuration.timeoutIntervalForRequest = 5
session?.dataTask(with: request! as URLRequest) { (data, response, error) -> Void in
if let data = data {
if let response = response as? HTTPURLResponse, 200...299 ~= response.statusCode {
success(data , response , error as? NSError)
} else {
failure(data , response as? HTTPURLResponse, error as? NSError)
}
}else {
failure(data , response as? HTTPURLResponse, error as? NSError)
}
}.resume()
}
}
Now you can refer below code to get how to make an API call.
var paramsDictionary = [String:Any]()
paramsDictionary["username"] = "BBB"
paramsDictionary["password"] = "refef"
HttpClientApi.instance().makeAPICall(url: "Your URL", params:paramsDictionary, method: .POST, success: { (data, response, error) in
// API call is Successfull
}, failure: { (data, response, error) in
// API call Failure
})
I think you should pass your request instead of the url to session.dataTask
here is how my code looks like:
private let url = URL(string: "http://example.com/")!
func httpPost(jsonData: Data) {
if !jsonData.isEmpty {
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = jsonData
URLSession.shared.getAllTasks { (openTasks: [URLSessionTask]) in
NSLog("open tasks: \(openTasks)")
}
let task = URLSession.shared.dataTask(with: request, completionHandler: { (responseData: Data?, response: URLResponse?, error: Error?) in
NSLog("\(response)")
})
task.resume()
}
}
Here is the Example of POST API for calling Login API with parameters "emailaddress" and "password" with userEmailID and Userpassword as two strings holding values for email and password respectively.
You can call this POST API anywhere in your view controller, as given below:
self.postLoginCall(url: "Your post method url") example: self.postLoginCall(url: "http://1.0.0.1/api/login.php")
func postLoginCall(url : String){
let request = NSMutableURLRequest(url: NSURL(string: url)! as URL)
request.httpMethod = "POST"
let postString = "emailaddress=\(userEmailID!)&password=\(Userpassword!)"
print(postString)
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpBody = postString.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in
guard error == nil && data != nil else { // check for fundamental networking error
print("error=\(error)")
return
}
do {
if let responseJSON = try JSONSerialization.jsonObject(with: data!) as? [String:AnyObject]{
print(responseJSON)
print(responseJSON["status"]!)
self.response1 = responseJSON["status"]! as! Int
print(self.response1)
//Check response from the sever
if self.response1 == 200
{
OperationQueue.main.addOperation {
//API call Successful and can perform other operatios
print("Login Successful")
}
}
else
{
OperationQueue.main.addOperation {
//API call failed and perform other operations
print("Login Failed")
}
}
}
}
catch {
print("Error -> \(error)")
}
}
task.resume()
}
Hello everyone I share below an example of a function to make a request in POST with SWIFT 5+.
This function allows you to send a POST request with an API entry point and parameters in the form of [[String: String]] and an Int to determine the output action.
For the output actions we call a function with Switch Case.
The operation is extremely simple. You have to put the two functions in one of your classes.
func MGSetRequestApi(endpoint: String, parameters: [[String: String]], MGSetAction: Int) -> String {
var setReturn: String!
let semaphore = DispatchSemaphore (value: 0)
var MGGetParam: String! = ""
for gate in parameters {
for (key, value) in gate {
let myParam = key + "=" + value + "&"
MGGetParam.append(contentsOf: myParam)
}
}
let postData = MGGetParam.data(using: .utf8)
var request = URLRequest(url: URL(string: endpoint)!,timeoutInterval: 10000)
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = postData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print(String(describing: error))
semaphore.signal()
return
}
print(String(data: data, encoding: .utf8)!)
setReturn = String(data: data, encoding: .utf8)!
DispatchQueue.main.async {
self.MGRequestAction(MGGetIdRq: MGSetAction, MGGetData: setReturn)
}
semaphore.signal()
}
task.resume()
semaphore.wait()
return setReturn
}
Then implement this function to manage the outputs
func MGRequestAction(MGGetIdRq: Int, MGGetData: String) {
switch MGGetIdRq {
case 1:
// Do something here
case 2:
// Do something else here
case 3:
// Do something else here again
default:
print("Set default action");
}
}
How to use this, you have two possibilities, the first one is to process what the function
MGSetRequestApi(endpoint: String, parameters: [[String: String]], MGSetAction: Int) -> String
returns (String) or to pass by the function
MGRequestAction(MGGetIdRq: Int, MGGetData: String)
which will call your Json parse function.
The MGRequestAction() function takes for parameter an Int for the choice of the action and the String of the return of the request
Now to use it do like this:
_ = MGSetRequestApi(endpoint: MY_END_POINT_API,
parameters: [["KEY_1": "VALUE 1"],
["KEY_2": "VALUE 2"],
["KEY_3": "VALUE 3"],
["KEY_4": "VALUE 4"]],
MGSetAction: 3)

How to POST JSON data using NSURLSession in swift

I am stuck with the below code. How do I set the param and in post method?
let params:[String:Any] = [
"email" : usr,
"userPwd" : pwdCode]
let url = NSURL(string:"http://inspect.dev.cbre.eu/SyncServices/api/jobmanagement/PlusContactAuthentication")
let request = NSMutableURLRequest(URL: url!)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPBody = params<what should do for Json parameter>
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if let httpResponse = response as? NSHTTPURLResponse {
if httpResponse.statusCode != 200 {
println("response was not 200: \(response)")
return
}
}
if error {
println("error submitting request: \(error)")
return
}
// handle the data of the successful response here
}
task.resume()
if I understand the question correctly
var configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
var session = NSURLSession(configuration: configuration)
var usr = "dsdd"
var pwdCode = "dsds"
let params:[String: AnyObject] = [
"email" : usr,
"userPwd" : pwdCode ]
let url = NSURL(string:"http://localhost:8300")
let request = NSMutableURLRequest(URL: url!)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
var err: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions.allZeros, error: &err)
let task = session.dataTaskWithRequest(request) {
data, response, error in
if let httpResponse = response as? NSHTTPURLResponse {
if httpResponse.statusCode != 200 {
println("response was not 200: \(response)")
return
}
}
if (error != nil) {
println("error submitting request: \(error)")
return
}
// handle the data of the successful response here
var result = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: nil) as? NSDictionary
println(result)
}
task.resume()
I would suggest using AFNetworking. See for example, Posting JSON data using AFNetworking 2.0.
This is how you can set parameters and send a POST request, easy approach using Alamofire.
Swift 2.2
let URL = NSURL(string: "https://SOME_URL/web.send.json")!
let mutableURLRequest = NSMutableURLRequest(URL: URL)
mutableURLRequest.HTTPMethod = "POST"
let parameters = ["api_key": "______", "email_details": ["fromname": "______", "subject": "this is test email subject", "from": "support#apple.com", "content": "<p> hi, this is a test email sent via Pepipost JSON API.</p>"], "recipients": ["_________"]]
do {
mutableURLRequest.HTTPBody = try NSJSONSerialization.dataWithJSONObject(parameters, options: NSJSONWritingOptions())
} catch {
// No-op
}
mutableURLRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
Alamofire.request(mutableURLRequest)
.responseJSON { response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}