Sending Http Post request returns 500 status code in IoS - ios

I am trying to send Receipt data of NSData type(converted to string) and several other parameters of type as String in Http Post request.
func receiptValidation(productId:String)
{
let SUBSCRIPTION_SECRET = My_SecretKey
let defaults = UserDefaults.standard
let receiptPath = Bundle.main.appStoreReceiptURL?.path
if FileManager.default.fileExists(atPath: receiptPath!){
var receiptData:NSData?
do{
receiptData = try NSData(contentsOf: Bundle.main.appStoreReceiptURL!, options: NSData.ReadingOptions.alwaysMapped)
}
catch{
print("ERROR: " + error.localizedDescription)
}
let receiptString = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
// let base64encodedReceipt = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions.endLineWithCarriageReturn)
let requestDictionary = ["receipt-data":receiptString!,"password":SUBSCRIPTION_SECRET]
guard JSONSerialization.isValidJSONObject(requestDictionary) else { print("requestDictionary is not valid JSON"); return }
do {
let requestData = try JSONSerialization.data(withJSONObject: requestDictionary)
let requestDataString = NSString(data: requestData, encoding: String.Encoding.utf8.rawValue)
//https://<apiProxyServer>:<apiProxyServerPort>/api/validate-receipt-data
let URLForApplication:String = String(format:"%#/api/validate-receipt-data",opcodeDetails["apiProxyBaseUrl"]!) // this works but as noted above it's best to use your own trusted server
let url:URL! = URL.init(string: URLForApplication)
var request = URLRequest.init(url: url)
request.httpMethod = "POST"
let configure = URLSessionConfiguration.background(withIdentifier: Bundle.main.bundleIdentifier!)
var postString:[String:Any]=[
"receiptData": requestDataString
"deviceType":"IOS",
"subscriberId":encodeString(normalString: defaults.array(forKey: "userDetails")?.first as! String),
"password":encodeString(normalString: defaults.array(forKey: "userDetails")?.last as! String),
"productId":encodeString(normalString: productId),
"code":opcodeDetails["opCode"]!
]
do {
let receiptData = try JSONSerialization.data(withJSONObject: postString)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpBody = receiptData
} catch let error {
print(error.localizedDescription)
}
let session = URLSession(configuration:configure,
delegate:applicationDelegate.application,
delegateQueue:OperationQueue.main)
session1 = session
let connection = session1?.dataTask(with: request)
connection?.resume()
} catch let error as NSError {
print("json serialization failed with error: \(error)")
}
}
}
Where encodeString() is a defined method
func encodeString(normalString:String) -> String {
let allowedCharacters = CharacterSet.letters
let encodedString:String!=normalString.addingPercentEncoding(withAllowedCharacters: allowedCharacters)
return encodedString
}
There were no problem on server side.But I could not get success response instead What I am getting is {"status":"failure","statusCode":500,"message":"Resource url not found!"}.What mistake am i doing with this code?.Anyone please help me.Thanks in advance.

Try appending '/' at the end of URL.
Eg:
google.com/api/post and google.com/api/post/ are different and trailing slash sometimes gives 500 error, in case of Django-Backend it does.

Related

Https Post Request Response

private func makeLoginRestCall(email:String, password:String){
guard let url = URL(string: "http://-----------/PassengerLogin.php") else {
return
}
var request = URLRequest(url:url)
request.httpMethod = "POST"
let emailString : String = "email="
let parameters = emailString + email+",password=" + password
request.httpBody = parameters.data(using: .utf8)
let session = URLSession.shared
session.dataTask(with:request) {
(data,response,error) in
if let response = response {
print(response)
}else{
print("No response")
}
if let data = data {
do{
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSDictionary
print(json ?? "No data found")
}catch{
print(error)
}
}else {
print("No data found")
}
}.resume()}
When I send this request from simulator I always get invalid email response.
But When I send this request from postman I get all user details .
Please help new here
Thank you in advance.

How to send array by POST method to server?

