I can see this question has been asked before but can't find that anyone has accepted an answer anywhere. My error is:
NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.
let myUrl = NSURL(string: "http://www.example.com/xxx.php")
let request = NSMutableURLRequest(URL:myUrl!);
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST";
let postString = "email=\(useremail)&pass=\(userpassword)&username=\(username)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
let task = session.dataTaskWithRequest(request) { (data, response, error) in
// if error
if error != nil {
print("error=\(error)")
return
}
var json: NSDictionary? = nil
do {
json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
} catch {
print("error=\(error)")
}
if let parseJSON = json {
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!;
}}
I am trying to send email, pass, username, and successfully presenting my alert and changing view controller. but I am yet to hit database. It's PHP and MYSQL via url.
try changing this line
json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
to this
json = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments) as? NSDictionary
Related
below is my code. I want the value for Latitude and Longitude in my Poststring. But When he do the poststring my values are still nil because swift didn't update the location yet. So how can I wait for latitude and longitude before poststring gets the Values? I heard something of didset but I don't know how to use it and where I have to use it.
import Foundation
import CoreLocation
protocol FeedmodelProtocol: class {
func itemsDownloaded(items: NSArray)
}
class Feedmodel: NSObject, URLSessionDataDelegate, CLLocationManagerDelegate {
weak var delegate: FeedmodelProtocol!
let locationManager = CLLocationManager() // create Location Manager object
var latitude : Double?
var longitude : Double?
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location: CLLocationCoordinate2D = manager.location?.coordinate else { return }
// set the value of lat and long
latitude = location.latitude
longitude = location.longitude
}
func downloadItems() {
self.locationManager.requestAlwaysAuthorization()
// For use in foreground
// You will need to update your .plist file to request the authorization
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
let myUrl = URL(string: "http://example.com/stock_service4.php");
let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default)
var request = URLRequest(url:myUrl!)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
var postString = ""
if let lat = latitude, let long = longitude {
locationManager.stopUpdatingLocation()
postString = "lati=\(Int(lat))&longi=\(Int(long))"
// do task here now that postString is not empty
}
request.httpBody = postString.data(using: .utf8)
let task = defaultSession.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(String(describing: 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 = \(String(describing: response))")
print("error=\(String(describing: error))")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
print("error=\(String(describing: error))")
self.parseJSON(data)
}
task.resume()
}
func parseJSON(_ data:Data) {
var jsonResult = NSArray()
do{
jsonResult = try JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray;
} catch let error as NSError {
print(error)
}
var jsonElement = NSDictionary()
let stocks = NSMutableArray()
for i in 0 ..< jsonResult.count
{
print(jsonResult)
jsonElement = jsonResult[i] as! NSDictionary
let stock = Stockmodel()
//the following insures none of the JsonElement values are nil through optional binding
if let Datum = jsonElement["Datum"] as? String,
let Tankstelle = jsonElement["Tankstelle"] as? String,
let Kraftstoff1 = jsonElement["Kraftstoff1"] as? String,
let Preis1 = jsonElement["Preis1"] as? String,
let Kraftstoff2 = jsonElement["Kraftstoff2"] as? String,
let Preis2 = jsonElement["Preis2"] as? String,
let Notiz = jsonElement["Notiz"] as? String,
let longitude = jsonElement["longitude"] as? String,
let latitude = jsonElement["latitude"] as? String
{
print (Datum)
print(Tankstelle)
print(Kraftstoff1)
print(Preis1)
print(Kraftstoff2)
print(Preis2)
print(Notiz)
print(longitude)
print(latitude)
stock.Datum = Datum
stock.Tankstelle = Tankstelle
stock.Kraftstoff1 = Kraftstoff1
stock.Preis1 = Preis1
stock.Kraftstoff2 = Kraftstoff2
stock.Preis2 = Preis2
stock.Notiz = Notiz
stock.longitude = longitude
stock.latitude = latitude
}
stocks.add(stock)
}
DispatchQueue.main.async(execute: { () -> Void in
self.delegate.itemsDownloaded(items: stocks)
})
}
}
Thank You!
The function locationManager(_:didUpdateLocations:) is called every time when the location is update. So you should add downloadItems() in the location manager like this :
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location: CLLocationCoordinate2D = manager.location?.coordinate else { return }
// set the value of lat and long
latitude = location.latitude
longitude = location.longitude
downloadItems()
}
See the documentation about locationManager(_:didUpdateLocations:)
this is my code for the Json request to php and to show the data in the app:
import Foundation
protocol FeedmodelProtocol: class {
func itemsDownloaded(items: NSArray)
}
class Feedmodel: NSObject, URLSessionDataDelegate {
weak var delegate: FeedmodelProtocol!
func downloadItems() {
let myUrl = URL(string: "http://www.example.net/zumba.php");
var request = URLRequest(url:myUrl!)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let postString = "firstName=51&lastName=6";
request.httpBody = postString.data(using: .utf8)
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=\(String(describing: 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 = \(String(describing: response))")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
self.parseJSON(data)
}
task.resume()
}
func parseJSON(_ data:Data) {
var jsonResult = NSArray()
do{
jsonResult = try JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray;
} catch let error as NSError {
print(error)
}
var jsonElement = NSDictionary()
let stocks = NSMutableArray()
for i in 0 ..< jsonResult.count
{
print(jsonResult)
jsonElement = jsonResult[i] as! NSDictionary
let stock = Stockmodel()
//the following insures none of the JsonElement values are nil through optional binding
if let Datum = jsonElement["Datum"] as? String,
let Tankstelle = jsonElement["Tankstelle"] as? String,
let Kraftstoff1 = jsonElement["Kraftstoff1"] as? String,
let Preis1 = jsonElement["Preis1"] as? String,
let Kraftstoff2 = jsonElement["Kraftstoff2"] as? String,
let Preis2 = jsonElement["Preis2"] as? String,
let Notiz = jsonElement["Notiz"] as? String,
let longitude = jsonElement["longitude"] as? String,
let latitude = jsonElement["latitude"] as? String
{
print (Datum)
print(Tankstelle)
print(Kraftstoff1)
print(Preis1)
print(Kraftstoff2)
print(Preis2)
print(Notiz)
print(longitude)
print(latitude)
stock.Datum = Datum
stock.Tankstelle = Tankstelle
stock.Kraftstoff1 = Kraftstoff1
stock.Preis1 = Preis1
stock.Kraftstoff2 = Kraftstoff2
stock.Preis2 = Preis2
stock.Notiz = Notiz
stock.longitude = longitude
stock.latitude = latitude
}
stocks.add(stock)
}
DispatchQueue.main.async(execute: { () -> Void in
self.delegate.itemsDownloaded(items: stocks)
})
}
}
I have a mySQL PHP what seems to work because my Console shows me that:
responseString = Optional("[\"51\",\"6\"]") (
51,
6 ) Could not cast value of type 'NSTaggedPointerString' (0x1045cbf68) to 'NSDictionary' (0x1045cc288). 2018-06-20
23:29:34.586355+0200 TankBilliger[37631:3753628] Could not cast value
of type 'NSTaggedPointerString' (0x1045cbf68) to 'NSDictionary'
(0x1045cc288). (lldb)
I don't know what the problem is, can anyone help?
Thank You!
The problem is , your getting data as dictionary but you taken as string
delete this line and try
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
This method parseJSON() do above functionality
I have been trying to fetch certain values from database through my postString, but it doesn't return any value. Php is tested and its working fine, any help would be appreciated. Below is the code.
import UIKit
class DisplayDetailedViewController: UIViewController {
var role = String()
var date = String()
var city = String()
var mark_ref = String()
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func getData(){
let myUrl = URL(string:"http://xxxxxx.co.in/xxxxx/show_report1.php")
var request = URLRequest(url: myUrl! as URL)
request.httpMethod = "POST"
let postString = "city=\(city)&date=\(date)&market_rep=\(mark_ref)"
request.httpBody = postString.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
DispatchQueue.main.async{
if error != nil{
print("error is\(String(describing: error))")
}
do{
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
let myBoard : String!
myBoard = parseJSON["success"] as! String?
print(myBoard)
}
}
catch {
print(error)
}
}
}
task.resume()
}
}
Try 1: Replace below line (NSDictionary)
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
Try 2: Replace below line (NSArray)
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSArray
Try 3: Replace below line (NSString)
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSArray
Also try to options: .mutableContainers -> options: JSONSerialization.ReadingOptions.allowFragments
I am new on Swift but I was follwoing some examples like how to make a login app sending username and password fields to a php file and getting the json response back.
When I print my responseString I get:
[{"userid":1,"username":"rodrigo","password":"minhoca","groupname":"couple"}]
But when I try to parse the json I never can set the username variable because never gets into that part of the code, I just get "here"
Thanks for the help
func sendLoginInfo(username: String, password: String) -> String{
if let url = URL(string: "myphpurl"){
let request = NSMutableURLRequest(url:url)
request.httpMethod = "POST";// Compose a query string
let postString = "?username=\(myUsername)&password=\(myPassword)"
request.httpBody = postString.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with:request as URLRequest){
data, response, error in
if error != nil{
print("1\(error)")
}
else{
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("response string = \(responseString!)")
}
do {
if let convertedJsonIntoDict = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary {
// Print out dictionary
print(convertedJsonIntoDict)
// Get value by key
let firstNameValue = convertedJsonIntoDict["username"] as? String
print("here = \(firstNameValue!)")
}
else{
print("here")
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
task.resume()
}
return ""
}
Change the NSDictionary to NSArray in your code because you are getting an array and trying to convert to dictonary:
if let convertedJson = try JSONSerialization.jsonObject(with: data!, options: []) as? NSArray
get the object at index 0 which will give you dictonary & then you can get username
So the Final code will be:
func sendLoginInfo(username: String, password: String) -> String{
if let url = URL(string: "myphpurl"){
let request = NSMutableURLRequest(url:url)
request.httpMethod = "POST";// Compose a query string
let postString = "?username=\(myUsername)&password=\(myPassword)"
request.httpBody = postString.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with:request as URLRequest){
data, response, error in
if error != nil{
print("1\(error)")
}
else{
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("response string = \(responseString!)")
}
do {
if let convertedJsonIntoDict = try JSONSerialization.jsonObject(with: data!, options: []) as? NSArray {
// Print out dictionary
print(convertedJsonIntoDict)
// Get value by key
let firstNameValue = (convertedJsonIntoDict[0] as! NSDictionary)["username"] as? String
print("here = \(firstNameValue!)")
}
else{
print("here")
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
task.resume()
}
return ""
}
i have the php file that return json_encode value and when i go to the http address they give me the value but
i cant get the value form the server side to my apps i have try many time but its not get it
func loadData() {
let url = NSURL(string: "http://example.com/getExpo.php")
let request = NSMutableURLRequest(URL: url!)
// modify the request as necessary, if necessary
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
if error != nil {
// Display an alert message
print(error)
return
}
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary
if (json != nil) {
//let userId = parseJSON["userId"] as? String
// Display an alert message
let userMessage = json!["id"] as? String
print(userMessage)
} else {
// Display an alert message
let userMessage = "Could not fetch Value"
print(userMessage)
}
} catch {
print(error)
}
}).resume()
}
any one can help , thank you !!
Your JSON response is an array of dictionaries:
[{"id":"115","expoName":"aziz","expoDetails":"aziz","expoPhone":"aziz","expoLocation":"aziz"}]
But you're trying to cast it as a Dictionary:
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary
The solution of course is to cast it as an array:
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSArray
Better use Swift types if you can:
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [[String:AnyObject]]
Then for example you can use a loop:
if let json = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [[String:AnyObject]] {
for item in json {
let userMessage = item["id"] as? String
}
}