POST data to PHP and getting JSON with SwiftyJSON - ios

I'm developing an iOS app with Xcode and Swift.
I'm getting JSON data with SwiftyJSON.swift and the following code:
import UIKit
class ViewController: UIViewController {
var dict = NSDictionary()
#IBOutlet weak var firstLb: UILabel!
#IBOutlet weak var secondLb: UILabel!
var uasername = "TestUserName"
override func viewDidLoad() {
super.viewDidLoad()
let urlString = "http://example.com/showUserInfo.php"
if let url = NSURL(string: urlString) {
if let data = try? NSData(contentsOfURL: url, options: []) {
let json = JSON(data: data)
print(json)
let f = json[0]["name"].stringValue
let s = json[0]["age"].stringValue
firstLb.text = f
secondLb.text = s
}
}
}
}
But I want to be able to POST a value to showUserInfo.php, too.
My showUserInfo.php PHP script looks like this:
<?php
$root = realpath($_SERVER["DOCUMENT_ROOT"]);
include "$root/config.php";
$username = $_POST['username'];
$stmt = $pdo->prepare('SELECT * FROM contact WHERE username = :username');
$stmt->execute(array('username' => $username));
$userData = array();
while($row=$stmt->fetch(PDO::FETCH_ASSOC)){
$userData[] = $row;
}
echo json_encode($userData);
?>
Getting JSON data from the PHP script with my Swift code works very well when using $username = "TestUserName"; instead of $username = $_POST['username']; in my PHP script. But I want to be able to $_POST a specific username to this PHP script that is declared in my app.
Does anybody know how to do this without the need of importing a library or so?

Here is Alamofire and SwiftyJSON implementation
let parameters = ["username": "TestUserName"]
Alamofire.request(.POST, "http://example.com/showUserInfo.php",parameters: parameters).responseJSON { response in
debugPrint(response.result.value)
let json = JSON(data: response.data!)
print(json)
let f = json[0]["name"].stringValue
let s = json[0]["age"].stringValue
firstLb.text = f
secondLb.text = s
}

In default behaviour NSURL uses GET as a HTTP method. You have to use NSMutableURLRequest and set property called HTTPMethod to POST. If you want to see exactly example of using post request in Swift 2/3 visit here.

Related

Read json content from remote and printing on main interface in Xcode with swift 5

I got an error while reading json content from remote url and printing on main interface in iOS Simulator.
MBP13"2016 && Mojave 10.14.6 && xcode 10.3(10G8) && swift 5
Here is the code sample. I had change a bit from "https://www.simplifiedios.net/swift-json-tutorial/"
import UIKit
class ViewController: UIViewController {
//the json file url
let URL_POSTS = "https://demo.ghost.io/ghost/api/v2/content/posts/?key=22444f78447824223cefc48062";
//A string array to save all the names
var nameArray = [String]()
//the label we create
#IBOutlet weak var labelTest: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//calling the function that will fetch the json
getJsonFromUrl();
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//this function is fetching the json from URL
func getJsonFromUrl(){
//creating a NSURL
let url = NSURL(string: URL_POSTS)
//fetching the data from the url
URLSession.shared.dataTask(with: (url as URL?)!, completionHandler: {(data, response, error) -> Void in
if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary {
//printing the json in console
print(jsonObj.value(forKey: "posts")!)
//getting the companies tag array from json and converting it to NSArray
if let heroeArray = jsonObj.value(forKey: "posts") as? NSArray {
//looping through all the elements
for heroe in heroeArray{
//converting the element to a dictionary
if let heroeDict = heroe as? NSDictionary {
//getting the name from the dictionary
if let name = heroeDict.value(forKey: "name") {
//adding the name to the array
self.nameArray.append((name as? String)!)
}
}
}
}
OperationQueue.main.addOperation({
//calling another function after fetching the json
//it will show the names to label
self.showNames()
})
}
}).resume()
}
func showNames(){
//looing through all the elements of the array
for name in nameArray{
//appending the names to label
labelTest.text = labelTest.text! + name + "\n";
}
}
}
From the result above, it seems ok that I had found content result in console while fetching json from remote url , but nothing shows up on main interface with iOS simulator.
json result in console
main interface nothing show up in IOS Simulator
I've had some kind of this problem with JSON keys and NSDictionary usage. What worked out for me was just using Decodable protocol. I would recommend using this new API for parsing instead of JSONSerialization.
Here's a few good reads:
https://medium.com/swiftly-swift/swift-4-decodable-beyond-the-basics-990cc48b7375
https://medium.com/xcblog/painless-json-parsing-with-swift-codable-2c0beaeb21c1

let url = URL(string: item)! returning nil in swift

Really cannot figure this one out, the URL prints and is not equal to nil, and it works in the browser when I paste it in. Any ideas?
import UIKit
class WebViewController: UIViewController {
var postLink: String = String()
#IBOutlet weak var mywebView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
print(postLink)
let attempt = postLink
let url: URL = URL(string: attempt)!
let request: URLRequest = URLRequest(url: url)
mywebView.loadRequest(request)
}
The error occurs at:
let url: URL = URL(string: attempt)!
I am guess you are passing the urlString from another controller, do that instead
var postUrlString:String? //<-- make it optional
override func viewDidLoad() {
super.viewDidLoad()
guard let urlString = postUrlString, // forced unwrapped
let url = URL(string: urlString)
else { return } // if there is any optional we return
// else continue
let request: URLRequest = URLRequest(url: url)
mywebView.loadRequest(request)
}
The error is simple, postLink, you are providing to create URL is not correct. My guess is its empty.(Just a guess) and you have forgot to set it.
Avoid using force unwrapping ! in your code as much as possible.
You should either use guard let or if let in the scenarios.
In your case you might want to show some error to user when you are unable to load. Instead of
let url: URL = URL(string: attempt)!
use
if let url = URL(string: attempt) {
let request = URLRequest(url: url)
mywebView.loadRequest(request)
} else {
// Do something like. Show an alert that could not load webpage etc.
}
Alternatively you can use guard let, but it would require to return from the function where it is used. To know more about uses of if and guard let you can go through by blog post here.

Caching JSON - Haneke get fetch values

I am not able assign the values for var backgroundArray and var newsArray, as the fetch method returns nil. Within the fetch the values are available though. Also, is it a good way to refresh the cache by removing it such way in the commented section?
init(update: Bool){
let dataurl = "http://example.com"
let imgurl = "http://example.com"
let newsDataURL = NSURL(string: dataurl)!
let backgroundURL = NSURL(string: imgurl)!
var backgroundArray = [JSON]()
var newsArray = [JSON]()
let cache = Shared.JSONCache
// if update{
// cache.remove(key: dataurl)
// cache.remove(key: imgurl)
// }
cache.fetch(URL: newsDataURL).onSuccess { json in
let data = json.asData()
newsArray = JSON(data: data).arrayValue
}
cache.fetch(URL: backgroundURL).onSuccess{ json in
let data = json.asData()
backgroundArray = JSON(data: data).arrayValue
}
populateStories(newsArray, backgroundArray: backgroundArray)
}

SwiftyJSON - issues with parsing

I try to parse json with SwiftyJSON. One of the fields have url to image and i try to save it as NSData but I face crash and console errors. Crash appears when compiler comes to object creation
code it the following
var JSONStorage : [Article?]?
var objects = [Article?]()
override func viewDidLoad() {
super.viewDidLoad()
let number = arc4random_uniform(1000)
let urlString = "http://wirehead.ru/article.json?\(number)"
if let url = NSURL(string: urlString) {
if let data = try? NSData(contentsOfURL: url, options: []) {
let json = JSON(data: data)
for element in json["article"].arrayValue {
let id = Int(element["id"].stringValue)
let title = element["title"].stringValue
let subtitle = element["subtitle"].stringValue
let body = element["body"].stringValue
let img = element["images"]["main"].rawValue
let obj:Article = Article(id: id!, title: title, subtitle: subtitle, body: body, mainImage: img as! NSData)
objects.append(obj)
print("We are inside if let")
}
}
}
print(objects)
}
Link to JSON is http://wirehead.ru/article.json and here is with highlight http://pastebin.com/AAEFjsQN
Error that I get is
Any advice ?
["images"]["main"] contains an URL represented by a String
To get the image data, use something like this
let imgURLString = element["images"]["main"].stringValue
if let url = NSURL(string:imgURLString) {
let img = NSData(contentsOfURL:url)
}

Parsing a json file returns unwanted result

After a bit of struggling I finally got my Json file to parse. Although I guess it is parsing.. I am getting nil when Trying to access a value with alot of "objects". This is my code using the swiftyJson library. And here is how my json looks like. The code I am using is
import UIKit
class MapViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let jsonData = getJSON("hls", extn: "json") {
println(jsonData)
let jsonDataResult = JSON(jsonData)
var js = jsonDataResult["name"].string
println("\(js)")
}
}
func getJSON(fileName: String, extn: String) -> NSData?
{
if let fileURL = NSBundle.mainBundle().URLForResource(fileName, withExtension: extn) {
if let data = NSData(contentsOfURL: fileURL) {
return data
}
}
return nil
}
}
I don't understand what I am doing wrong getting the following output in my console. Any help and tips would be appreciated!
When using SwiftyJSON, I believe you need to use the other initializer. That is to say:
let jsonDataResult = JSON(jsonData)
in order for that to work jsonData would already have been run through and parsed once before. The init you are wanting is the following, because you are passing it raw nsData as seen in your output.
let jsonDataResult = JSON(data: jsonData)

Resources