I am trying to send array as parameter to server but server is not receiving. Server have to receive two arrays that I am sending. But in server they are not appear ?? I dont know is it my mistake or mistake in the server ??
My array name is testAns and testQuest and I have to send it to parameters: answer and quest.
my Code:
let userID = UserDefaults.standard.string(forKey: "userID")
let artID = UserDefaults.standard.string(forKey: "index")
let myUrl = URL(string: "http://www.someurls.kz/modules/CheckTestF.php");
var request = URLRequest(url:myUrl!)
request.httpMethod = "POST"
var testAns = [Int]()
var testQuest = [Int]()
testAns = [131,123,23]
testQuest = [123,233,232]
let postString = "uID=97B436E41&idUser=\(userID!)&art_id=\(artID!)&answer=\(testAns)&quest=\(testQuest)"
print(postString)
print(testAns,testQuest)
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
}
do {
_ = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
}
catch {
print(error)
}
}
task.resume()
}
i don't know how to encode that array on your server side.
but temporary you can try this way and check your database.
let postString = "uID=97B436E41&idUser=\(userID!)&art_id=\(artID!)&answer[0]=131&answer[1]=123&quest[0]=123&quest[1]=233"
You can use the Alamofire that is very popular at this time that is advanced version of AFNetworking
Also, I am sharing the method that will help you to hit API, You have to pass only the dictionary object in this method and this will give you the response in two blocks and you can use them as per requirements.
1: unReachable()
2: handler(responseDict)
//MARK: *********** HIT POST SERVICE IN JSON FORM***********
func hitPostServiceJsonForm(_ params:Dictionary<String,Any>,unReachable:(() -> Void),handler:#escaping ((Dictionary<String,Any>?) -> Void)) {
if networkReachable() == false {
unReachable()
}
let BASE_URL = "http://mydoamain"
var request = URLRequest(url: URL(string: BASE_URL)!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try! JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
print(BASE_URL)
Alamofire.request(request).responseJSON { response in
//print("Request: \(String(describing: response.request))") // original url request
//print("Response: \(String(describing: response.response))") // http url response
print("Result: \(response.result)") // response serialization result
switch response.result {
case .success:
if let jsonDict = response.result.value as? Dictionary<String,Any> {
print("Json Response: \(jsonDict)") // serialized json response
handler(jsonDict)
}
else{
handler(nil)
}
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
print("Server Response: \(utf8Text)") // original server data as UTF8 string
}
break
case .failure(let error):
handler(nil)
print(error)
break
}
}
}
func networkReachable() -> Bool {
return (NetworkReachabilityManager()?.isReachable)!
}
convert the your array to json string then try to send it to server
func post_array(){
let userID = UserDefaults.standard.string(forKey: "userID")
let artID = UserDefaults.standard.string(forKey: "index")
let myUrl = URL(string: "http://www.someurls.kz/modules/CheckTestF.php");
var request = URLRequest(url:myUrl!)
request.httpMethod = "POST"
var testAns = [Int]()
var testQuest = [Int]()
testAns = [131,123,23]
testQuest = [123,233,232]
var tempAns : NSString = ""
do {
let arrJson = try JSONSerialization.data(withJSONObject: testAns, options: .prettyPrinted)
let string = NSString(data: arrJson, encoding: String.Encoding.utf8.rawValue)
tempAns = string! as NSString
}catch let error as NSError{
print(error)
}
var tempQuest : NSString = ""
do {
let arrJson = try JSONSerialization.data(withJSONObject: testQuest, options: .prettyPrinted)
let string = NSString(data: arrJson, encoding: String.Encoding.utf8.rawValue)
tempQuest = string! as NSString
}catch let error as NSError{
print(error)
}
let postString = "uID=97B436E41&idUser=\(userID!)&art_id=\(artID!)&answer=\(tempAns)&quest=\(tempQuest)"
print(postString)
print(testAns,testQuest)
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
}
do {
_ = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
}
catch {
print(error)
}
}
task.resume()
}

Implementing Receipt Validation in Swift 3

