I am having trouble getting a simple Json object from my php page into my ios app. I am using Swift 3 in xcode 8. I have tried multiple tutorials with no avail. I keep getting the error "Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." I have checked my php page with a Json validator and it seems to be fine. Any help in the right direction will be greatly appreciated. Here is my Json data that is echoed to my php page.
{"SSID":"TESTSSID","PASS":"TESTPASS"}
As you can see, all I am trying to do is be able to get SSID and PASS into a variable in Swift so that I can output the data to the app. Here is what I have so far for the swift code. (sorry if it is terrible, I am a newbie and just hacked it together)
This is in my ViewDidLoad()..
let urlString = "http://192.168.51.1/mytestPHP.php"
let url = URL(string: urlString)
URLSession.shared.dataTask(with:url!) { (data, response, error) in
if error != nil {
print(error)
} else {
do {
let parsedData = try JSONSerialization.jsonObject(with: data!, options: []) as! [String:Any]
let SSID = parsedData["SSID"] as! [String:Any]
print(SSID)
} catch let error as NSError {
print(error)
}
}
}.resume()
In your JSON response both SSID and PASS keys having String as value not Dictionary.
do {
let parsedData = try JSONSerialization.jsonObject(with: data!, options: []) as! [String:Any]
if let ssid = parsedData["SSID"] as? String,
let pass = parsedData["PASS"] as? String {
print(ssid, pass)
}
} catch let error as NSError {
print(error)
}
Note: As error suggesting your response is not valid so try once converting data to string and check what you are getting in response. Add below line before calling JSONSerialization and the response of it here.
print(String(data: data!, encoding: .utf8))
You are basically getting an invalid JSON error, so either your PHP script is not returning the JSON you think it's returning or it's not returning anything at all.
Related
I'm having some trouble with serialization on a JSON response on my iOS app from my server, its a PHP back-end. My app sends a post request with the appropriate parameters, validates them, puts the results in an array, and encodes it in. Now that's not the problem, code works fine. However, its the link between them. Look at the PHP code below.
echo json_encode($array)
Now coming to xcode, I'm using alamofire to send the request as seen in the code below
Alamofire.request(URL_USER_REGISTER, method: .post, parameters: parameters).responseString { response in
print(response)
}
}
As you can see its in .responseString because I apparently if I use .responseJSON it throws a code=3480 error and I want to get specific data from my own response JSON. I tried other ways to fix this online, but they all choose the .responseString option.
Why is this happening? Are the JSON types incompatible? Is there a secret to this?
I just want to get specific data from my JSON response such as "message" and its not possible when i get a string... Any help is appreciated!
I'm using Alamofire 4.3
Try following so Alamofire will run the response data through JSONSerialization, depending on the type of JSON response you can use either json as? [String : Any] or json as? [[String : Any]]
Alamofire.request(URL, method: .post, parameters: parameters).responseJSON { response in
guard response.error == nil, let json = response.result.value else {
print("Error: \(response.error?.localizedDescription ?? "no content")")
return
}
if let jsonDict = json as? [String : Any] {
print(jsonDict)
} else if let jsonArray = json as? [[String : Any]] {
print(jsonArray)
}
}
Have you tried printing the response.value to check it it's a valid JSON?
I am making an Alamofire request but getting an odd response. (Swift 3)
Alamofire.request(url, parameters: params).validate(statusCode: 200..<300).responseJSON { response in
if let result = response.result.value {
let JSON = result as! NSDictionary
print("JSON: \(JSON)")
}
This prints the following:
JSON: {
message = "Payment has been charged";
status = Success;
}
Looks solid, but I'm having trouble with two pieces of this response. First off, what is the type of this response. Array? Any? Dictionary? Second, how would I access an element in it. For instance, I want to check to see if the status equals Success.
The last piece of information I have is that my backend (in PHP) produces this with:
$response = array("status"=>"Success","message"=>"Payment has been charged");
Thank you for any insight!
I have a question relating to sending a POST request from an iOS app to a web service written in php, that will ultimately query a MySQL database.
tldr: How do I view the contents of the POST variables directly in the browser window, without refreshing?
Long version:
I had written my Swift code in Xcode, with NSURLSession, request, data etc.
I had a php web page set to var_dump($_POST); so that I could check that the data was sent in correctly (my data was a hard-coded string in Xcode for testing purposes).
I couldn't for the life of me figure out why I kept getting empty POST variables, until I decided to add a test query statement to my web page binding the POST variable. Lo and behold, the query ran successfully and my table updated.
I now realise that the reason I thought the POST variable was empty was because I was refreshing the web page in order to see the results of my var_dump. I now also know that this was deleting the POST data, because when I repeated this action with the query statement, my table was getting NULL rows.
My question is how do I view the contents of the POST variables directly in the browser window, without refreshing? I know this must be a real noob goose chase I've led myself on... but I am a noob.
Thank you
You would need to modify the service itself to output those values in some way. If this is strictly for debugging, you are better off having the service write out to a log file instead. If this is part of the requesting applications call and the data needs to be displayed to the user, the service should probably return either an XML or JSON string response that your application can parse. Otherwise, you can use Fiddler to monitor your web traffic.
Of course overtime you refresh the page you just get an empty variable.
This is what I used to test if my code was working:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
testPost() // this function will test that the code is sending the variable to your server
return true
}
func testPost() {
let variableToPost = "someVariable"
let myUrl = NSURL(string: "http://www.yourserver.com/api/v1.0/post.php")
let request = NSMutableURLRequest(URL: myUrl!)
request.HTTPMethod = "POST"
let postString = "variable=\(variableToPost)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
{ data, response, error in
if error != nil {
print(error)
return
}
do{
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
if let parseJSON = json{
let result = parseJSON["status"] as? String
let message = parseJSON["message"] as? String
if result == "Success"{
//this should return your variable
print(message)
}else{
// print the message if it failed ie. Missing required field
print(message)
}
}//if parse
} catch let error as NSError {
print("error in registering: \(error)")
} //catch
}
task.resume()
}
then your php file will only check if there is no empty post and return the variable as JSON:
post.php
<?php
$postValue = htmlentities($_POST["variable"]);
if(empty($postValue))
{
$returnValue["status"] = "error";
$returnValue["message"] = "Missing required field";
echo json_encode($returnValue);
return;
} else {
$returnValue["status"] = "success";
$returnValue["message"] = "your post value is ".$postValue."";
echo json_encode($returnValue);
}
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
}
In my programm I am using this code to get json from server:
func getJSON(urlToRequest: String) -> NSData{
return NSData(contentsOfURL: NSURL(string: urlToRequest)!)!
}
urlToRequest is creating using information from form, so the problem is if I enter only English letters in form and I get urlToRequest like:
"http://example.com/join?joinName=Max&joinEmail=my#email.com&joinPass=myPass&joinBirth=01.01.1990&joinGender=1" everything is works, but if I put for example Russian letters in form and get link:
"http://example.com/join?joinName=Максим&joinEmail=my#email.com&joinPass=myPass&joinBirth=01.01.1990&joinGender=1"
I get error with NSData fatal error: unexpectedly found nil while unwrapping an Optional value
Please, help, how I can fix this problem?
You should use stringByAddingPercentEncodingWithAllowedCharacters to sanitize your URL:
let str = "http://example.com/join?joinName=Максим&joinEmail=my#email.com&joinPass=myPass&joinBirth=01.01.1990&joinGender=1"
let url = NSURL(string: str.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLFragmentAllowedCharacterSet())!)