swift 3 REST api - get call returns 1 byte instead of 1 (as an int), why? - rest

So I am trying to get a number from my DB. My get call returns 1 when I use postman. However when I run this code underneath, I get 1 byte.
func getDbVersionFromServer(callback: #escaping (_ serverDbVersion: Int16)-> ()) {
let urlPath = "\(baseApiUrl)/users/getDBVersion"
let url = NSURL(string: urlPath)
let session = URLSession.shared
let request = NSMutableURLRequest(url: url as! URL)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
getTokensFromDB(){dbTokens in
request.addValue(dbTokens["accessToken"]!, forHTTPHeaderField: "accessToken")
request.addValue(dbTokens["refreshToken"]!, forHTTPHeaderField: "refreshToken")
request.httpMethod = "GET"
let task = session.dataTask(with: request as URLRequest, completionHandler: {data, response, error -> Void in
if let httpResponse = response as? HTTPURLResponse {
if (httpResponse.statusCode == 200){
let aToken = httpResponse.allHeaderFields["accessToken"] as? String
updateAccessTokenOnly(newAccessToken: aToken!)
let dbVersion = data
print("here is data: \(data!) and here is dbVersion \(dbVersion!)")
callback(0)
}
}
})
task.resume()
}
}
What am I doing wrong here? And how do I get my 1? Thanks in advance!

data is type of Data so if your response is not returning JSON you can use String(data:encoding:) to get your expected result.
let task = session.dataTask(with: request as URLRequest, completionHandler: {data, response, error -> Void in
if let httpResponse = response as? HTTPURLResponse {
if (httpResponse.statusCode == 200){
let aToken = httpResponse.allHeaderFields["accessToken"] as? String
updateAccessTokenOnly(newAccessToken: aToken!)
if let data = data, let stringResponse = String(data: data, encoding: .utf8) {
print("Response \(stringResponse)")
}
callback(0)
}
}
})
task.resume()

Related

Sending emails with Swift using Mailgun

func test() {
let session = URLSession.shared
var request = URLRequest(url: URL(string: "https://api.mailgun.net/v3/sandbox(Personal info).mailgun.org/messages")!)
request.httpMethod = "POST"
let data = "from: Excited User <(Personal info)>&to: [bar#example.com,(Personal info)]&subject:Hello&text:Testinggsome Mailgun awesomness!"
request.httpBody = data.data(using: .ascii)
request.setValue("key-(Personal info)", forHTTPHeaderField: "api")
let task = session.dataTask(with: request, 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()
}
Currently running with the above code and I am getting a 401 error. I have confirmed that the credentials are correct. Any suggestions?
TRY
func email() {
let session = URLSession.shared
let request = NSMutableURLRequest(url: NSURL(string: "https://api.mailgun.net/v3/{edited_out}/messages")! as URL)
request.httpMethod = "POST"
let credentials = "api:key-{omitted}"
request.setValue("Basic \(credentials.toBase64())", forHTTPHeaderField: "Authorization")
let data = "from: Swift Email <(test#test.com)>&to: [my_email_address#gmail.com,(my_email_address#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()
}
extension String {
func fromBase64() -> String? {
guard let data = Data(base64Encoded: self) else {
return nil
}
return String(data: data, encoding: .utf8)
}
func toBase64() -> String {
return Data(self.utf8).base64EncodedString()
}
}

Returning data from URLSession in Swift

I have tried to research this issue and am unable to find a suitable fix. I attached an image of the code. I am trying to return the subscriptions array which is declared before the URLSession, and data is appended during the URLSession. However, it returns the originally declared, empty array. I added print statements so you can understand what I am talking about. It prints 2 before 1.
let request = NSMutableURLRequest(url: NSURL(string: "https://utelly-tv-shows-and-movies-availability-v1.p.rapidapi.com/lookup?term=\(searchShow)&country=us")! 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) {
//let json = try? JSONSerialization.jsonObject(with: data!, options: [])
//print(json)
} else {
//let httpResponse = response as? HTTPURLResponse
let decoder = JSONDecoder()
let json = try! decoder.decode(results.self, from: data!)
//print(json) (for debugging use only)
//print(httpResponse)
for item in json.results{
for each in item.locations{
subscriptions.append(each.display_name)
}
}
//Remove duplicates from array
let uniqueUnordered = Array(Set(subscriptions))
let uniqueOrdered = Array(NSOrderedSet(array: uniqueUnordered))
subscriptions = uniqueOrdered as! [String]
//Print subscriptions array
print("1: \(subscriptions)")
}
})
dataTask.resume()
print("2: \(subscriptions)")
return subscriptions

Swift: How to add Dictionary format in forHTTPHeaderField in GET request

In GET request, I am trying to add header.
request.setValue(value: String?, forHTTPHeaderField: "SessionInfo")
But, SessionInfo value is in [String : Any]
Attempt 1:
func SO_Function() {
let service_url = WebService.sharedManager().serviceURL
let getMenuURL = service_url + "/MyPage/FileDownload.ashx"
var convertedString = ""
do {
let data1 = try JSONSerialization.data(withJSONObject: WebService.sharedManager().mobInfoDict, options: [])
convertedString = String(data: data1, encoding: .utf8)!
print("\n\nconvertedJSONtoData ", convertedString)
} catch {
print("\n\nCAtcLL___Err ",error.localizedDescription)
}
let url = NSURL(string: getMenuURL)
let request = NSMutableURLRequest(url: url! as URL)
//Below line, If I can able to add [String:Any] then I will get
proper Image as output.
request.setValue(convertedString, forHTTPHeaderField: "SessionInfo")
request.setValue("67a2a6fb1d13450a", forHTTPHeaderField: "Flowid")
request.setValue("d29566ac42de4e99", forHTTPHeaderField: "Fileid")
request.setValue("LMS_LEAVEREQUEST", forHTTPHeaderField: "Form")
request.httpMethod = "GET"
let session = URLSession.shared
let mData = session.dataTask(with: request as URLRequest) { (data, response, error) -> Void in
if let res = response as? HTTPURLResponse {
DispatchQueue.main.async {
let img = UIImage(data: data!)
self.attachmentImgVw.image = img
}
}else{
print("\n\nError: \(String(describing: error))")
}
}
mData.resume()
}
Output
The data couldn’t be read because it isn’t in the correct format.
Error ScreenShot 1:
Postman Screenshot
In postman, I am giving SessionInfo value as in Dictionary format. Working fine.
How to solve this issue?

How to convert this to a POST call with a JSON serialized Object

I have tried Alamofire, I have tried it with all my heart. It just does not work for me. I finally got http GET working, but I need to get http POST working. Our POST API's take a Request object that has all the necessary data in it. I have requested the backend developers to provide me with a KEY-VALUE pair JSON (no embedded objects/arrays) so that I can use a Dictionary in my swift code convert that to json and send the request. All I need is now to convert the below code to POST.
My earlier questions that did not help much.
NSInvalidArgumentException Invalid type in JSON write DemographicsPojo
Swift 3.0, Alamofire 4.0 Extra argument 'method' in call
I have given up on Alamofire. I want to use Foundation classes. Simple basic and fundamental way of life :).
func callWebService(url : String) {
// Show MBProgressHUD Here
var config :URLSessionConfiguration!
var urlSession :URLSession!
config = URLSessionConfiguration.default
urlSession = URLSession(configuration: config)
// MARK:- HeaderField
let HTTPHeaderField_ContentType = "Content-Type"
// MARK:- ContentType
let ContentType_ApplicationJson = "application/json"
//MARK: HTTPMethod
let HTTPMethod_Get = "GET"
let callURL = URL.init(string: url)
var request = URLRequest.init(url: callURL!)
request.timeoutInterval = 60.0 // TimeoutInterval in Second
request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalCacheData
request.addValue(ContentType_ApplicationJson, forHTTPHeaderField: HTTPHeaderField_ContentType)
request.httpMethod = HTTPMethod_Get
let dataTask = urlSession.dataTask(with: request) { (data,response,error) in
if error != nil{
print("Error **")
return
}
do {
let resultJson = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:AnyObject]
print("Result",resultJson!)
} catch {
print("Error -> \(error)")
}
}
dataTask.resume()
print("..In Background..")
}
Just pass JSON string and the API URL to this function. Complete code for POST.
func POST(api:String,jsonString:String,completionHandler:#escaping (_ success:Bool,_ response:String?,_ httpResponseStatusCode:Int?) -> Void) {
let url = URL(string: api)
var request: URLRequest = URLRequest(url: url!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField:"Content-Type")
request.timeoutInterval = 60.0
//additional headers
if let token = Helper.readAccessToken() {
request.setValue("\(token)", forHTTPHeaderField: "Authorization")
}
let jsonData = jsonString.data(using: String.Encoding.utf8, allowLossyConversion: true)
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) {
(data: Data?, response: URLResponse?, error: Error?) -> Void in
var responseCode = 0
if let httpResponse = response as? HTTPURLResponse {
responseCode = httpResponse.statusCode
print("responseCode \(httpResponse.statusCode)")
}
if error != nil {
completionHandler(false, error?.localizedDescription,nil)
} else {
let responseString = String(data: data!, encoding: .utf8)
completionHandler(true, responseString, responseCode)
}
}
task.resume()
}

