Make contact form for iOS app with Swift and PHP - php

I want to create a contact form where the user can leave me a message (and name and phone number…) and send it to me.
But I don't know how to do this because I never dealt with thinks like this before.
My own suggestion is to $_POST the content from TextField and TextView to a PHP script on my server. This will handle the content. (Either send an email to me with mail() or store it in a file on the server. The PHP script is no problem for me.)
Is that way reasonable? What is the common way to do that, to leave a feedback or something like this to the developer?
P.S. I know there's a way that the user sends me an email from inside the app. But I don't like this way.

That seems reasonable to me. You could just write a function in swift to send to send get or post parameters like so:
func postParamRequest(resourceURL: String, postData: String, completionHandler: ((NSURLResponse?, NSData?, NSError?) -> Void)) {
let request : NSMutableURLRequest = NSMutableURLRequest()
request.URL = NSURL(string: resourceURL)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPBody = postData.dataUsingEncoding(NSUTF8StringEncoding)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse?, data: NSData?, error: NSError?) in
completionHandler(response, data, error)
})
}
You can then just call that function and get the callback of the response, data, and any errors too (the postData should be [key: value]) for the POST parameters. Like so:
postParamRequest("theUrlToYourScript", postData: "key1=value&key2=value&key3=value") { (response, data, error) in
print(data)
}
In your PHP script you could then retrieve the data with something like this: $_POST["paramName"].

Related

Swift HTTP Request Issue (Not sending HOST Header)

I have a simple rest endpoint built on PHP that works on postman and browsers.
https://someserver.com/api/endpoint.php?name=hello
But the code fails to execute when invoked from Swift.
Upon Investigation, I found out that Postman and Browser sends the Host Header whereas the Swift URLRequest doesn't. When you don't send the HOST Header, the php server refuses to accept the incoming request and I believe the request is rejected at the web server level. I tried using the
request.addValue("127.0.0.1", "Host")
but it still didn't work. Any help is appreciated.
Full Code (Swift 4)
let url = urlInput.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
print("URL is: " + url)
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "GET"
request.addValue(<#T##value: String##String#>, forHTTPHeaderField: <#T##String#>)
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
if let httpResponse = response as? HTTPURLResponse {
let respStr = String(data: data!, encoding: String.Encoding.utf8) as String?
print ("Response is \(respStr ?? "")")
print("statusCode: \(httpResponse.statusCode)")
let data: Data? = respStr?.data(using: .utf8)
}
})
Swift is ignoring the fact that you set the header, as it typically should. See the docs about Swift headers and why it's ignoring your Host header.
The URL Loading System handles various aspects of the HTTP protocol
for you (HTTP 1.1 persistent connections, proxies, authentication,
and so on). As part of this support, the URL Loading System takes
responsibility for certain HTTP headers:
Content-Length
Authorization
Connection
Host
Proxy-Authenticate
Proxy-Authorization
WWW-Authenticate
If you set a value for one of these reserved headers, the system may
ignore the value you set, or overwrite it with its own value, or
simply not send it. Moreover, the exact behavior may change over
time. To avoid confusing problems like this, do not set these headers
directly.
The documentation is here:
https://developer.apple.com/documentation/foundation/nsurlrequest#1776617
I have seen this before with Java - there is a workaround in Java depending on the library you are using, but I don't know about Swift.
I figured out that the issue happens only when you hit a php server. The php web server looks for some header and cant find it when the call is made from Swift. I even copied the working code from Postman and results were the same.
The solution I went with was to create a proxy server using firebase cloud function. Swift code would hit a firebase cloud function which talks to php and sends the response to swift.

How to establish a connection to a web server with NSURL in which variables can be passed securely via URL to PHP script

I am using Swift's NSURL function to connect to a PHP script that I can use to interact with a MySQL database. Everything is running smoothly except for the insecurity of the variables passed in the URL via POST. If someone were to intercept these variables it would pose an enormous security risk to my application. I have researched the subject extensively however I have hit a wall. Is an SSL certificate enough to secure the URL? I am not passing the variables through the literal URL but a POST method. As far as I know, the SSL certificate provides security for the data passed AFTER the initial connection (meaning that the data originally passed via POST and the URL are not secure). So essentially, how do I go about passing variables to a web server securely?Here is the code I am using to establish the connection:
let myUrl = NSURL(string: "http://testsite.com/login.php”)
let request = NSMutableURLRequest(URL: myUrl!)
request.HTTPMethod = "POST"
let postString = “username=bob&password=123"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
if let responseData = data {
let responseString = NSString(data: responseData, encoding: NSUTF8StringEncoding)
if error != nil {
print("Error: \(error)")
}
dispatch_async(dispatch_get_main_queue()) {
}
}
} else {
self.sendAlert("Error", message: "Unable to establish connection")
}
}
You can refer to raywenderlich tutorials for setting up the iOS part of it. This tutorial is for connection between ruby rails and swift. It has sign in, sign up and token system, it also includes encryption.
The tutorial uses httpBody to pass the information, you can stick with that or modify to header instead to personalise your codes as required.
request.addValue("bob", forHTTPHeaderField: "username")
request.addValue("123", forHTTPHeaderField: "password") // add AES Encryption.
Also, you can implement a token system instead of passing your username and password. You would however have to pass it initially to get the token.

