This question already has answers here:
How can I get the Data from NSURLSession.sharedSession().dataTaskWithRequest
(2 answers)
JSON parsing swift, array has no value outside NSURLSession
(1 answer)
Closed 4 years ago.
at my form load, i need to get a data from json string and push it into an arraylist. When i check my code with breakpoints, my cursor enters my method, going through, and it get task2, pass "if" then stopped at var sec="" then exit my method, after 2-3 seconds, it enters do for.
Whats wrong with my code?
override func viewDidLoad() {
super.viewDidLoad()
let urlJsonToken2 = "https://services.domain.com/"
let myURL2 = NSURL(string: urlJsonToken2)
let request2 = NSMutableURLRequest(url: myURL2! as URL)
request2.httpMethod = "GET"
request2.addValue("Bearer "+tokenNewId, forHTTPHeaderField: "Authorization")
request2.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "content-type")
request2.setValue("application/json", forHTTPHeaderField: "Accept")
let task2 = URLSession.shared.dataTask(with: request2 as URLRequest) {(data2, response2, error2) -> Void in
if let unwrappedData2 = data2 {
do {
guard let records = try? JSONSerialization.jsonObject(with: unwrappedData2, options: .mutableContainers) as? [[String: Any]] else {
return
}
for item in records! {
let id = item["id"] as? intmax_t
let name = item["name"] as? String
self?.ArrayList.append(ClassCat(id:id!, id: name!, name));
}
} catch {}
}
} task2.resume()
var sec = ""
}
Related
In my iOS App i'm able to download data from a database, but actually all the operations are made in background and the main thread is still active, even the GUI. I also tried to make a 'sleep' with
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(3)) { ... }
With this delay everthing works fine, but it's not a good solution. How can i change my code to do this in the main thread? Possibly with loadingIndicator.
This is my code (checking if username exists):
func CheckIfUsernameExists(username : String, passwordFromDb : inout String, errorMsg : inout String)
{
//declare parameter as a dictionary which contains string as key and value combination. considering inputs are valid
var _errorMsg = ""
var _psw = ""
var parameters : [String : Any]?
parameters = ["username": username,
"action": "login"]
print(parameters!)
let session = URLSession.shared
let url = "http://www.thetestiosapp.com/LoginFunctions.php"
let request = NSMutableURLRequest()
request.url = URL(string: url)!
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField:"Accept")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField:"Content-Type")
do{
request.httpBody = try JSONSerialization.data(withJSONObject: parameters!, options: .sortedKeys)
let task = session.dataTask(with: request as URLRequest, completionHandler: {(data, response, error) in
if let response = response {
let nsHTTPResponse = response as! HTTPURLResponse
let statusCode = nsHTTPResponse.statusCode
print ("status code = \(statusCode)")
}
if let error = error {
print ("\(error)")
}
if let data = data {
do{
_psw = self.parseJSON_CheckIfUsernameExists(data, errorMsg: &_errorMsg)
}
}
})
task.resume()
}catch _ {
print ("Oops something happened buddy")
errorMsg = "Usarname non recuperato (1)"
}
passwordFromDb = _psw
errorMsg = _errorMsg
}
You’re attempting to update passwordFromDb and errorMsg at the end of this method. But this is an asynchronous method and and those local variables _psw and _errorMsg are set inside the closure. Rather than trying to defer the checking of those variables some arbitrary three seconds in the future, move whatever “post request” processing you need inside that closure. E.g.
func CheckIfUsernameExists(username : String, passwordFromDb : inout String, errorMsg : inout String) {
//declare parameter as a dictionary which contains string as key and value combination. considering inputs are valid
let parameters = ...
let session = URLSession.shared
var request = URLRequest()
...
do {
request.httpBody = ...
let task = session.dataTask(with: request) { data, response, error in
if let httpResponse = response as? HTTPURLResponse,
let statusCode = httpResponse.statusCode {
print ("status code = \(statusCode)")
}
guard let data = data else {
print (error ?? "Unknown error")
return
}
let password = self.parseJSON_CheckIfUsernameExists(data, errorMsg: &_errorMsg)
DispatchQueue.main.async {
// USE YOUR PASSWORD AND ERROR MESSAGE HERE, E.G.:
self.passwordFromDb = password
self.errorMsg = _errorMsg
// INITIATE WHATEVER UI UPDATE YOU WANT HERE
}
}
task.resume()
} catch _ {
print ("Oops something happened buddy")
errorMsg = "Usarname non recuperato (1)"
}
}
This question already has answers here:
Swift 3 URLSession.shared() Ambiguous reference to member 'dataTask(with:completionHandler:) error (bug)
(14 answers)
Closed 5 years ago.
How to solve this issue
Ambiguous reference to member 'dataTask(with:completionHandler:)'
guard let requestUrl = URL(string:"http://www.digi.com/laravel_api_demo/api/demoapi") else { return }
let request = NSMutableURLRequest(url: requestUrl)
request.httpMethod = "POST"
let postString = "firstName=James&lastName=Bond"
request.httpBody = postString.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request){ (data, response, error) in
if error != nil
{
//print(error)
return
}
//You can print out response object
print("response = \(response)")
//Print out response body
let responseString = String(data: data, encoding: NSUTF8StringEncoding)
print("response data = \(responseString)")
var err: Error?
var json = JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
var firstNameValue = parseJSON["firstName"] as? String
print("first name value = \(firstNameValue)")
}
}
task.resume()
}
Call should be like this , first parameter is of type URL not NSMutableURLRequest
guard let requestUrl = URL(string:"http://www.digi.com/laravel_api_demo/api/demoapi") else { return }
var request = URLRequest(url: requestUrl)
request.httpMethod = "POST"
let postString = "firstName=James&lastName=Bond"
request.httpBody = postString.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request){ (data, response, error) in
if error != nil
{
//print(error)
return
}
}
task.resume()
see here signature of available methods
This question already has answers here:
Swift closure async order of execution
(1 answer)
Returning data from async call in Swift function
(13 answers)
Returning method object from inside block
(3 answers)
Closed 5 years ago.
func isEmailTaken(email:String) -> String {
let myUrl = URL(string: "URL");
var request = URLRequest(url:myUrl!)
request.httpMethod = "POST"
let postString = "email=\(email)";
request.httpBody = postString.data(using: String.Encoding.utf8);
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
if error != nil {
print("error=\(error)")
return
}
print("response = \(response)")
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
let emailAlreadyTakenData = parseJSON["emailAlreadyTaken"] as! String
print(emailAlreadyTakenData)
}
} catch {
print(error)
}
}
task.resume()
return(emailAlreadyTakenData)
}
The line :
return(emailAlreadyTakenData)
Doesnt get the variable value. So, the http request gets the data successfully but the return command doesn't parse the correct data.
Your variable is in different scope, then when you declared it. So you cannot access the variable outside of the defined scope
This question already has answers here:
Correctly Parsing JSON in Swift 3
(10 answers)
Closed 5 years ago.
I am getting data like {"OTP":"5480"} in a string named responseString, How can I uset it.
My Code is.
#IBAction func signupButton() {
var request = URLRequest(url: URL(string:"http://122.166.215.8:8090/RESTMVC/validateMobileNumber")!)
request.httpMethod = "POST"
let mobileNumberString : String = self.mobileNumberTextfield.text!
let postString = ["mobileNumber":mobileNumberString]
request.httpBody = try! JSONSerialization.data(withJSONObject: postString, options:.prettyPrinted)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
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=\(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 = \(response)")
}
let responseString = String(data: data, encoding: .utf8)
var recived = [UInt8]()
recived.append(contentsOf: data)
print(responseString!)
DispatchQueue.main.async(execute: {
self.performSegue(withIdentifier: "OTPView", sender: nil)
});
}
task.resume()
}
and I want to change that string into Array. Or is there any way in which I can get Array directly on the place of String?
To access value of "OTP" you need to parse your response string and convert it in Json dictionary you can achive this using following code, just pass your response data in JSONSerialization.jsonObject(with: data, options: .allowFragments)
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! Dictionary<String, Any>
if let otpValue = json["OTP"] {
print("Otp value : \(otpValue)")
}
} catch {
// Handle Exception
}
You can get otp from dictionary like below.
print(responseString["OTP"])
I was accessing my webservices fine till xcode 7.3 i updated to xcode 8.2 and swift 3, now my app is crashing, here is my code
func jsonParsingFromURL () throws {
let WSLink = "http://XXXXX.co/itXXXXMS/webservice.asmx/GXXXXXX"
let url = URL(string: WSLink)
let bodyData = "lastlogindate=\(todayDate)&CompanyId=\(compID)" //problem is here
let request:NSMutableURLRequest = NSMutableURLRequest(url:url!)
request.httpMethod = "POST"
request.httpBody = bodyData.data(using: String.Encoding.utf8);
NSURLConnection.sendAsynchronousRequest(request as URLRequest, queue: OperationQueue.main) {(response, data, error) in
guard let _ = data else { return }
self.startParsing(data!)
}
}
func startParsing(_ data :Data) {
//Am getting error here in this line
let dict: NSDictionary!=(try! JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers)) as! NSDictionary
arrDict.removeAllObjects()
for i in 0 ..< (dict.value(forKey: "results") as! NSArray).count {
arrDict.add((dict.value(forKey: "results") as! NSArray) .object(at: i))
}
}
json text did not start with array or object and option to allow
fragments not set
Actually i found the reason of error but don't know how to fix it.
when i write as, let bodyData = "lastlogindate=26/11/2016&CompanyId=3" //it is working.
and when i wrap parameters in variables which are dynamic coming from previous viewController like
let date = "26/11/2016", let id = "3" and
let bodyData = "lastlogindate=(date)&CompanyId=(id)" then am getting error.
So basically my question is how to wrap dynamic variables to request.httpBody in swift 3 ?
My problem was in this line while passing parameters to bodyData:
let bodyData = "lastlogindate=\(todayDate)&CompanyId=\(compID)"
//example lastlogindate = "12/24/2016" and CompanyId = 134
When I do print(bodyData) I'm getting output as
"lastlogindate=optional(12/24/2016)&CompanyId=optional(134)"
Why optional was getting added in Swift 3, I dont know.
In Swift 2.2 it was not adding optional .
So, what i did is
let bodyData = "lastlogindate=" + todayDate + "&CompanyId=" + compID
Now, when I do print(bodyData) it gives me correct output as
lastlogindate=12/24/2016&CompanyId=134.