I am developing an iOS app in Swift 3 and trying to implement receipt validation following this tutorial: http://savvyapps.com/blog/how-setup-test-auto-renewable-subscription-ios-app. However, the tutorial seems to have been written using an earlier version of Swift, so I had to make several changes. Here is my receiptValidation() function:
func receiptValidation() {
let receiptPath = Bundle.main.appStoreReceiptURL?.path
if FileManager.default.fileExists(atPath: receiptPath!){
var receiptData:NSData?
do{
receiptData = try NSData(contentsOf: Bundle.main.appStoreReceiptURL!, options: NSData.ReadingOptions.alwaysMapped)
}
catch{
print("ERROR: " + error.localizedDescription)
}
let receiptString = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
let postString = "receipt-data=" + receiptString! + "&password=" + SUBSCRIPTION_SECRET
let storeURL = NSURL(string:"https://sandbox.itunes.apple.com/verifyReceipt")!
let storeRequest = NSMutableURLRequest(url: storeURL as URL)
storeRequest.httpMethod = "POST"
storeRequest.httpBody = postString.data(using: .utf8)
let session = URLSession(configuration:URLSessionConfiguration.default)
let task = session.dataTask(with: storeRequest as URLRequest) { data, response, error in
do{
let jsonResponse:NSDictionary = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
let expirationDate:NSDate = self.expirationDateFromResponse(jsonResponse: jsonResponse)!
self.updateIAPExpirationDate(date: expirationDate)
}
catch{
print("ERROR: " + error.localizedDescription)
}
}
task.resume()
}
}
The problem shows up when I try to call the expirationDateFromResponse() method. It turns out that the jsonResponse that gets passed to this method only contains: status = 21002;. I looked this up and it means "The data in the receipt-data property was malformed or missing." However, the device I'm testing on has an active sandbox subscription for the product, and the subscription seems to work correctly aside from this issue. Is there something else I still need to do to make sure the receiptData value will be read and encoded correctly, or some other issue that might be causing this problem?
EDIT:
I tried an alternate way of setting storeRequest.httpBody:
func receiptValidation() {
let receiptPath = Bundle.main.appStoreReceiptURL?.path
if FileManager.default.fileExists(atPath: receiptPath!){
var receiptData:NSData?
do{
receiptData = try NSData(contentsOf: Bundle.main.appStoreReceiptURL!, options: NSData.ReadingOptions.alwaysMapped)
}
catch{
print("ERROR: " + error.localizedDescription)
}
let receiptString = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0)) //.URLEncoded
let dict = ["receipt-data":receiptString, "password":SUBSCRIPTION_SECRET] as [String : Any]
var jsonData:Data?
do{
jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
}
catch{
print("ERROR: " + error.localizedDescription)
}
let storeURL = NSURL(string:"https://sandbox.itunes.apple.com/verifyReceipt")!
let storeRequest = NSMutableURLRequest(url: storeURL as URL)
storeRequest.httpMethod = "POST"
storeRequest.httpBody = jsonData!
let session = URLSession(configuration:URLSessionConfiguration.default)
let task = session.dataTask(with: storeRequest as URLRequest) { data, response, error in
do{
let jsonResponse:NSDictionary = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
let expirationDate:NSDate = self.expirationDateFromResponse(jsonResponse: jsonResponse)!
self.updateIAPExpirationDate(date: expirationDate)
}
catch{
print("ERROR: " + error.localizedDescription)
}
}
task.resume()
}
}
However, when I run the app with this code, it hangs upon reaching the line jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted). It doesn't even make it to the catch block, it just stops doing anything. From what I've seen online, other people seem to have trouble using JSONSerialization.data to set the request httpBody in Swift 3.
Its working correctly with Swift 4
func receiptValidation() {
let SUBSCRIPTION_SECRET = "yourpasswordift"
let receiptPath = Bundle.main.appStoreReceiptURL?.path
if FileManager.default.fileExists(atPath: receiptPath!){
var receiptData:NSData?
do{
receiptData = try NSData(contentsOf: Bundle.main.appStoreReceiptURL!, options: NSData.ReadingOptions.alwaysMapped)
}
catch{
print("ERROR: " + error.localizedDescription)
}
//let receiptString = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
let base64encodedReceipt = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions.endLineWithCarriageReturn)
print(base64encodedReceipt!)
let requestDictionary = ["receipt-data":base64encodedReceipt!,"password":SUBSCRIPTION_SECRET]
guard JSONSerialization.isValidJSONObject(requestDictionary) else { print("requestDictionary is not valid JSON"); return }
do {
let requestData = try JSONSerialization.data(withJSONObject: requestDictionary)
let validationURLString = "https://sandbox.itunes.apple.com/verifyReceipt" // this works but as noted above it's best to use your own trusted server
guard let validationURL = URL(string: validationURLString) else { print("the validation url could not be created, unlikely error"); return }
let session = URLSession(configuration: URLSessionConfiguration.default)
var request = URLRequest(url: validationURL)
request.httpMethod = "POST"
request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringCacheData
let task = session.uploadTask(with: request, from: requestData) { (data, response, error) in
if let data = data , error == nil {
do {
let appReceiptJSON = try JSONSerialization.jsonObject(with: data)
print("success. here is the json representation of the app receipt: \(appReceiptJSON)")
// if you are using your server this will be a json representation of whatever your server provided
} catch let error as NSError {
print("json serialization failed with error: \(error)")
}
} else {
print("the upload task returned an error: \(error)")
}
}
task.resume()
} catch let error as NSError {
print("json serialization failed with error: \(error)")
}
}
}
I have updated the #user3726962's code, removing unnecessary NS'es and "crash operators". It should look more like Swift 3 now.
Before using this code be warned that Apple doesn't recommend doing direct [device] <-> [Apple server] validation and asks to do it [device] <-> [your server] <-> [Apple server]. Use only if you are not afraid to have your In-App Purchases hacked.
UPDATE: Made the function universal: it will attempt to validate receipt with Production first, if fails - it will repeat with Sandbox. It's a bit bulky, but should be quite self-contained and independent from 3rd-parties.
func tryCheckValidateReceiptAndUpdateExpirationDate() {
if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
NSLog("^A receipt found. Validating it...")
GlobalVariables.isPremiumInAmbiquousState = true // We will allow user to use all premium features until receipt is validated
// If we have problems validating the purchase - this is not user's fault
do {
let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
let receiptString = receiptData.base64EncodedString(options: [])
let dict = ["receipt-data" : receiptString, "password" : "your_shared_secret"] as [String : Any]
do {
let jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
if let storeURL = Foundation.URL(string:"https://buy.itunes.apple.com/verifyReceipt"),
let sandboxURL = Foundation.URL(string: "https://sandbox.itunes.apple.com/verifyReceipt") {
var request = URLRequest(url: storeURL)
request.httpMethod = "POST"
request.httpBody = jsonData
let session = URLSession(configuration: URLSessionConfiguration.default)
NSLog("^Connecting to production...")
let task = session.dataTask(with: request) { data, response, error in
// BEGIN of closure #1 - verification with Production
if let receivedData = data, let httpResponse = response as? HTTPURLResponse,
error == nil, httpResponse.statusCode == 200 {
NSLog("^Received 200, verifying data...")
do {
if let jsonResponse = try JSONSerialization.jsonObject(with: receivedData, options: JSONSerialization.ReadingOptions.mutableContainers) as? Dictionary<String, AnyObject>,
let status = jsonResponse["status"] as? Int64 {
switch status {
case 0: // receipt verified in Production
NSLog("^Verification with Production succesful, updating expiration date...")
self.updateExpirationDate(jsonResponse: jsonResponse) // Leaves isPremiumInAmbiquousState=true if fails
case 21007: // Means that our receipt is from sandbox environment, need to validate it there instead
NSLog("^need to repeat evrything with Sandbox")
var request = URLRequest(url: sandboxURL)
request.httpMethod = "POST"
request.httpBody = jsonData
let session = URLSession(configuration: URLSessionConfiguration.default)
NSLog("^Connecting to Sandbox...")
let task = session.dataTask(with: request) { data, response, error in
// BEGIN of closure #2 - verification with Sandbox
if let receivedData = data, let httpResponse = response as? HTTPURLResponse,
error == nil, httpResponse.statusCode == 200 {
NSLog("^Received 200, verifying data...")
do {
if let jsonResponse = try JSONSerialization.jsonObject(with: receivedData, options: JSONSerialization.ReadingOptions.mutableContainers) as? Dictionary<String, AnyObject>,
let status = jsonResponse["status"] as? Int64 {
switch status {
case 0: // receipt verified in Sandbox
NSLog("^Verification succesfull, updating expiration date...")
self.updateExpirationDate(jsonResponse: jsonResponse) // Leaves isPremiumInAmbiquousState=true if fails
default: self.showAlertWithErrorCode(errorCode: status)
}
} else { DebugLog("Failed to cast serialized JSON to Dictionary<String, AnyObject>") }
}
catch { DebugLog("Couldn't serialize JSON with error: " + error.localizedDescription) }
} else { self.handleNetworkError(data: data, response: response, error: error) }
}
// END of closure #2 = verification with Sandbox
task.resume()
default: self.showAlertWithErrorCode(errorCode: status)
}
} else { DebugLog("Failed to cast serialized JSON to Dictionary<String, AnyObject>") }
}
catch { DebugLog("Couldn't serialize JSON with error: " + error.localizedDescription) }
} else { self.handleNetworkError(data: data, response: response, error: error) }
}
// END of closure #1 - verification with Production
task.resume()
} else { DebugLog("Couldn't convert string into URL. Check for special characters.") }
}
catch { DebugLog("Couldn't create JSON with error: " + error.localizedDescription) }
}
catch { DebugLog("Couldn't read receipt data with error: " + error.localizedDescription) }
} else {
DebugLog("No receipt found even though there is an indication something has been purchased before")
NSLog("^No receipt found. Need to refresh receipt.")
self.refreshReceipt()
}
}
func refreshReceipt() {
let request = SKReceiptRefreshRequest()
request.delegate = self // to be able to receive the results of this request, check the SKRequestDelegate protocol
request.start()
}
This works for auto-renewable subscriptions. Haven't tested it with other kinds of subscriptions yet. Leave a comment if it works for you with some other subscription type.
//too low rep to comment
Yasin Aktimur, thanks for your answer, it's awesome. However, looking at Apple documentation on this, they say to connect to iTunes on a separate Queue. So it should look like this:
func receiptValidation() {
let SUBSCRIPTION_SECRET = "secret"
let receiptPath = Bundle.main.appStoreReceiptURL?.path
if FileManager.default.fileExists(atPath: receiptPath!){
var receiptData:NSData?
do{
receiptData = try NSData(contentsOf: Bundle.main.appStoreReceiptURL!, options: NSData.ReadingOptions.alwaysMapped)
}
catch{
print("ERROR: " + error.localizedDescription)
}
let base64encodedReceipt = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions.endLineWithCarriageReturn)
let requestDictionary = ["receipt-data":base64encodedReceipt!,"password":SUBSCRIPTION_SECRET]
guard JSONSerialization.isValidJSONObject(requestDictionary) else { print("requestDictionary is not valid JSON"); return }
do {
let requestData = try JSONSerialization.data(withJSONObject: requestDictionary)
let validationURLString = "https://sandbox.itunes.apple.com/verifyReceipt" // this works but as noted above it's best to use your own trusted server
guard let validationURL = URL(string: validationURLString) else { print("the validation url could not be created, unlikely error"); return }
let session = URLSession(configuration: URLSessionConfiguration.default)
var request = URLRequest(url: validationURL)
request.httpMethod = "POST"
request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringCacheData
let queue = DispatchQueue(label: "itunesConnect")
queue.async {
let task = session.uploadTask(with: request, from: requestData) { (data, response, error) in
if let data = data , error == nil {
do {
let appReceiptJSON = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSDictionary
print("success. here is the json representation of the app receipt: \(appReceiptJSON)")
} catch let error as NSError {
print("json serialization failed with error: \(error)")
}
} else {
print("the upload task returned an error: \(error ?? "couldn't upload" as! Error)")
}
}
task.resume()
}
} catch let error as NSError {
print("json serialization failed with error: \(error)")
}
}
}
I struggled my head with the same problem. The issue is that this line:
let receiptString = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
Returns an OPTIONAL and
jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
cannot handle optionals. So to fix it, simply substitute the first line of code with this:
let receiptString:String = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions.lineLength64Characters) as String!
And everything will work like charm!
I liked your answer and I just rewrote it in C# for those who are using it like me as I did not find a good source for the solution.
Thanks Again
For Consumable IAP
void ReceiptValidation()
{
var recPath = NSBundle.MainBundle.AppStoreReceiptUrl.Path;
if (File.Exists(recPath))
{
NSData recData;
NSError error;
recData = NSData.FromUrl(NSBundle.MainBundle.AppStoreReceiptUrl, NSDataReadingOptions.MappedAlways, out error);
var recString = recData.GetBase64EncodedString(NSDataBase64EncodingOptions.None);
var dict = new Dictionary<String,String>();
dict.TryAdd("receipt-data", recString);
var dict1 = NSDictionary.FromObjectsAndKeys(dict.Values.ToArray(), dict.Keys.ToArray());
var storeURL = new NSUrl("https://sandbox.itunes.apple.com/verifyReceipt");
var storeRequest = new NSMutableUrlRequest(storeURL);
storeRequest.HttpMethod = "POST";
var jsonData = NSJsonSerialization.Serialize(dict1, NSJsonWritingOptions.PrettyPrinted, out error);
if (error == null)
{
storeRequest.Body = jsonData;
var session = NSUrlSession.FromConfiguration(NSUrlSessionConfiguration.DefaultSessionConfiguration);
var tsk = session.CreateDataTask(storeRequest, (data, response, err) =>
{
if (err == null)
{
var rstr = NSJsonSerialization.FromObject(data);
}
else
{
// Check Error
}
});
tsk.Resume();
}else
{
// JSON Error Handling
}
}
}
Eventually I was able to solve the problem by having my app call a Lambda function written in Python, as shown in this answer. I'm still not sure what was wrong with my Swift code or how to do this entirely in Swift 3, but the Lambda function got the desired result in any case.