How can i convert String to Dictionary to access nested array and dictionary, i want to access stateId and stateName to add in to my table

i
func callAddWithPOST(Name mname:String, PhoneNo mphone:String, Email memail:String, Comment mcomments:String){
let login = ["countryId":"1"]
print("Your Result is : = \(login)")
let url = NSURL(string: "http://photokeeper.mgtcloud.co.uk/commonwebservice.asmx/getStateList")!
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: url)
do {
let auth = try NSJSONSerialization.dataWithJSONObject(login, options: .PrettyPrinted)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
request.HTTPBody = auth
let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
let result = self.convertStringToDictionary(responseString!)
let keys = Array(result!.values)
print(keys[0])
print("Done.")
})
task.resume()
} catch {
print("Error")
}
}
output
{"result":[{"stateId":3871,"stateName":"Aberdeenshire"},{"stateId":3872,"stateName":"Anglesey/Sir Fon"},{"stateId":3873,"stateName":"Angus"},{"stateId":3874,"stateName":"Antrim"},{"stateId":3875,"stateName":"Argyll And Bute"},{"stateId":3876,"stateName":"Armagh"},{"stateId":3877,"stateName":"Ayrshire"},{"stateId":3878,"stateName":"Bedfordshire"},{"stateId":3879,"stateName":"Berkshire"},{"stateId":3880,"stateName":"Blaenau Gwent/Blaenau Gwent"},{"stateId":3881,"stateName":"Bristol"},{"stateId":3882,"stateName":"Buckinghamshire"},{"stateId":3883,"stateName":"Caerphilly/Caerffili"},{"stateId":3884,"stateName":"Cambridgeshire"},{"stateId":3885,"stateName":"Cardiff/Caerdydd"},{"stateId":3886,"stateName":"Cardiganshire/Ceredigion"},{"stateId":3888,"stateName":"Carmarthenshire/Sir Gaerfyrddin"},{"stateId":3890,"stateName":"Cheshire"},{"stateId":3891,"stateName":"Clackmannanshire"},{"stateId":3893,"stateName":"Conwy/Conwy"},{"stateId":3895,"stateName":"County Durham"},{"stateId":3896,"stateName":"Cumbria"},{"stateId":3897,"stateName":"Denbighshire/Sir Ddinbych"},{"stateId":3898,"stateName":"Derbyshire"},{"stateId":3899,"stateName":"Devon"},{"stateId":3901,"stateName":"Dorset"},{"stateId":3902,"stateName":"Down"},{"stateId":3904,"stateName":"Dumfries And Galloway"},{"stateId":3905,"stateName":"Dunbartonshire"},{"stateId":3906,"stateName":"Dundee"},{"stateId":3907,"stateName":"Durham/North Yorkshire"},{"stateId":3908,"stateName":"East Lothian"},{"stateId":3909,"stateName":"East Sussex"},{"stateId":3910,"stateName":"East Yorkshire"},{"stateId":3911,"stateName":"Edinburgh"},{"stateId":3912,"stateName":"Essex"},{"stateId":3913,"stateName":"Fermanagh"},{"stateId":3914,"stateName":"Fife"},{"stateId":3915,"stateName":"Flintshire/Sir Fflint"},{"stateId":3917,"stateName":"Glamorgan/Morgannwg"},{"stateId":3918,"stateName":"Glasgow"},{"stateId":3919,"stateName":"Gloucestershire"},{"stateId":3920,"stateName":"Gwynedd/Gwynedd"},{"stateId":3921,"stateName":"Hampshire"},{"stateId":3922,"stateName":"Herefordshire"},{"stateId":3923,"stateName":"Hertfordshire"},{"stateId":3924,"stateName":"Highland"},{"stateId":3925,"stateName":"Kent"},{"stateId":3929,"stateName":"Lanarkshire"},{"stateId":3930,"stateName":"Lancashire"},{"stateId":3932,"stateName":"Leicestershire"},{"stateId":3935,"stateName":"Lincolnshire"},{"stateId":3936,"stateName":"London"},{"stateId":3937,"stateName":"Londonderry"},{"stateId":3940,"stateName":"Manchester"},{"stateId":3943,"stateName":"Merthyr Tydfil/Merthyr Tydfil"},{"stateId":3944,"stateName":"Midlothian"},{"stateId":3946,"stateName":"Monmouthshire/Sir Fynwy"},{"stateId":3947,"stateName":"Moray"},{"stateId":3948,"stateName":"Neath Port Talbot"},{"stateId":3949,"stateName":"Newport"},{"stateId":3950,"stateName":"Norfolk"},{"stateId":3951,"stateName":"Northamptonshire"},{"stateId":3952,"stateName":"Northumberland"},{"stateId":3953,"stateName":"Nottinghamshire"},{"stateId":3955,"stateName":"Orkney"},{"stateId":3956,"stateName":"Oxfordshire"},{"stateId":3957,"stateName":"Pembrokeshire/Sir Benfro"},{"stateId":3958,"stateName":"Perth And Kinross"},{"stateId":3959,"stateName":"Powys/Powys"},{"stateId":3960,"stateName":"Renfrewshire"},{"stateId":3962,"stateName":"Rutland"},{"stateId":3963,"stateName":"Scottish Borders"},{"stateId":3964,"stateName":"Shetland Isles"},{"stateId":3965,"stateName":"Shropshire"},{"stateId":3967,"stateName":"Somerset"},{"stateId":3968,"stateName":"South Yorkshire"},{"stateId":3969,"stateName":"Staffordshire"},{"stateId":3970,"stateName":"Stirling"},{"stateId":3971,"stateName":"Suffolk"},{"stateId":3972,"stateName":"Surrey"},{"stateId":3973,"stateName":"Swansea"},{"stateId":3975,"stateName":"Torfaen"},{"stateId":3976,"stateName":"Tyrone"},{"stateId":3977,"stateName":"Warwickshire"},{"stateId":3979,"stateName":"West Lothian"},{"stateId":3980,"stateName":"West Midlands"},{"stateId":3981,"stateName":"West Sussex"},{"stateId":3982,"stateName":"West Yorkshire"},{"stateId":3983,"stateName":"Western Isles"},{"stateId":3987,"stateName":"Wiltshire"},{"stateId":3988,"stateName":"Worcestershire"},{"stateId":3989,"stateName":"Wrexham"}],"status":"success"}
Done.
Instead of converting data to String try to convert it Dictionary direct
let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
let response = try NSJSONSerialization.JSONObjectWithData(data!, options:.MutableContainers) as! [String: AnyObject]
let status = response["status"] as! String
if status == "success" {
let array = response["result"] as! [[String: AnyObject]]
print(array)
}
})
Note: You have already written your code inside do block thats why i have not declare that block for try, you just need to replace your task block with my one.
Edit:
func callAddWithPOST(Name mname:String, PhoneNo mphone:String, Email memail:String, Comment mcomments:String){
let login = ["countryId":"1"]
print("Your Result is : = \(login)")
let url = NSURL(string: "http://photokeeper.mgtcloud.co.uk/commonwebservice.asmx/getStateList")!
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: url)
do {
let auth = try NSJSONSerialization.dataWithJSONObject(login, options: .PrettyPrinted)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
request.HTTPBody = auth
let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
let response = try NSJSONSerialization.JSONObjectWithData(data!, options:.MutableContainers) as! [String: AnyObject]
let status = response["status"] as! String
if status == "success" {
let array = response["result"] as! [[String: AnyObject]]
print(array)
}
})
task.resume()
} catch let error as NSError {
print(error.localizedDescription)
}
}