I'm relatively new to iOS development. Currently, I'm following the tutorial on making POST request to server in Swift. However, I'm getting error messages that I don't really understand what is wrong with it.
2016-01-08 14:44:48.991 test[24331:4311765] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
error=Optional(Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, NSUnderlyingError=0x7c28c9b0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorCodeKey=-9802, _kCFStreamErrorDomainKey=3, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x7ae43c60>, kCFStreamPropertySSLPeerCertificates=<CFArray 0x7c28aad0 [0x4ef098]>{type = immutable, count = 1, values = (
0 : <cert(0x7c191330) s: localhost i: localhost>
)}}}, _kCFStreamErrorCodeKey=-9802, NSErrorFailingURLStringKey=https://localhost/, NSErrorPeerCertificateChainKey=<CFArray 0x7c28aad0 [0x4ef098]>{type = immutable, count = 1, values = (
0 : <cert(0x7c191330) s: localhost i: localhost>
)}, NSErrorClientCertificateStateKey=0, NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x7ae43c60>, NSErrorFailingURLKey=https://localhost/})
POST request in Swift:
let myUrl = NSURL(string: "https://localhost");
let request = NSMutableURLRequest(URL:myUrl!);
request.HTTPMethod = "POST";
// Compose a query string
let postString = "firstName=James&lastName=Bond";
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil
{
print("error=\(error)")
return
}
// You can print out response object
print("response = \(response)")
// Print out response body
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
//Let’s convert response sent from a server side script to a NSDictionary object:
do {
let myJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
// YOUR CODE HERE
if let parseJSON = myJSON {
// Now we can access value of First Name by its key
let firstNameValue = parseJSON["firstName"] as? String
print("firstNameValue: \(firstNameValue)")
}
} catch {
print(error)
}
}
task.resume()
Code in index.php:
<?php
// Read request parameters
$firstName= $_REQUEST["firstName"];
$lastName = $_REQUEST["lastName"];// Store values in an array
$returnValue = array(“firstName”=>$firstName, “lastName”=>$lastName);
// Send back request in JSON format
echo json_encode($returnValue);
?>
Your localhost is not https, it's http. In iOS 9 you'll have to disable that in your info.plist so it allows you to make requests to non-https targets.
Add this to your info.plist
Related
Hi all I am trying my hands on Swift and I am trying to post users registration data. I know how to do it firebase but my main project is in php mysql so I want to connect it with swift
#IBAction func signUp(_ sender: Any) {
//check textfield data
checkTextFields()
//create user
let url = NSURL(string: "http://localhost:8888/helo/register.php")
let request = NSMutableURLRequest(url: url! as URL)
request.httpMethod = "POST"
//apending body to url
let body = "Fullname=\(name.text!.lowercased())&userName=\(userName.text!.lowercased())&emailAddress=\(emailAddress.text!.lowercased())&password=\(password.text!.lowercased())"
request.httpBody = body.data(using: String.Encoding.utf8)
//lunching
URLSession.shared.dataTaskWithRequest(request as URLRequest, completionHandler: { (data:NSData?, response:URLResponse?, error:NSError?) in
if error == nil{
dispatch_async(dispatch_get_main_queue(),{
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as?
NSDictionary
guard let parseJSON = json else{
print("Error while parsing")
return
}
let id = parseJSON["id"]
if id != nil {
print(parseJSON)
}
}catch{
print("Caugth an error: \(error)")
}
})
}else{
print("error: \(error)")
}
} )
}
I am getting an error on the line where I have commented as as lunching which say
Cannot convert value of type '(NSData?, URLResponse?, NSError?) -> ()' to expected argument type '(Data?, URLResponse?, Error?) -> Void'
I am new to Swift any help is welcome thank you all. I am using Xcode 9
After enough reading, I just realised I was doing a very tedious and using orthodox method when things have improved. I removed the whole code and did everything with Alamofire. Its really easy and straight forward. I will post the code below to help others who encounter similar problems later on.
//Constant that holds the URL for our web servicer
let URL_USER_REGISTER = "http://localhost:8888/members/register.php?"
Alamofire.request(URL_USER_REGISTER, method: .post, parameters: parameters).responseJSON{
response in
//printing response
print(response)
//getting json value from the server
if let result = response.result.value {
//converting it as NSDictionary
let jsonData = result as! NSDictionary
//displaying the message in label
self.lableMessage.text = jsonData.value(forKey: "message") as! String?
}
}
you have to first import Alamofire.
I want to post some data to my php page, I've tested two ways to do so but non of them worked :
let parameters = [
"name": "test",
]
Alamofire.request(URL(string: "http://www.tameshkshop.ir/11.php")!, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: [:]).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
let responseString = String(data: response.data!, encoding: .utf8)
print(responseString)
}
the second way :
var request = URLRequest(url: URL(string: "http://www.tameshkshop.ir/11.php")!)
request.httpMethod = "POST"
let postString = "name=\(FinallFactorViewController.name)"
request.httpBody = postString.data(using: .)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = String(data: data, encoding: .utf8)
let index = responseString?.index((responseString?.startIndex)!, offsetBy: 4)
let done = responseString?.substring(to: index!)
in the php page, I get the posted value and echo them like this :
echo $_POST['name'];
but it I get nothing in return .
what is wrong ? where am I doing is wrong ?
Your POST service is waiting for for httpBody parameters, not JSON. I did check this on postman. Use the following code to make your request:
let parameters = ["name":"Name"]
Alamofire.request(.POST, "http://tameshkshop.ir/11.php", parameters: parameters)
.responseString(completionHandler: { response in
print(response.result.value)
})
The output:
"test : Name |"
EDIT:
You can't make a request using HTTP since iOS 9. Instead use HTTPS or Allow arbitrary loads in your .plist https://stackoverflow.com/a/33712228/5006492 Before going to production disable Allow arbitrary loads, is a security risk use HTTP. Get a SSL certificate for your site.
I am trying to get login/register on my iOS app to work. I am using mySQL and PHP besides Swift 2.0. For some reason when I try to send my HTTP POST to the PHP-scripts I keep geting the error: "The data couldn’t be read because it isn’t in the correct format."
I am using MAMP for the mySQL server.
let request = NSMutableURLRequest(URL: NSURL.fileURLWithPath("/Users/robin/Programming/xcode/Projects/Quix/php_scripts/userRegister.php"))
request.HTTPMethod = "POST"
let postString = "email=\(userEmail)&password=\(userPassword)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
print(postString)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
if (error != nil) {
print("error=\(error)")
}
do {
if let parseJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
let resultValue = parseJSON["status"] as? String
print("result: \(resultValue)")
var isUserRegistered:Bool = false
if (resultValue == "Success") { isUserRegistered = true }
var messageToDisplay:String = parseJSON["message"] as! String!
if (!isUserRegistered) {
messageToDisplay = parseJSON["message"] as! String!
}
dispatch_async(dispatch_get_main_queue(), {
let myAlert = UIAlertController(title: "Alert", message: messageToDisplay, preferredStyle: UIAlertControllerStyle.Alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default) { action in
self.dismissViewControllerAnimated(true, completion: nil)
}
myAlert.addAction(okAction)
self.presentViewController(myAlert, animated: true, completion: nil)
});
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
task.resume()
In my database I have the table 'users' and the parameters id (auto_increment), email and password. I am using port: 3306 for mySQL aswell. The standard IP for MAMP is 127.0.0.1, should I use the IP: 127.0.0.1 or localhost:3306 aswell?
You are using a file URL with a NSURLSession request. You should use a https:// or http:// request. NSURLSession is for making network requests, not local file system requests. So, if you're running this on the iOS simulator, you can use http://localhost/.... But when you run it on an device, you'll have to supply it a host name that will resolve to your machine running MAMP.
By the way, if you use http, you may need to add a NSExceptionDomains entry as outlined in https://stackoverflow.com/a/31254874/1271826.
I'm having trouble parsing a JSON, sent from a PHP script, on IOS using swift. I just started learning IOS development this week and also had never worked with JSON before so any help would be greatly appreciated on parsing this correctly. I'm sending a result from a mysql query as a JSON to the app. Here is my swift code and the error log in which you can see the object received by the http service.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let secondViewController:VC2 = segue.destinationViewController as! VC2
let myUrl = NSURL(string: "myscriptaddress");
let request = NSMutableURLRequest(URL:myUrl!);
request.HTTPMethod = "POST";
let postString = "condition=" + String(currentval);
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
secondViewController.mystring = "getting ready"
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
guard data != nil else {
print("no data found: \(error)")
return
}
do {
if let json = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
print("Success")
} else {
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Error could not parse JSON: \(jsonStr)")
}
} catch let parseError {
print(parseError)
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Error can't parse JSON: '\(jsonStr)'")
}
}
task.resume()
}
And now the error log:
Error could not parse JSON: Optional([{"unidad":"sanfrancisco","capacidad":"15","uso":"5","telefono":"num"},{"unidad":"pediatricouniversitario","capacidad":"15","uso":"5","telefono":"num"},{"unidad":"sanjorge","capacidad":"15","uso":"7","telefono":"num"},{"unidad":"himacaguas","capacidad":"20","uso":"4","telefono":"num"},{"unidad":"himabayamon","capacidad":"20","uso":"8","telefono":"num"},{"unidad":"sanlucas","capacidad":"10","uso":"8","telefono":"num"},{"unidad":"auxiliomutuo","capacidad":"15","uso":"11","telefono":"num"}])
Its failing to unwrap the JSON data as a dictionary type. The JSON string provided is an array of objects.
Try this in your JSONObjectWithData call:
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [[String : AnyObject]]
Hi I am trying to connect my iOS app to my PHP API.
I am sending JSON POST to my PHP API but I am getting an empty array as Output.
My Swift Code
#IBAction func JSONButtonAction(sender: AnyObject) {
var configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
var session = NSURLSession(configuration: configuration)
var usr = "dsdd"
var pwdCode = "dsds"
var image : UIImage = clickedPhotoView.image!
var imageData = UIImagePNGRepresentation(image)
let base64String = imageData.base64EncodedStringWithOptions(.allZeros)
let params:[String: AnyObject] = [
"email" : usr,
"image" : base64String ]
let url = NSURL(string:"http://localhost/app/")
let request = NSMutableURLRequest(URL: url!)
let boundaryConstant = "Boundary-7MA4YWxkTLLu0UIW"; // This should be auto-generated.
request.setValue("application/x-www-form-urlencoded", 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
// println("response = \(response)")
let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
println("\(responseString)")
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()
}
PHP Code
print_r($_POST);
Output is
array(
)
But when I use
$data = json_decode(file_get_contents('php://input'), true);
It works fine
I dont know why $_POST is not working.
If your intent is actually to send a string, then you should change the content-type:
request.setValue("text/plain", forHTTPHeaderField: "Content-Type")
Tested your exact code with this modification on my tests server:
Otherwise, check #kekub's comment.