I ran this and nothing happens when I try to send the data. So I debugged this and the it can't read anything from the url. It says "unable to read data". I checked the url its correct, I checked this sever its good and my php code. I experience this problem only when I upgraded to swift 2 or Xcode7. Thanks for the help!
let myUrl = NSURL(string: "http://localhost/SwiftAppAndMySQL/scripts/registerUser.php");
let request = NSMutableURLRequest(URL:myUrl!);
request.HTTPMethod = "POST";
let postString = "userEmail=\(userEmail!)&userFirstName=\(userFirstName!)&userLastName=\(userLastName!)&userPassword=\(userPassword!)";
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
dispatch_async(dispatch_get_main_queue())
{
//spinningActivity.hide(true)
if error != nil {
self.displayAlertMessage(error!.localizedDescription)
return
}
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
if let parseJSON = json {
let userId = parseJSON["userId"] as? String
if( userId != nil)
{
let myAlert = UIAlertController(title: "Alert", message: "Registration successful", 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)
} else {
let errorMessage = parseJSON["message"] as? String
if(errorMessage != nil)
{
self.displayAlertMessage(errorMessage!)
}
}
}
} catch{
print(error)
}
}
}).resume()
I experience this problem only when I upgraded to swift 2 or Xcode7.
Xcode 7 contains iOS Simulator with iOS 9. iOS 9 has a new feature – App Transport Security (ATS), which prevents non-secured connections (http). More information:
App Transport Security Technote
How to allow http-connections with ATS
I show you my example of work with JSON
let mainString = "http://api.mymemory.translated.net/get?q=\(sendWord)&langpair=\(langpair)".stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLFragmentAllowedCharacterSet())!
Alamofire.request(.POST, mainString).responseJSON { (response) -> Void in
let mainDictionary = response.result.value as! [String : AnyObject]
print(mainDictionary)
let arrayDictionary = mainDictionary["matches"] as! [AnyObject]
let matchesDictionary = arrayDictionary[0] as! [String : AnyObject]
let segment = matchesDictionary["segment"] as! String
print(segment)
let translation = matchesDictionary["translation"] as! String
print(translation)
The second example
let url = NSURL(string: "http://api.mymemory.translated.net/get?q=Hello%20World!&langpair=en%7Cit")!
let dataData = NSData(contentsOfURL: url)!
let main = try! NSJSONSerialization.JSONObjectWithData(dataData, options: NSJSONReadingOptions.AllowFragments)
print(main)
Related
Swift 3.0 (Xcode 8.3)
I'm trying to make a small program, that send a username to a web data base. I have found out how to send first_name, last_name,dob,owner_mobile,owner_email,
owner_password,choice_for_verification, by using in POST method. I obtain a JSON string earlier, then when I try to parse it, I get the above error on the try NSJSONSerialization line, on the as keyword. What did I do wrong? Thanks for your answers.
#IBAction func Login_Action(_ sender: Any)
{
var responseString : String!
var request = URLRequest(url: URL(string: "http://dev.justpick2go.com/cpanel/api/owner/ownerregistration.php")!)
request.setValue("Application/x-www.ownerregistration.php.com", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let postString = "first_name=\(txtFirstName.text!)&last_name=\(txtLastName.text!)&dob=\(txtDOB.text!)&owner_mobile=\(txtMobileNo.text!)&owner_email=\(txtEmailID.text!)&owner_password=\(txtPassword.text!)" //&choice_for_verification=\(email)" // sending a parameters
print("\(postString)")
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data, error != nil else { //checking for fundamental error
print("Error is =\(String(describing: error))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200
{ // checking for http errors
print("statusCode should be 200 , but is\(httpStatus.statusCode)")
print("response is =\(String(describing: response))")
}
responseString = String(data: data, encoding: .utf8)
print("ResponseString=\(responseString!)")
do {
let json : NSDictionary! = try! JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! NSDictionary
self.parseTheJSonData(JsonData: json)
}
catch
{
print(error)
}
}
task.resume()
}
func parseTheJSonData(JsonData : NSDictionary)
{
var successMessage : String = String()
var sampleCode : Int = Int()
let verificationAlert = UIAlertController()
if ((JsonData.value(forKey: "success") as! Int) == 1)
{
successMessage = "Login is Successful"
sampleCode = JsonData.value(forKey: "success") as! Int
verificationAlert.addAction(UIAlertAction(title: "No", style: .cancel, handler: nil))
verificationAlert.addAction(UIAlertAction(title: "Yes", style: .default, handler: { (Relogin) in
let Log = self.storyboard?.instantiateViewController(withIdentifier: "") as! LoginViewController
self.navigationController?.pushViewController(Log, animated: true)
self.present(Log, animated: true, completion: nil)
}))
}
else if ((JsonData.value(forKey: "success") as! Int) == 0)
{
sampleCode = JsonData.value(forKey: "success") as! Int
successMessage = "Please try again"
verificationAlert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
}
verificationAlert.title = successMessage
OperationQueue.main.addOperation
{
self.present(verificationAlert, animated: true, completion: nil)
}
}
I have been trying to insert certain data into mysql through php. But however i am getting an error coded 3840.Below is the code i am working on:-
#IBAction func btnVerify(_ sender: Any) {
let myUrl = URL(string: "http://kumbhkaran.co.in/ios_otp_check/verifyOTP.php");
var request = URLRequest(url:myUrl!);
request.httpMethod = "POST";
let postString = "category=\(Category)&subcategory=\(SubCategory)&vendorname=\(ShopName)&managername=\(ManagerName)&managercontact=\(ManagerMobile)&mobile=\(UserName)&landline=\(Landline)&email=\(Email)&website=\(Website)&city=\(City)&address=\(Address)&area=\(Area)&pincode=\(Pincode)&rentowned=\(ShopStatus)&homedelivary=\(HomeDelivery)&pwd=\(Password)&marketing_ref=\(MarketingRef)&Working_Start_time=\(StartTime)&Working_End_time=\(EndTime)"
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
{
//spinningActivity!.hide(true)
if error != nil {
self.displayAlertMessage(messageToDisplay: error!.localizedDescription)
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
let userId = parseJSON["message"] as? String
if( userId != nil)
{
let myAlert = UIAlertController(title: "Alert", message: "Registration successful", preferredStyle: UIAlertControllerStyle.alert);
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default){(action) in
self.dismiss(animated: true, completion: nil)
}
myAlert.addAction(okAction);
self.present(myAlert, animated: true, completion: nil)
} else {
let errorMessage = parseJSON["message"] as? String
if(errorMessage != nil)
{
self.displayAlertMessage(messageToDisplay: errorMessage!)
}
}
}
} catch{
print(error)
}
}
}
task.resume()
}
However after all this code i get an error stated as below:-
Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start
with array or object and option to allow fragments not set."
UserInfo={NSDebugDescription=JSON text did not start with array or
object and option to allow fragments not set
Try this :
Set option value to allowFragments instead of mutableContainers.
Probably the json response is not properly formed.
let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary
I am new to web development and Swift
I created a web api based on ASP.NET and I connected my ios app so I can do GET, POST, PUT, DELETE.
When I send GET request with specific ID number
I get output in Xcode as following:
Data:
Optional("{\"Id\":1,\"UserName\":\"codeinflash\",\"UserPassword\":\"Wldnrodxxxx\",\"UserEmail\":\"codeinflash#gmail.com\",\"Rebate\":0.00,\"MemCom\":123.44}")
Here is function in Swift:
//GET /api/account/{id}
#IBAction func GetAccount(_ sender: Any) {
let _accountIdNumber = AccountIdNumber.text
if (_accountIdNumber!.isEmpty){
createAlert(title: "Warning", message: "Account ID # is required")
return
}
let restEndPoinst: String = "http://tresmorewebapi2.azurewebsites.net/api/account/" + _accountIdNumber!;
guard let url = URL(string: restEndPoinst) else {
print("Error creating URL")
return
}
var urlRequest = URLRequest(url: url)
urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
// api key need urlRequest.setValue(<#T##value: String?##String?#>, forHTTPHeaderField: "APIKey")
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
var userEmail = ""
var rebate = ""
var memcom = ""
let task = session.dataTask(with: urlRequest, completionHandler:
{
(data, response, error) in
print("Error:")
print(error)
print("response:")
print(response)
print("Data:")
print(String(data: data!, encoding: String.Encoding.utf8))
//////////////I think I need logic here to filter the data
userEmail = data.substring of find emailaddress
rebate = data.substring find users' rebate
memcom = same logic
then show alert window with his info and I will show his info on next page which is a Dashboard page view
})
task.resume()
}
Honestly I am not sure the Data is JSON data but the output in Xcode is in string.
My purpose is get uer's data and store in local variables that passes them to next view(Dashboard) in ios Swift.
Thank you!
Added
Here is the task getting data from web api in login fuction swift
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
var userEmail = ""
var rebate = ""
var memcom = ""
let task = session.dataTask(with: urlRequest, completionHandler:
{
(data: Data?, response: URLResponse?, error: Error?) in
print("Error:")
print(error)
print("response:")
print(response)
print("Data:")
print(String(data: data!, encoding: String.Encoding.utf8))
let json = try? JSONSerialization.jsonObject(with: data!) as! [String: AnyObject] ?? [:];
userEmail = json?["UserEmail"] as? String ?? ""
createAlert(title: "Got User Eamil Address!", message: userEmail)
})
task.resume()
But I get nothing in my alert view. The alert view working fine I tested.
Here is my createAlert fuction in Swift
func createAlert(title:String, message:String){
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (anction) in
alert.dismiss(animated: true, completion: nil)}))
self.present(alert, animated: true, completion: nil)
}
You have answer in comments already, but this is less "swifty" way, more readable for someone new to Swift (pay attention and try to understand what is going on and how you can make this more compact):
do {
guard let unwrappedData = data else{
//data is nil - handle case here
return //exit scope
}
guard let dictionary = try JSONSerialization.jsonObject(with: unwrappedData) as? [String:AnyObject] else {
//you cannot cast this json object to dictionary - handle case here
return //exit scope
}
userEmail = dictionary["UserEmail"]
DispatchQueue.main.async { [weak self] in
self?.createAlert(title: "Got User Eamil Address!", message: userEmail)
}
} catch _ {
//handle error
}
I am using swift to access the youtubeinmp3 api and I am stuck. I am quite new to this so please be gentle. Using the api I get a json response and use the link property that gets returned to download a file. However the link I get looks like this : http://www.youtubeinmp3.com/download/get/?i=PL6sPTHlt1KHYj6hUsDxW8zjAgcNiU1SXVHIzxnSALX8%2FKNV35SZqd9l5qxk7LOiD%2FcrlIUe5JJvgZxKg0WeMw%3D%3D
The link works fine in a browser like Chrome but the swift app downloads an unknown file, definitely not an mp3.
I used this question to find the code.
Any ideas on how I could go through the redirect to get to the mp3 download link?
Thank you in advance.
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let videoURL1 = (videosArray[indexPath.row]).objectForKey("videoID") as! String
//let videoURL = "https://www.youtube.com/watch?v=\(videoURL1)"
let videoURL = "//www.youtubeinmp3.com/fetch/?video=https://www.youtube.com/watch?v=\(videoURL1)"
let urlString = "http://www.youtubeinmp3.com/fetch/?format=JSON&video=\(videoURL)"
let url = NSURL(string: "http://www.youtubeinmp3.com/fetch/?format=JSON&video=\(videoURL)")
let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "GET"
let task = session.dataTaskWithRequest(request, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
if (error == nil) {
if let response = response as? NSHTTPURLResponse {
print("response=\(response)")
if response.statusCode == 200 {
if data != nil {
do {
let responseJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as! NSDictionary;
//let urlString = NSURL(string:"\(responseJSON["link"] as! String)")
//print("URLString: \(urlString)")
//let directDownloadURL = NSURL(string: urlString)
// Call your method loadFileAsync
// code here
let urlString = responseJSON["link"] as! String
//let finalURLString = urlString.stringByReplacingOccurrencesOfString("get", withString: "mp3")
print(urlString)
dispatch_async(dispatch_get_main_queue(), {
let identifier = NSUUID().UUIDString
let downloadItem = DownloadsTableViewCellItem(identifier: identifier, urlString: urlString, infoLabelTitle: selectedName, stateLabelTitle: "Press Download", progressLabelTitle: "", action: DownloadsTableViewCellAction.Download)
DownloadsViewController().addDownloadItem(downloadItem, withIdentifier: identifier)
SVProgressHUD.showSuccessWithStatus("Download Added")
print("Download Task Added")
})
}
catch let JSONError as NSError {
print("\(JSONError)")
}
catch {
print("unknown error in JSON Parsing");
}
}
}
}
}
else {
print("Failure: \(error!.localizedDescription)");
}
})
task.resume()
}
Things i did :
I have one url api which will display some data in my table view.
2.And i fetch the particular value called "_id" from my url and i just pass that value to one custom class object.
Then i am passing that class object value to one of my another api calling url.In there i getting the value as nil.
Here is the code that ia m populating the data to my table view.And i am taking the particular value from api "_id" And i am storing that value to one custom class object :
// Showing favourites
func populateFavourites()
{
let token = NSUserDefaults.standardUserDefaults().valueForKey("access_token") as! String
let headers = ["x-access-token": token]
let request = NSMutableURLRequest(URL: NSURL(string: "some url")!)
request.HTTPMethod = "GET"
request.allHTTPHeaderFields = headers
let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
if (error != nil)
{
print(error)
}
else
{
dispatch_async(dispatch_get_main_queue(),{
if let json = (try? NSJSONSerialization.JSONObjectWithData(data!, options: [])) as? Dictionary<String,AnyObject>
{
print("Success Got Json Data")
let success = json["success"] as? Int
if(success == 1)
{
let jsonData = json["data"] as! NSArray
if(jsonData.count>0)
{
for items in jsonData
{
let BObj = items as! NSDictionary
let BusinessDetails = BObj.valueForKey("business_id") as! Dictionary<String,AnyObject>
self.FavBusinessValues.append(Businessdata(json:BusinessDetails))
print(items)
let FavId = BObj.valueForKey("_id") as! String
self.FavDelete?.FavIds = FavId
print(FavId)
}
self.tableView.reloadData()
}
else
{
self.CreateNoDataLabel()
}
}
else
{
let message = json["message"] as? String
print("Fav Message ",message)
let alert = UIAlertController(title: "Error: ", message: message, preferredStyle: UIAlertControllerStyle.Alert)
// add an action (button)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
// show the alert
self.presentViewController(alert, animated: true, completion: nil)
}
}
})
}
})
dataTask.resume()
}
In my above code i am taking the particular value "_id" and i am passing to my custom objet class :
let FavId = BObj.valueForKey("_id") as! String
self.FavDelete?.FavIds = FavId
print(FavId)
This print(FavId) is printing the correct value.Here is my cutom class object that store that value of "_id" :
import Foundation
class Favdelete
{
var FavIds : String?
init(json:String)
{
self.FavIds = json as? String
}
}
Then i am passing the "_id" objet value FavIds to my one of my api calling.That code is under below :
func apidelete () {
let Favouriteid = FavDelete?.FavIds
print(Favouriteid)
let userToken = NSUserDefaults.standardUserDefaults().valueForKey("access_token") as! String;
print(userToken)
let headers = [
"x-access-token": userToken,
"cache-control": "no-cache",
"postman-token": "81fbd1fc-c333-3ceb-272a-a9ecffb2dad2",
"content-type": "application/x-www-form-urlencoded"
]
let FBI = "favourite_id="+Favouriteid!
let postData = NSMutableData(data: FBI.dataUsingEncoding(NSUTF8StringEncoding)!)
let request = NSMutableURLRequest(URL: NSURL(string: "some url")!,
cachePolicy: .UseProtocolCachePolicy,
timeoutInterval: 10.0)
let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
let httpResponse = response as? NSHTTPURLResponse
print(httpResponse)
dispatch_async(dispatch_get_main_queue(),{
if let json = (try? NSJSONSerialization.JSONObjectWithData(data!, options: [])) as? Dictionary<String,AnyObject>
{
print("Success Got Json Data");
let success = json["success"] as? Int;
var message:String = "";
if(success == 1)
{
message = json["message"] as! String;
}
else
{
message = json["message"] as! String;
}
print(message);
let alert = UIAlertController(title: "Message from server", message: message, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
})
}
})
dataTask.resume()
}
When i try to print this :
let Favouriteid = FavDelete?.FavIds
print(Favouriteid)
I ma getting crash and it says nil printing in my console.
Can any one please help me out.!!
Updated :
Under my first function method.That is when i get the particular value and store that value to my custom object .I just print it.I am getting nil there too.
The line is :
let FavId = BObj.valueForKey("_id") as! String
self.FavDelete?.FavIds = FavId
print(self.FavDelete?.FavIds)
Its printing nil
Updated :
Although you have a custom class you need to initialize it to use its method. Without proper initialization you cannot set its properties.
So in the ViewController, declare the object for that class at the top.
var FavbDelete : Favdelete?
At this point, your FavDelete is nil.
Then you get the "_id" from populateFavourites() method. You may be calling it from viewDidLoad() method. There you get FabId as
let FavId = BObj.valueForKey("_id") as! String
But now you cannot directly store it into FabDelete Object. because it has not been initialized. Although Xcode doesn't throw any error when you do that, But the resulting value will be nil. So now you initialize that object using the initializer you built in custom class.
self.FavDelete = Favdelete(json: FavId)
Now the FavDelete object is initialized , and when you call apidelete() method after this step, you can access the value of id by using
let someVar = self.FavDelete?.FavIds
Since, all of this work is being done in background using NSURLSession,ensure that you are not calling apidelete before the FabDelete Object is initialized.