Swift iOS HTTP request post json

I want to make a HTTP request to a server but I have troubles parsing my data to JSON.
This is my code:
let dic = ["interest":["category":"Viajes","value":"Mexico"],"metadata":["version":"0.1","count":1]]
do{
let jsonData = try NSJSONSerialization.dataWithJSONObject(dic, options: NSJSONWritingOptions())
let url:NSURL = NSURL(string: "http://ip/interests")!
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
//let paramString = ""
//request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)
request.HTTPBody = jsonData
let dataString = NSString(data: jsonData, encoding: NSUTF8StringEncoding)
print(dataString)
let task = session.dataTaskWithRequest(request) {
(
let data, let response, let error) in
guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
print(error)
return
}
print(response?.description)
}
task.resume()
}catch let error as NSError {
print(error)
return
}
The server catch :
{ '{"interest":{"category":"Viajes","value":"Mexico"},"metadata":{"count":1,"version":"0.1"}}': '' }
What I want:
{"interest":{"category":"Viajes","value":"Mexico"},"metadata":{"count":1,"version":"0.1"}}
Anybody knows how to fix it?

Make a http request with basic authentication

I want to make an http request with basic auth. I tried to follow this topic : click here. But Xcode tell me
Bad Request after httpResponse
And I don't know why since this morning. Maybe anyone got a idea more interesting than I can find on the web ? :)
Here is my code :
func topRefresh(sender:AnyObject){
var list=Array<Notification>()
//credential
let credentialLogin = NSUserDefaults.standardUserDefaults().objectForKey("login") as! String
let credentialPassword = NSUserDefaults.standardUserDefaults().objectForKey("password") as! String
// set up the base64-encoded credentials
let loginString = NSString(format: "%#:%#", credentialLogin, credentialPassword)
let loginData: NSData = loginString.dataUsingEncoding(NSUTF8StringEncoding)!
let base64LoginString = loginData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength)
// create the request
let url = NSURL(string: jsonLink)!
let request = NSMutableURLRequest(URL: url)
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
request.HTTPMethod="GET"
let paramString="login="+credentialLogin
request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) {
(data, response, error) -> Void in
let httpResponse = response as! NSHTTPURLResponse
if (httpResponse.statusCode == 200) {
do{
if (data != nil){
self.notificationsDisplayed.removeAll()
let jsonDict = try NSJSONSerialization.JSONObjectWithData(data!,options: .AllowFragments)
list=self.parseJson(jsonDict)
if (self.notifications.count==0){
self.notifications=self.copyArray(list)
list.removeAll()
}else{
//compare new data with past data
while(list.count>0){
print(list.count)
let tmp=list.last
for notification in self.notifications {
if(tmp!.id==notification.id){
list.removeLast()
break
}else{
self.notifications.insert(tmp!, atIndex: 0)
list.removeLast()
break
}
}
}
}
self.orderByDate(&self.notifications)
self.notificationsDisplayed=self.copyArray(self.notifications)
self.applyFilter()
print("Data parsed")
}else{
print("Data is empty")
}
}catch {
print("Error with Json: \(error)")
}
}else{
print("HTTP Error")
}
self.refreshControl?.endRefreshing()
print("Finished")
}
task.resume()
}
I use the following in my code to create a default session that include the authentication:
static func defaultURLSession(username : String, password:String) -> NSURLSession {
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let userPasswordString = "\(username):\(password)"
let userPasswordData = userPasswordString.dataUsingEncoding(NSUTF8StringEncoding)
let base64EncodedCredential = userPasswordData!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.EncodingEndLineWithCarriageReturn)
let authString = "Basic \(base64EncodedCredential)"
config.HTTPAdditionalHeaders = ["Authorization" : authString]
return NSURLSession(configuration: config)
}

Resources