Start PHP with Swift

I wanted to send an email via a websever and php. Therefore I created a connection to my webserver (000webhoster).
Nearly everything works fine.
My main problem is, that I don't receive anything. I am not even sure, if the PHP code is even executed.
This is my current swift code:
func postToServer (){
print("button pressed")
var url: NSURL = NSURL(string: "http://www.bl1nd3d.herobo.com/email.php")!
var request: NSMutableURLRequest = NSMutableURLRequest(URL:url)
var bodyData = "data=something"
request.HTTPMethod = "POST"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler:{ response, data, error in
if let HTTPResponse = response as? NSHTTPURLResponse {
let statusCode = HTTPResponse.statusCode
if statusCode == 200 {
print("nice")
// TODO : Sent successfully popup
}
else {
print(statusCode)
}
}
})
}
This works fine ^^ .. I always receive the statuscode of 200. (If you wanted to try this you need to enable the insecure AppTransport)
And this is my PHP code.. I believe this doesn't work that properly..
<?php
$postVar = $_POST['data'];
if (!empty($postVar)) {
echo $postVar;
// email , subject, message
mail("myMail#mail.com","Agent was booked","The POST was set and button was pressed" . $postVar);
}
echo "doesn't work that good " . $postVar;
?>
I checked, it should be possible with my webhoster, to send emails..
But it doesn't work.. Did I forget something?
Well something must have gone really bad wrong... My whole dir was deleted while trying this.. :O
The directory /public_html does not exist or could not be selected, so
the directory / is shown instead.
well it probably didn't work that well.. My account was blocked...
Did you check the spam folder? Standard mail() function is not a great solution to send emails. Your mail provider can block email's sent from mail() or it just couldn't work at all. You need to send mail using smtp. Here's the example

Swift: How to use NSURLSession to query external database?

I am writing this question because I am in a big difficulty in understanding how to implement a simple basic authentication login with Swift.
The first screen of my app is a simple form with text fields (username and password) and a Sign In button. In my LoginViewController.swift file I linked the button to this:
#IBAction func doLogin(sender : AnyObject) {
}
The probem now is that I don't know how to go on. I have a local server in MAMP where there is this file.php querying a database and which works perfectly:
<?php
$deep="";
require_once($deep."class/config.php");
$sistema = new config($deep);
if( isset($_GET["username"]) && isset($_GET["password"]) ) {
$username=mysqli_real_escape_string($sistema->dbConn,$_GET["username"]);
$password=mysqli_real_escape_string($sistema->dbConn,$_GET["password"]);
$userL=$sistema->user->allAdmin("WHERE username='".$username."' AND password='".$password."' ");
echo json_encode($userL);
}
?>
So how can I perform a GET request to this file? I suppose I need to create a URL with user data like this form:
http://localhost:8888/excogitoweb/loginM.php?username=lorenzo&password=lorenzo
but then I don't know how to go on. How can I perform this request to retrieve that JSON content? And how can I check that JSON content in order to understand if the sign in procedure has succeeded or has not?
I have watched many tutorials in youtube, overall this but even if I copy the code they show I always get compilation errors...
for a "normal" GET request you need a NSURLRequest with your url... Its just like this:
if let requestURL: NSURL = NSURL(string: "http://localhost:8888/excogitoweb/loginM.php?username=lorenzo&password=lorenzo") as NSURL? {
let urlRequest: NSURLRequest = NSURLRequest(URL: requestURL)
let urlSession = NSURLSession.sharedSession().dataTaskWithRequest(urlRequest, completionHandler: { (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
if let responseJSON: [String: String] = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: nil) as? [String: String] {
///Here you can handle the responded JSON
}
})
urlSession.resume()
}
Don't forget, you are on a background Task when you handle the responded JSON... If you want to do some UI Stuff there you will need to dispatch it to the mein queue
Also a would recommend you doing HTTP POST instead of HTTP GET for such things
UPDATE
if let responseJSON: [[String: String]] = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: nil) as? [[String: String]] {
///Here you can handle the responded JSON
}

How can I send and receive an image in a php POST request to a mySQL database in ios Swift

I'm creating a an app where the user can upload a profile picture.
I need to be able to receive the image from the user, and also send it back to the user were necessary. I need to send that image from the ios device to the server and also receive it.
I've given an example of what my request would look like here :
var url: NSURL = NSURL(string: rootAddress + "uploadImage.php")!
var request:NSMutableURLRequest = NSMutableURLRequest(URL:url)
let bodyData : String = "userID=" + userData.userID + "&sessionID=" + userData.sessionID + "&platform=i&imageData=" + imageData//String in question
request.HTTPMethod = "POST"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
var status = "error"
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue())
{
...
}
the request works and everything but I don't know how to convert the said image to blob, or whatever format I need to be able to send it as a parameter.
Should the image be converted to NSData or some other form that I'm not aware of, and if so how do I send it as a POST parameter?
If I where to request the image back from the server, can it be easily converted and sent back to the device as a json object?
Is sending it like that safe for parsing by other platforms too (android, or webapp)?
Sorry if this seems like a broad subject.
Simply put if tldr : how can I convert an image to blob and send it by a POST php request?
You should always encode binary data (images, etc) to Base64 as a general rule, when POSTing data:
Convert between UIImage and Base64 string

Categories